1 /* tag: hosted forth environment, executable code
3 * Copyright (C) 2003-2005 Patrick Mauritz, Stefan Reinauer
5 * See the file "COPYING" for further information about
6 * the copyright and warranty status of this work.
14 #define __USE_LARGEFILE64
18 #include <sys/types.h>
27 #include "sysinclude.h"
30 #include "kernel/kernel.h"
32 #include "kernel/stack.h"
33 #include "arch/unix/plugins.h"
34 #include "libopenbios/bindings.h"
35 #include "libopenbios/console.h"
36 #include "libopenbios/openbios.h"
37 #include "openbios-version.h"
40 #include "libopenbios/ofmem.h"
42 #define MEMORY_SIZE (4*1024*1024) /* 4M ram for hosted system */
43 #define DICTIONARY_SIZE (256*1024) /* 256k for the dictionary */
45 #if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS==64)
47 #define __LFS O_LARGEFILE
53 static void exit_terminal(void);
56 unsigned long virt_offset = 0;
64 static int segfault = 0;
65 static int verbose = 0;
67 #if defined(CONFIG_PPC) || defined(CONFIG_SPARC64)
68 unsigned long isa_io_base;
71 int errno_int; /* implement for fs drivers, needed to build on Mac OS X */
73 ucell ofmem_claim(ucell addr, ucell size, ucell align)
79 extern void flush_icache_range(char *start, char *stop);
81 void flush_icache_range(char *start, char *stop)
87 /* Expose system level is_machine helpers to make generic code easier */
89 #include "drivers/drivers.h"
100 int is_newworld(void)
107 static void write_dictionary(char *filename)
112 initxt = findword("initialize-of");
114 printk("warning: dictionary needs word called initialize-of\n");
116 f = fopen(filename, "w");
118 printk("panic: can't open dictionary.\n");
123 fwrite(DICTID, 16, 1, f);
124 fwrite(dict, dicthead, 1, f);
126 /* Write start address and last to relocate on load */
127 fwrite(&dict, sizeof(ucell), 1, f);
128 fwrite(&last, sizeof(ucell), 1, f);
132 #ifdef CONFIG_DEBUG_DICTIONARY
133 printk("wrote dictionary to file %s.\n", filename);
138 static ucell read_dictionary(char *fil)
146 if (stat(fil, &finfo))
149 ilen = finfo.st_size;
151 if ((mem = malloc(ilen)) == NULL) {
152 printk("panic: not enough memory.\n");
159 printk("panic: can't open dictionary.\n");
164 if (fread(mem, ilen, 1, f) != 1) {
165 printk("panic: can't read dictionary.\n");
172 ret = load_dictionary(mem, ilen);
180 * functions used by primitives
183 static int unix_availchar(void)
185 int tmp = getc(stdin);
193 static int unix_putchar(int c)
199 static int unix_getchar(void)
204 static struct _console_ops unix_console_ops = {
205 .putchar = unix_putchar,
206 .availchar = unix_availchar,
207 .getchar = unix_getchar
212 #ifdef CONFIG_PLUGINS
213 io_ops_t *ior = find_iorange(reg);
215 return ior->inb(reg);
218 printk("TRAP: io byte read @0x%x", reg);
224 #ifdef CONFIG_PLUGINS
225 io_ops_t *ior = find_iorange(reg);
227 return ior->inw(reg);
230 printk("TRAP: io word read @0x%x", reg);
236 #ifdef CONFIG_PLUGINS
237 io_ops_t *ior = find_iorange(reg);
239 return ior->inl(reg);
242 printk("TRAP: io long read @0x%x", reg);
246 void outb(u32 reg, u8 val)
248 #ifdef CONFIG_PLUGINS
249 io_ops_t *ior = find_iorange(reg);
256 printk("TRAP: io byte write 0x%x -> 0x%x", val, reg);
259 void outw(u32 reg, u16 val)
261 #ifdef CONFIG_PLUGINS
262 io_ops_t *ior = find_iorange(reg);
268 printk("TRAP: io word write 0x%x -> 0x%x", val, reg);
271 void outl(u32 reg, u32 val)
273 #ifdef CONFIG_PLUGINS
274 io_ops_t *ior = find_iorange(reg);
280 printk("TRAP: io long write 0x%x -> 0x%x", val, reg);
284 * terminal initialization and cleanup.
287 static struct termios saved_termios;
289 static void init_terminal(void)
291 struct termios termios;
293 tcgetattr(0, &saved_termios);
294 tcgetattr(0, &termios);
295 termios.c_lflag &= ~(ICANON | ECHO);
296 termios.c_cc[VMIN] = 1;
297 termios.c_cc[VTIME] = 3; // 300 ms
298 tcsetattr(0, 0, &termios);
301 static void exit_terminal(void)
303 tcsetattr(0, 0, &saved_termios);
307 * segmentation fault handler. linux specific?
311 segv_handler(int signo __attribute__ ((unused)),
312 siginfo_t * si, void *context __attribute__ ((unused)))
314 static int count = 0;
315 ucell addr = 0xdeadbeef;
318 printk("Died while dumping forth dictionary core.\n");
324 if (PC >= (ucell) dict && PC <= (ucell) dict + dicthead)
325 addr = *(ucell *) PC;
327 printk("panic: segmentation violation at %x\n", (ucell)si->si_addr);
328 printk("dict=0x%x here=0x%x(dict+0x%x) pc=0x%x(dict+0x%x)\n",
329 (ucell)dict, (ucell)dict + dicthead, dicthead, PC, PC - (ucell) dict);
330 printk("dstackcnt=%d rstackcnt=%d instruction=%x\n",
331 dstackcnt, rstackcnt, addr);
333 #ifdef CONFIG_DEBUG_DSTACK
336 #ifdef CONFIG_DEBUG_RSTACK
340 printk("Writing dictionary core file\n");
341 write_dictionary("forth.dict.core");
350 * Interrupt handler. linux specific?
351 * Restore terminal state on ctrl-C.
355 int_handler(int signo __attribute__ ((unused)),
356 siginfo_t * si __attribute__ ((unused)),
357 void *context __attribute__ ((unused)))
365 * allocate memory and prepare engine for memory management.
368 static void init_memory(void)
370 memory = malloc(MEMORY_SIZE);
372 printk("panic: not enough memory on host system.\n");
377 memset (memory, 0, MEMORY_SIZE);
378 /* we push start and end of memory to the stack
379 * so that it can be used by the forth word QUIT
380 * to initialize the memory allocator
383 PUSH((ucell) memory);
384 PUSH((ucell) memory + MEMORY_SIZE);
387 void exception(__attribute__((unused)) cell no)
390 * this is a noop since the dictionary has to take care
391 * itself of errors it generates outside of the bootstrap
404 bind_func("platform-boot", boot);
408 read_from_disk( int channel, int unit, int blk, unsigned long mphys, int size )
410 // channels and units not supported yet.
411 unsigned char *buf=(unsigned char *)mphys;
416 //printk("read: ch=%d, unit=%d, blk=%ld, phys=%lx, size=%d\n",
417 // channel, unit, blk, mphys, size);
419 lseek(diskemu, (ducell)blk*512, SEEK_SET);
420 read(diskemu, buf, size);
429 #define BANNER "OpenBIOS core. (C) 2003-2006 Patrick Mauritz, Stefan Reinauer\n"\
430 "This software comes with absolutely no warranty. "\
431 "All rights reserved.\n\n"
434 #define USAGE "usage: %s [options] [dictionary file|source file]\n\n"
436 int main(int argc, char *argv[])
440 unsigned char *dictname = NULL;
444 const char *optstring = "VvhsD:P:p:f:?";
448 int option_index = 0;
449 static struct option long_options[] = {
450 {"version", 0, NULL, 'V'},
451 {"verbose", 0, NULL, 'v'},
452 {"help", 0, NULL, 'h'},
453 // {"dictionary", 1, NULL, 'D'},
454 {"segfault", 0, NULL, 's'},
455 #ifdef CONFIG_PLUGINS
456 {"plugin-path", 1, NULL, 'P'},
457 {"plugin", 1, NULL, 'p'},
459 {"file", 1, NULL, 'f'}
462 c = getopt_long(argc, argv, optstring, long_options,
465 c = getopt(argc, argv, optstring);
472 printk(BANNER "Version " OPENBIOS_VERSION_STR "\n");
476 printk(BANNER "Version " OPENBIOS_VERSION_STR "\n"
487 printk("Dumping final dictionary to '%s'\n", optarg);
491 #ifdef CONFIG_PLUGINS
493 printk("Plugin search path is now '%s'\n", optarg);
497 printk("Loading plugin %s\n", optarg);
502 diskemu=open(optarg, O_RDONLY|__LFS);
504 printk("Using %s as harddisk.\n", optarg);
506 printk("%s not found. no harddisk node.\n",
514 if (argc < optind + 1) {
515 printk(USAGE, argv[0]);
519 /* Initialise console */
520 init_console(unix_console_ops);
522 if ((dict = (unsigned char *) malloc(DICTIONARY_SIZE)) == NULL) {
523 printk("panic: not enough memory.\n");
527 dictlimit = DICTIONARY_SIZE;
528 memset(dict, 0, DICTIONARY_SIZE);
532 printk("Installing SIGSEGV handler...");
534 sa.sa_sigaction = segv_handler;
535 sigemptyset(&sa.sa_mask);
536 sa.sa_flags = SA_SIGINFO | SA_NODEFER;
537 sigaction(SIGSEGV, &sa, NULL);
543 /* set terminal to do non blocking reads */
547 printk("Installing SIGINT handler...");
549 sa.sa_sigaction = int_handler;
550 sigemptyset(&sa.sa_mask);
551 sa.sa_flags = SA_SIGINFO | SA_NODEFER;
552 sigaction(SIGINT, &sa, NULL);
557 read_dictionary(argv[optind]);
560 PUSH_xt( bind_noname_func(arch_init) );
561 fword("PREPOST-initializer");
563 PC = (cell)findword("initialize-of");
566 if (optind + 1 != argc)
567 printk("Warning: only first dictionary used.\n");
569 printk("dictionary loaded (%d bytes).\n", dicthead);
570 printk("Initializing memory...");
577 printk("Jumping to dictionary...");
580 enterforth((xt_t)PC);
582 if (dictname != NULL)
583 write_dictionary(dictname);
588 } else { /* input file is not a dictionary */
589 printk("not supported.\n");
602 printk( const char *fmt, ... )
607 va_start( args, fmt );
608 i = vprintf(fmt, args );