aboutsummaryrefslogtreecommitdiff
path: root/arclib/prom.c
blob: 27a8e695deaef9feaff5597dd90f6106660b7ff7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

#include <stdio.h>
#include "arc.h"
#include "prom.h"

#include <stddef.h>
#include <stdlib.h>
#include <subarch.h>

void prom_wait(const char *prompt)
{
	int ch;

	if (prompt != NULL)
		puts(prompt);

	do {
		ch = getchar();
	} while ((ch != EOF) && (((char) ch) != ' '));
}


void prom_fatal(const CHAR * message, ...)
{
	va_list ap;

	if (message != NULL) {
		printf("FATAL ERROR:  ");
		va_start(ap, message);
		vprintf(message, ap);
		va_end(ap);
	}

	prom_wait("\n\r--- Press <spacebar> to enter ARC interactive mode ---");
	ArcEnterInteractiveMode();
}

void prom_init_malloc(void)
{
	MEMORYDESCRIPTOR *current = NULL;
	unsigned long stack = (unsigned long) &current;
#ifdef DEBUG
	printf("stack starts at: 0x%lx\n\r", stack);
#endif

	current = ArcGetMemoryDescriptor(current);
	if(!current ) {
		prom_fatal("Can't find any valid memory descriptors!\n\r");
	}
	while (current != NULL) {
		/*
		 *  The spec says we should have an adjacent FreeContiguous
		 *  memory area that includes our stack.  It would be much
		 *  easier to just look for that and give it to malloc, but
		 *  the Indy only shows FreeMemory areas, no FreeContiguous.
		 *  Oh well.
		 */
		if (current->Type == FreeMemory) {
			unsigned long start = KSEG0ADDR(current->BasePage * PAGE_SIZE);
			unsigned long end =
			    start + (current->PageCount * PAGE_SIZE);
#if DEBUG
			printf("Free Memory(%u) segment found at (0x%lx,0x%lx).\n\r",
					current->Type, start, end);
#endif

			/* Leave some space for our stack */
			if ((stack >= start) && (stack < end))
				end =
				    (stack -
				     (STACK_PAGES *
				      PAGE_SIZE)) & ~(PAGE_SIZE - 1);

			/* Don't use memory from reserved region */
			if ((start >= KERNELADDR)
			    && (start < (KERNELADDR + MAXLOADSIZE)))
				start = KERNELADDR + MAXLOADSIZE;
			if ((end > KERNELADDR)
			     && (end <= (KERNELADDR + MAXLOADSIZE)))
				end = KERNELADDR;
			if (end > start) {
#ifdef DEBUG
				printf("Adding %lu bytes at 0x%lx to the list of available memory\n\r", 
						end-start, start);
#endif
				malloc_area_add(start, end - start);
			}
		}
		current = ArcGetMemoryDescriptor(current);
	}
}


int prom_open(char *name, int mode, FILE *stream) {
	/* Translate mode to Arc variant */
	int	amode=OpenReadOnly;
	if (mode == O_RDWR)
		amode=OpenReadWrite;
	return ArcOpen(name, amode, stream);
}

int prom_close(FILE stream) {
	return ArcClose(stream);
}

int prom_seek(FILE stream, long long position, int whence) {
	LARGEINTEGER	apos;
	SEEKMODE	amode=SeekAbsolute;

	/* Translate generic positioning to ARC positioning */
	if (whence == SEEK_CUR)
		amode=SeekRelative;

	/* Translate 64 bit long long to Arc representation */
	apos.HighPart=position>>32;
	apos.LowPart=position&0xffffffff;

	return ArcSeek(stream, &apos, amode);
}

int prom_write(FILE stream, char *string, unsigned long len, unsigned long *rlen) {
	return ArcWrite(stream, string, len, rlen);
}

int prom_read(FILE stream, char *string, unsigned long len, unsigned long *rlen) {
	return ArcRead(stream, string, len, rlen);
}