#include #include "arc.h" #include "prom.h" #include #include #include void prom_flush_cache_all(void ) { ArcFlushAllCaches(); } void prom_restart(void ) { ArcRestart(); } void prom_return_interactive(void ) { ArcEnterInteractiveMode(); } 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 to enter ARC interactive mode ---"); ArcEnterInteractiveMode(); } void prom_init_malloc(void) { MEMORYDESCRIPTOR *current = NULL; unsigned long stack = (unsigned long) ¤t; #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); }