diff options
Diffstat (limited to 'qemu/roms/openbios/kernel/bootstrap.c')
-rw-r--r-- | qemu/roms/openbios/kernel/bootstrap.c | 1322 |
1 files changed, 0 insertions, 1322 deletions
diff --git a/qemu/roms/openbios/kernel/bootstrap.c b/qemu/roms/openbios/kernel/bootstrap.c deleted file mode 100644 index 520d7b48c..000000000 --- a/qemu/roms/openbios/kernel/bootstrap.c +++ /dev/null @@ -1,1322 +0,0 @@ -/* tag: forth bootstrap environment - * - * Copyright (C) 2003-2006 Stefan Reinauer, Patrick Mauritz - * - * See the file "COPYING" for further information about - * the copyright and warranty status of this work. - */ - -#include "sysinclude.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <signal.h> -#include <fcntl.h> -#include <unistd.h> -#include <termios.h> -#include <sys/stat.h> - -#ifdef __GLIBC__ -#define _GNU_SOURCE -#include <getopt.h> -#endif - -#include "config.h" -#include "kernel/stack.h" -#include "sysinclude.h" -#include "kernel/kernel.h" -#include "dict.h" -#include "cross.h" -#include "openbios-version.h" - -#define MAX_PATH_LEN 256 - -#define MEMORY_SIZE (1024*1024) /* 1M ram for hosted system */ -#define DICTIONARY_SIZE (256*1024) /* 256k for the dictionary */ -#define TRAMPOLINE_SIZE (4*sizeof(cell)) /* 4 cells for the trampoline */ - -/* state variables */ -static ucell *latest, *state, *base; -static ucell *memory; -ucell *trampoline; - -/* local variables */ -static int errors = 0; -static int segfault = 0; -static int verbose = 0; - -#define MAX_SRC_FILES 128 - -static FILE *srcfiles[MAX_SRC_FILES]; -static char *srcfilenames[MAX_SRC_FILES]; -static int srclines[MAX_SRC_FILES]; -static unsigned int cursrc = 0; - -static char *srcbasedict; - -/* console variables */ -static FILE *console; - -#ifdef NATIVE_BITWIDTH_SMALLER_THAN_HOST_BITWIDTH -unsigned long base_address; -#endif - -/* include path handling */ -typedef struct include_path include; -struct include_path { - const char *path; - include *next; -}; - -static include includes = { ".", NULL }; -static FILE *depfile; - -static ucell * relocation_address=NULL; -static int relocation_length=0; - -/* the word names are used to generate the prim words in the - * dictionary. This is done by the C written interpreter. - */ -static const char *wordnames[] = { - "(semis)", "", "(lit)", "", "", "", "", "(do)", "(?do)", "(loop)", - "(+loop)", "", "", "", "dup", "2dup", "?dup", "over", "2over", "pick", "drop", - "2drop", "nip", "roll", "rot", "-rot", "swap", "2swap", ">r", "r>", - "r@", "depth", "depth!", "rdepth", "rdepth!", "+", "-", "*", "u*", - "mu/mod", "abs", "negate", "max", "min", "lshift", "rshift", ">>a", - "and", "or", "xor", "invert", "d+", "d-", "m*", "um*", "@", "c@", - "w@", "l@", "!", "+!", "c!", "w!", "l!", "=", ">", "<", "u>", "u<", - "sp@", "move", "fill", "(emit)", "(key?)", "(key)", "execute", - "here", "here!", "dobranch", "do?branch", "unaligned-w@", - "unaligned-w!", "unaligned-l@", "unaligned-l!", "ioc@", "iow@", - "iol@", "ioc!", "iow!", "iol!", "i", "j", "call", "sys-debug", - "$include", "$encode-file", "(debug", "(debug-off)" -}; - -/* - * dictionary related functions. - */ - -/* - * Compare two dictionaries constructed at different addresses. When - * the cells don't match, a need for relocation is detected and the - * corresponding bit in reloc_table bitmap is set. - */ -static void relocation_table(unsigned char * dict_one, unsigned char *dict_two, int length) -{ - ucell *d1=(ucell *)dict_one, *d2=(ucell *)dict_two; - ucell *reloc_table; - int pos, bit; - int l=(length+(sizeof(cell)-1))/sizeof(ucell), i; - - /* prepare relocation table */ - relocation_length=(length+BITS-1)/BITS; - reloc_table = malloc(relocation_length*sizeof(cell)); - memset(reloc_table,0,relocation_length*sizeof(cell)); - - for (i=0; i<l; i++) { - - pos=i/BITS; - bit=i&~(-BITS); - - if(d1[i]==d2[i]) { - reloc_table[pos] &= target_ucell(~((ucell)1ULL << bit)); - - // This check might bring false positives in data. - //if(d1[i] >= pointer2cell(dict_one) && - // d1[i] <= pointer2cell(dict_one+length)) - // printk("\nWARNING: inconsistent relocation (%x:%x)!\n", d1[i], d2[i]); - } else { - /* This is a pointer, it needs relocation, d2==dict */ - reloc_table[pos] |= target_ucell((ucell)1ULL << bit); - d2[i] = target_ucell(target_ucell(d2[i]) - pointer2cell(d2)); - } - } - -#ifdef CONFIG_DEBUG_DICTIONARY - printk("dict1 %lx dict2 %lx dict %lx\n",dict_one, dict_two, dict); - for (i=0; i< relocation_length ; i++) - printk("reloc %d %lx\n",i+1, reloc_table[i]); -#endif - relocation_address=reloc_table; -} - -static void write_dictionary(const char *filename) -{ - FILE *f; - unsigned char *write_data, *walk_data; - int write_len; - dictionary_header_t *header; - u32 checksum=0; - - /* - * get memory for dictionary - */ - - write_len = sizeof(dictionary_header_t)+dicthead+relocation_length*sizeof(cell); - write_data = malloc(write_len); - if(!write_data) { - printk("panic: can't allocate memory for output dictionary (%d" - " bytes\n", write_len); - exit(1); - } - memset(write_data, 0, write_len); - - /* - * prepare dictionary header - */ - - header = (dictionary_header_t *)write_data; - *header = (dictionary_header_t){ - .signature = DICTID, - .version = 2, - .cellsize = sizeof(ucell), -#ifdef CONFIG_BIG_ENDIAN - .endianess = -1, -#else - .endianess = 0, -#endif - .checksum = 0, - .compression = 0, - .relocation = -1, - .length = target_ulong((uint32_t)dicthead), - .last = target_ucell((ucell)((unsigned long)last - - (unsigned long)dict)), - }; - - /* - * prepare dictionary data - */ - - walk_data=write_data+sizeof(dictionary_header_t); - memcpy (walk_data, dict, dicthead); - - /* - * prepare relocation data. - * relocation_address is zero when writing a dictionary core. - */ - - if (relocation_address) { -#ifdef CONFIG_DEBUG_DICTIONARY - printk("writing %d reloc cells \n",relocation_length); -#endif - walk_data += dicthead; - memcpy(walk_data, relocation_address, - relocation_length*sizeof(cell)); - /* free relocation information */ - free(relocation_address); - relocation_address=NULL; - } else { - header->relocation=0; - } - - /* - * Calculate Checksum - */ - - walk_data=write_data; - while (walk_data<write_data+write_len) { - checksum+=read_long(walk_data); - walk_data+=sizeof(u32); - } - checksum=(u32)-checksum; - - header->checksum=target_long(checksum); - - if (verbose) { - dump_header(header); - } - - f = fopen(filename, "w"); - if (!f) { - printk("panic: can't write to dictionary '%s'.\n", filename); - exit(1); - } - - fwrite(write_data, write_len, 1, f); - - free(write_data); - fclose(f); - -#ifdef CONFIG_DEBUG_DICTIONARY - printk("wrote dictionary to file %s.\n", filename); -#endif -} - -/* - * Write dictionary as a list of ucell hex values to filename. Array - * header and end lines are not generated. - * - * Cells with relocations are output using the expression - * DICTIONARY_BASE + value. - * - * Define some helpful constants. - */ -static void write_dictionary_hex(const char *filename) -{ - FILE *f; - ucell *walk; - - f = fopen(filename, "w"); - if (!f) { - printk("panic: can't write to dictionary '%s'.\n", filename); - exit(1); - } - - for (walk = (ucell *)dict; walk < (ucell *)(dict + dicthead); walk++) { - int pos, bit, l; - ucell val; - - l = (walk - (ucell *)dict); - pos = l / BITS; - bit = l & ~(-BITS); - - val = read_ucell(walk); - if (relocation_address[pos] & target_ucell((ucell)1ULL << bit)) { - fprintf(f, "DICTIONARY_BASE + 0x%" FMT_CELL_x - ",\n", val); - } else { - fprintf(f, "0x%" FMT_CELL_x",\n", val); - } - } - - fprintf(f, "#define FORTH_DICTIONARY_LAST 0x%" FMT_CELL_x"\n", - (ucell)((unsigned long)last - (unsigned long)dict)); - fprintf(f, "#define FORTH_DICTIONARY_END 0x%" FMT_CELL_x"\n", - (ucell)dicthead); - fclose(f); - -#ifdef CONFIG_DEBUG_DICTIONARY - printk("wrote dictionary to file %s.\n", filename); -#endif -} - -static ucell read_dictionary(char *fil) -{ - int ilen; - ucell ret; - char *mem; - FILE *f; - struct stat finfo; - - if (stat(fil, &finfo)) - return 0; - - ilen = finfo.st_size; - - if ((mem = malloc(ilen)) == NULL) { - printk("panic: not enough memory.\n"); - exit(1); - } - - f = fopen(fil, "r"); - if (!f) { - printk("panic: can't open dictionary.\n"); - exit(1); - } - - if (fread(mem, ilen, 1, f) != 1) { - printk("panic: can't read dictionary.\n"); - fclose(f); - exit(1); - } - fclose(f); - - ret = load_dictionary(mem, ilen); - - free(mem); - return ret; -} - - -/* - * C Parser related functions - */ - -/* - * skipws skips all whitespaces (space, tab, newline) from the input file - */ - -static void skipws(FILE * f) -{ - int c; - while (!feof(f)) { - c = getc(f); - - if (c == ' ' || c == '\t') - continue; - - if (c == '\n') { - srclines[cursrc - 1]++; - continue; - } - - ungetc(c, f); - break; - } -} - -/* - * parse gets the next word from the input stream, delimited by - * delim. If delim is 0, any word delimiter will end the stream - * word delimiters are space, tab and newline. The resulting word - * will be put zero delimited to the char array line. - */ - -static int parse(FILE * f, char *line, char delim) -{ - int cnt = 0, c = 0; - - while (!feof(f)) { - c = getc(f); - - if (delim && c == delim) - break; - - if ((!delim) && (c == ' ' || c == '\t' || c == '\n')) - break; - - line[cnt++] = c; - } - - /* Update current line number */ - if (c == '\n') { - srclines[cursrc - 1]++; - } - - line[cnt] = 0; - - return cnt; -} - -/* - * parse_word is a small helper that skips whitespaces before a word. - * it's behaviour is similar to the forth version parse-word. - */ - -static void parse_word(FILE * f, char *line) -{ - skipws(f); - parse(f, line, 0); -} - - -static void writestring(const char *str) -{ - unsigned int i; - for (i = 0; i < strlen(str); i++) { - dict[dicthead + i] = str[i]; - } - dicthead += i + 1; - dict[dicthead - 1] = (char) strlen(str) + 128; -} - -#define writebyte(value) {write_byte(dict+dicthead,value); dicthead++;} -#define writecell(value) {write_cell(dict+dicthead, value); dicthead+=sizeof(cell);} - -/* - * reveal a word, ie. make it visible. - */ - -static void reveal(void) -{ - *last = *latest; -} - -/* - * dictionary padding - */ - -static void paddict(ucell align) -{ - while (dicthead % align != 0) - writebyte(0); -} - -/* - * generic forth word creator function. - */ - -static void fcreate(const char *word, ucell cfaval) -{ - if (strlen(word) == 0) { - printk("WARNING: tried to create unnamed word.\n"); - return; - } - - writestring(word); - /* get us at least 1 byte for flags */ - writebyte(0); - paddict(sizeof(cell)); - /* set flags high bit. */ - dict[dicthead - 1] = 128; - /* lfa and cfa */ - writecell(read_ucell(latest)); - *latest = target_ucell(pointer2cell(dict) + dicthead - sizeof(cell)); - writecell(cfaval); -} - - -static ucell *buildvariable(const char *name, cell defval) -{ - fcreate(name, DOVAR); /* see dict.h for DOVAR and other CFA ids */ - writecell(defval); - return (ucell *) (dict + dicthead - sizeof(cell)); -} - -static void buildconstant(const char *name, cell defval) -{ - fcreate(name, DOCON); /* see dict.h for DOCON and other CFA ids */ - writecell(defval); -} - -static void builddefer(const char *name) -{ - fcreate(name, DODFR); /* see dict.h for DODFR and other CFA ids */ - writecell((ucell)0); - writecell((ucell)findword("(semis)")); -} - -/* - * Include file handling - */ - -static void add_includepath(char *path) -{ - include *incl = &includes; - include *newpath; - - while (incl->next) - incl = incl->next; - - newpath = malloc(sizeof(include)); - if (!newpath) { - printk("panic: not enough memory for include path.\n"); - exit(1); - } - - incl->next = newpath; - newpath->path = path; - newpath->next = NULL; -} - - -static FILE *fopen_include(const char *fil) -{ - char fullpath[MAX_PATH_LEN]; - FILE *ret; - include *incl = &includes; - - while (incl) { - snprintf(fullpath, sizeof(fullpath), "%s/%s", incl->path, fil); - - ret = fopen(fullpath, "r"); - if (ret != NULL) { - -#ifdef CONFIG_DEBUG_INTERPRETER - printk("Including '%s'\n", fil); -#endif - srcfilenames[cursrc] = strdup(fil); - srclines[cursrc] = 1; - srcfiles[cursrc++] = ret; - - if (depfile) { - fprintf(depfile, " %s", fullpath); - } - - return ret; - } - - incl = incl->next; - } - return NULL; -} - - -/* - * Forth exception handler - */ - -void exception(cell no) -{ - printk("%s:%d: ", srcfilenames[cursrc - 1], srclines[cursrc - 1]); - - /* See also forth/bootstrap/interpreter.fs */ - switch (no) { - case -1: - case -2: - printk("Aborted.\n"); - break; - case -3: - printk("Stack Overflow.\n"); - break; - case -4: - printk("Stack Underflow.\n"); - break; - case -5: - printk("Return Stack Overflow.\n"); - break; - case -6: - printk("Return Stack Underflow.\n"); - break; - case -19: - printk("undefined word.\n"); - break; - case -21: - printk("out of memory.\n"); - break; - case -33: - printk("undefined method.\n"); - break; - case -34: - printk("no such device.\n"); - break; - default: - printk("error %" FMT_CELL_d " occured.\n", no); - } - exit(1); -} - - -/* - * This is the C version of the forth interpreter - */ - -static int interpret_source(char *fil) -{ - FILE *f; - char tib[160]; - cell num; - char *test; - - const ucell SEMIS = (ucell)findword("(semis)"); - const ucell LIT = (ucell)findword("(lit)"); - const ucell DOBRANCH = (ucell)findword("dobranch"); - - if ((f = fopen_include(fil)) == NULL) { - printk("error while loading source file '%s'\n", fil); - errors++; - exit(1); - } - - /* FIXME: We should read this file at - * once. No need to get it char by char - */ - - while (!feof(f)) { - xt_t res; - parse_word(f, tib); - - /* if there is actually no word, we continue right away */ - if (strlen(tib) == 0) { - continue; - } - - /* Checking for builtin words that are needed to - * bootstrap the forth base dictionary. - */ - - if (!strcmp(tib, "(")) { - parse(f, tib, ')'); - continue; - } - - if (!strcmp(tib, "\\")) { - parse(f, tib, '\n'); - continue; - } - - if (!strcmp(tib, ":")) { - parse_word(f, tib); - -#ifdef CONFIG_DEBUG_INTERPRETER - printk("create colon word %s\n\n", tib); -#endif - fcreate(tib, DOCOL); /* see dict.h for DOCOL and other CFA ids */ - *state = (ucell) (-1); - continue; - } - - if (!strcmp(tib, ";")) { -#ifdef CONFIG_DEBUG_INTERPRETER - printk("finish colon definition\n\n"); -#endif - writecell((cell)SEMIS); - *state = (ucell) 0; - reveal(); - continue; - } - - if (!strcasecmp(tib, "variable")) { - parse_word(f, tib); -#ifdef CONFIG_DEBUG_INTERPRETER - printk("defining variable %s\n\n", tib); -#endif - buildvariable(tib, 0); - reveal(); - continue; - } - - if (!strcasecmp(tib, "constant")) { - parse_word(f, tib); -#ifdef CONFIG_DEBUG_INTERPRETER - printk("defining constant %s\n\n", tib); -#endif - buildconstant(tib, POP()); - reveal(); - continue; - } - - if (!strcasecmp(tib, "value")) { - parse_word(f, tib); -#ifdef CONFIG_DEBUG_INTERPRETER - printk("defining value %s\n\n", tib); -#endif - buildconstant(tib, POP()); - reveal(); - continue; - } - - if (!strcasecmp(tib, "defer")) { - parse_word(f, tib); -#ifdef CONFIG_DEBUG_INTERPRETER - printk("defining defer word %s\n\n", tib); -#endif - builddefer(tib); - reveal(); - continue; - } - - if (!strcasecmp(tib, "include")) { - parse_word(f, tib); -#ifdef CONFIG_DEBUG_INTERPRETER - printk("including file %s\n\n", tib); -#endif - interpret_source(tib); - continue; - } - - if (!strcmp(tib, "[']")) { - xt_t xt; - parse_word(f, tib); - xt = findword(tib); - if (*state == 0) { -#ifdef CONFIG_DEBUG_INTERPRETER - printk - ("writing address of %s to stack\n\n", - tib); -#endif - PUSH_xt(xt); - } else { -#ifdef CONFIG_DEBUG_INTERPRETER - printk("writing lit, addr(%s) to dict\n\n", - tib); -#endif - writecell(LIT); /* lit */ - writecell((cell)xt); - } - continue; - /* we have no error detection here */ - } - - if (!strcasecmp(tib, "s\"")) { - int cnt; - cell loco; - - cnt = parse(f, tib, '"'); -#ifdef CONFIG_DEBUG_INTERPRETER - printk("compiling string %s\n", tib); -#endif - loco = dicthead + (6 * sizeof(cell)); - writecell(LIT); - writecell(pointer2cell(dict) + loco); - writecell(LIT); - writecell((ucell)cnt); - writecell(DOBRANCH); - loco = cnt + sizeof(cell) - 1; - loco &= ~(sizeof(cell) - 1); - writecell(loco); - memcpy(dict + dicthead, tib, cnt); - dicthead += cnt; - paddict(sizeof(cell)); - continue; - } - - /* look if tib is in dictionary. */ - /* should the dictionary be searched before the builtins ? */ - res = findword(tib); - if (res) { - u8 flags = read_byte((u8*)cell2pointer(res) - - sizeof(cell) - 1); -#ifdef CONFIG_DEBUG_INTERPRETER - printk("%s is 0x%" FMT_CELL_x "\n", tib, (ucell) res); -#endif - if (!(*state) || (flags & 3)) { -#ifdef CONFIG_DEBUG_INTERPRETER - printk("executing %s, %" FMT_CELL_d - " (flags: %s %s)\n", - tib, res, - (flags & 1) ? "immediate" : "", - (flags & 2) ? "compile-only" : ""); -#endif - PC = (ucell)res; - enterforth(res); - } else { -#ifdef CONFIG_DEBUG_INTERPRETER - printk("writing %s to dict\n\n", tib); -#endif - writecell((cell)res); - } - continue; - } - - /* if not look if it's a number */ - if (tib[0] == '-') - num = strtoll(tib, &test, read_ucell(base)); - else - num = strtoull(tib, &test, read_ucell(base)); - - - if (*test != 0) { - /* what is it?? */ - printk("%s:%d: %s is not defined.\n\n", srcfilenames[cursrc - 1], srclines[cursrc - 1], tib); - errors++; -#ifdef CONFIG_DEBUG_INTERPRETER - continue; -#else - return -1; -#endif - } - - if (*state == 0) { -#ifdef CONFIG_DEBUG_INTERPRETER - printk("pushed %" FMT_CELL_x " to stack\n\n", num); -#endif - PUSH(num); - } else { -#ifdef CONFIG_DEBUG_INTERPRETER - printk("writing lit, %" FMT_CELL_x " to dict\n\n", num); -#endif - writecell(LIT); /* lit */ - writecell(num); - } - } - - fclose(f); - cursrc--; - - return 0; -} - -static int build_dictionary(void) -{ - ucell lfa = 0; - unsigned int i; - - /* we need a temporary place for latest outside the dictionary */ - latest = &lfa; - - /* starting a new dictionary: clear dicthead */ - dicthead = 0; - -#ifdef CONFIG_DEBUG_DICTIONARY - printk("building dictionary, %d primitives.\nbuilt words:", - sizeof(wordnames) / sizeof(void *)); -#endif - - for (i = 0; i < sizeof(wordnames) / sizeof(void *); i++) { - if (strlen(wordnames[i]) != 0) { - fcreate((char *) wordnames[i], i); -#ifdef CONFIG_DEBUG_DICTIONARY - printk(" %s", wordnames[i]); -#endif - } - } -#ifdef CONFIG_DEBUG_DICTIONARY - printk(".\n"); -#endif - - /* get last/latest and state */ - state = buildvariable("state", 0); - last = buildvariable("forth-last", 0); - latest = buildvariable("latest", 0); - - *latest = target_ucell(pointer2cell(latest)-2*sizeof(cell)); - - base=buildvariable("base", 10); - - buildconstant("/c", sizeof(u8)); - buildconstant("/w", sizeof(u16)); - buildconstant("/l", sizeof(u32)); - buildconstant("/n", sizeof(ucell)); - buildconstant("/x", sizeof(u64)); - - reveal(); - if (verbose) { - printk("Dictionary initialization finished.\n"); - } - return 0; -} - -/* - * functions used by primitives - */ - -int availchar(void) -{ - int tmp; - if( cursrc < 1 ) { - interruptforth |= FORTH_INTSTAT_STOP; - /* return -1 in order to exit the loop in key() */ - return -1; - } - - tmp = getc( srcfiles[cursrc-1] ); - if (tmp != EOF) { - ungetc(tmp, srcfiles[cursrc-1]); - return -1; - } - - fclose(srcfiles[--cursrc]); - - return availchar(); -} - -int get_inputbyte( void ) -{ - int tmp; - - if( cursrc < 1 ) { - interruptforth |= FORTH_INTSTAT_STOP; - return 0; - } - - tmp = getc( srcfiles[cursrc-1] ); - - /* Update current line number */ - if (tmp == '\n') { - srclines[cursrc - 1]++; - } - - if (tmp != EOF) { - return tmp; - } - - fclose(srcfiles[--cursrc]); - - return get_inputbyte(); -} - -void put_outputbyte( int c ) -{ - if (console) - fputc(c, console); -} - -/* - * segmentation fault handler. linux specific? - */ - -static void -segv_handler(int signo __attribute__ ((unused)), - siginfo_t * si, void *context __attribute__ ((unused))) -{ - static int count = 0; - ucell addr = 0xdeadbeef; - - if (count) { - printk("Died while dumping forth dictionary core.\n"); - goto out; - } - - count++; - - if (PC >= pointer2cell(dict) && PC <= pointer2cell(dict) + dicthead) - addr = read_cell(cell2pointer(PC)); - - printk("panic: segmentation violation at %p\n", (char *)si->si_addr); - printk("dict=%p here=%p(dict+0x%" FMT_CELL_x ") pc=0x%" FMT_CELL_x "(dict+0x%" FMT_CELL_x ")\n", - dict, dict + dicthead, dicthead, PC, PC - pointer2cell(dict)); - printk("dstackcnt=%d rstackcnt=%d instruction=%" FMT_CELL_x "\n", - dstackcnt, rstackcnt, addr); - - printdstack(); - printrstack(); - - printk("Writing dictionary core file\n"); - write_dictionary("forth.dict.core"); - - out: - exit(1); -} - -/* - * allocate memory and prepare engine for memory management. - */ - -static void init_memory(void) -{ - memset(memory, 0, MEMORY_SIZE); - - /* we push start and end of memory to the stack - * so that it can be used by the forth word QUIT - * to initialize the memory allocator. - * Add a cell to the start address so we don't end - * up with a start address of zero during bootstrap - */ - - PUSH(pointer2cell(memory)+sizeof(cell)); - PUSH(pointer2cell(memory) + MEMORY_SIZE-1); -} - - -void -include_file( const char *name ) -{ - FILE *file; - - if( cursrc >= sizeof(srcfiles)/sizeof(srcfiles[0]) ) { - printk("\npanic: Maximum include depth reached!\n"); - exit(1); - } - - file = fopen_include( name ); - if( !file ) { - printk("\npanic: Failed opening file '%s'\n", name ); - exit(1); - } -} - - -void -encode_file( const char *name ) -{ - FILE *file = fopen_include(name); - int size; - - if( !file ) { - printk("\npanic: Can't open '%s'\n", name ); - exit(1); - } - fseek( file, 0, SEEK_END ); - size = ftell( file ); - fseek( file, 0, SEEK_SET ); - - if (verbose) { - printk("\nEncoding %s [%d bytes]\n", name, size ); - } - fread( dict + dicthead, size, 1, file ); - PUSH( pointer2cell(dict + dicthead) ); - PUSH( size ); - dicthead += size; - paddict(sizeof(cell)); -} - - -static void run_dictionary(char *basedict, char *confile) -{ - if(!basedict) - return; - - read_dictionary(basedict); - PC = (ucell)findword("initialize"); - - if (!PC) { - if (verbose) { - printk("Unable to find initialize word in dictionary %s; ignoring\n", basedict); - } - return; - } - - if(!srcfiles[0]) { - cursrc = 1; - srcfiles[cursrc-1] = stdin; - } - - dstackcnt=0; - rstackcnt=0; - - init_memory(); - if (verbose) - printk("Jumping to dictionary %s...\n", basedict); - - /* If a console file has been specified, open it */ - if (confile) - console = fopen(confile, "w"); - - srcbasedict = basedict; - - enterforth((xt_t)PC); - - /* Close the console file */ - if (console) - fclose(console); -} - -static void new_dictionary(const char *source) -{ - build_dictionary(); - - interpret_source((char *)source); - - if (verbose || errors > 0) { - printk("interpretion finished. %d errors occured.\n", - errors); - } -} - -/* - * main loop - */ - -#define BANNER "OpenBIOS bootstrap kernel. (C) 2003-2006 Patrick Mauritz, Stefan Reinauer\n"\ - "This software comes with absolutely no warranty. "\ - "All rights reserved.\n\n" - -#ifdef __GLIBC__ -#define USAGE "Usage: %s [options] [dictionary file|source file]\n\n" \ - " -h|--help show this help\n" \ - " -V|--version print version and exit\n" \ - " -v|--verbose print debugging information\n" \ - " -I|--include dir add dir to include path\n" \ - " -d|--source-dictionary bootstrap.dict\n" \ - " use this dictionary as base\n" \ - " -D|--target-dictionary output.dict\n" \ - " write to output.dict\n" \ - " -c|--console output.log\n" \ - " write kernel console output to log file\n" \ - " -s|--segfault install segfault handler\n" \ - " -M|--dependency-dump file\n" \ - " dump dependencies in Makefile format\n\n" \ - " -x|--hexdump output format is C language hex dump\n" -#else -#define USAGE "Usage: %s [options] [dictionary file|source file]\n\n" \ - " -h show this help\n" \ - " -V print version and exit\n" \ - " -v print debugging information\n" \ - " -I add dir to include path\n" \ - " -d bootstrap.dict\n" \ - " use this dictionary as base\n" \ - " -D output.dict\n" \ - " write to output.dict\n" \ - " -c output.log\n" \ - " write kernel console output to log file\n" \ - " -s install segfault handler\n\n" \ - " -M file dump dependencies in Makefile format\n\n" \ - " -x output format is C language hex dump\n" -#endif - -int main(int argc, char *argv[]) -{ - struct sigaction sa; - - unsigned char *ressources=NULL; /* All memory used by us */ - const char *dictname = NULL; - char *basedict = NULL; - char *consolefile = NULL; - char *depfilename = NULL; - - unsigned char *bootstrapdict[2]; - int c, cnt, hexdump = 0; - - const char *optstring = "VvhsI:d:D:c:M:x?"; - - while (1) { -#ifdef __GLIBC__ - int option_index = 0; - static struct option long_options[] = { - {"version", 0, NULL, 'V'}, - {"verbose", 0, NULL, 'v'}, - {"help", 0, NULL, 'h'}, - {"segfault", 0, NULL, 's'}, - {"include", 1, NULL, 'I'}, - {"source-dictionary", 1, NULL, 'd'}, - {"target-dictionary", 1, NULL, 'D'}, - {"console", 1, NULL, 'c'}, - {"dependency-dump", 1, NULL, 'M'}, - {"hexdump", 0, NULL, 'x'}, - }; - - /* - * option handling - */ - - c = getopt_long(argc, argv, optstring, long_options, - &option_index); -#else - c = getopt(argc, argv, optstring); -#endif - if (c == -1) - break; - - switch (c) { - case 'V': - printk("Version " OPENBIOS_VERSION_STR "\n"); - return 0; - case 'h': - case '?': - printk("Version " OPENBIOS_VERSION_STR "\n" USAGE, - argv[0]); - return 0; - case 'v': - verbose = 1; - break; - case 's': - segfault = 1; - break; - case 'I': -#ifdef CONFIG_DEBUG_INTERPRETER - printk("adding '%s' to include path\n", optarg); -#endif - add_includepath(optarg); - break; - case 'd': - if (!basedict) { - basedict = optarg; - } - break; - case 'D': - if(!dictname) { - dictname = optarg; - } - break; - case 'c': - if (!consolefile) { - consolefile = optarg; - } - break; - case 'M': - if (!depfilename) { - depfilename = optarg; - } - break; - case 'x': - hexdump = 1; - break; - default: - return 1; - } - } - - if (!dictname) { - dictname = "bootstrap.dict"; - } - if (verbose) { - printk(BANNER); - printk("Using source dictionary '%s'\n", basedict); - printk("Dumping final dictionary to '%s'\n", dictname); - printk("Dumping dependencies to '%s'\n", depfilename); - } - - if (argc < optind) { - printk(USAGE, argv[0]); - return 1; - } - - if (depfilename) { - depfile = fopen(depfilename, "w"); - if (!depfile) { - printk("panic: can't write to dependency file '%s'.\n", - depfilename); - exit(1); - } - fprintf(depfile, "%s:", dictname); - } - - /* - * Get all required resources - */ - - - ressources = malloc(MEMORY_SIZE + (2 * DICTIONARY_SIZE) + TRAMPOLINE_SIZE); - if (!ressources) { - printk("panic: not enough memory on host system.\n"); - return 1; - } - -#ifdef NATIVE_BITWIDTH_SMALLER_THAN_HOST_BITWIDTH - base_address=(unsigned long)ressources; -#endif - - memory = (ucell *)ressources; - - bootstrapdict[0] = ressources + MEMORY_SIZE; - bootstrapdict[1] = ressources + MEMORY_SIZE + DICTIONARY_SIZE; - trampoline = (ucell *)(ressources + MEMORY_SIZE + DICTIONARY_SIZE + DICTIONARY_SIZE); - -#ifdef CONFIG_DEBUG_INTERPRETER - printf("memory: %p\n",memory); - printf("dict1: %p\n",bootstrapdict[0]); - printf("dict2: %p\n",bootstrapdict[1]); - printf("trampoline: %p\n",trampoline); - printf("size=%d, trampoline_size=%d\n",MEMORY_SIZE + (2 * - DICTIONARY_SIZE) + TRAMPOLINE_SIZE, - TRAMPOLINE_SIZE); -#endif - - if (trampoline == NULL) { - /* We're using side effects which is to some extent nasty */ - printf("WARNING: no trampoline!\n"); - } else { - init_trampoline(trampoline); - } - - if (!segfault) { - if (verbose) - printk("Installing SIGSEGV handler..."); - - sa.sa_sigaction = segv_handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_SIGINFO | SA_NODEFER; - sigaction(SIGSEGV, &sa, NULL); - - if (verbose) - printk("done.\n"); - } - - /* - * Now do the real work - */ - - for (cnt=0; cnt<2; cnt++) { - if (verbose) { - printk("Compiling dictionary %d/%d\n", cnt+1, 2); - } - dict=bootstrapdict[cnt]; - if(!basedict) { - new_dictionary(argv[optind]); - } else { - for (c=argc-1; c>=optind; c--) - include_file(argv[c]); - - run_dictionary(basedict, consolefile); - } - if (depfile) { - fprintf(depfile, "\n"); - fclose(depfile); - depfile = NULL; - } - if(errors) - break; - } - -#ifndef CONFIG_DEBUG_INTERPRETER - if (errors) - printk("dictionary not dumped to file.\n"); - else -#endif - { - relocation_table( bootstrapdict[0], bootstrapdict[1], dicthead); - if (hexdump) { - write_dictionary_hex(dictname); - } else { - write_dictionary(dictname); - } - } - - free(ressources); - - if (errors) - return 1; - else - return 0; -} |