Annotation of qemu/roms/openbios/arch/unix/unix.c, revision 1.1.1.1

1.1       root        1: /* tag: hosted forth environment, executable code
                      2:  *
                      3:  * Copyright (C) 2003-2005 Patrick Mauritz, Stefan Reinauer
                      4:  *
                      5:  * See the file "COPYING" for further information about
                      6:  * the copyright and warranty status of this work.
                      7:  */
                      8: 
                      9: #include <stdio.h>
                     10: #include <stdint.h>
                     11: #include <stdlib.h>
                     12: #include <string.h>
                     13: #include <signal.h>
                     14: #define __USE_LARGEFILE64
                     15: #include <fcntl.h>
                     16: #include <unistd.h>
                     17: #include <termios.h>
                     18: #include <sys/types.h>
                     19: #include <sys/stat.h>
                     20: #include <stdarg.h>
                     21: 
                     22: #ifdef __GLIBC__
                     23: #define _GNU_SOURCE
                     24: #include <getopt.h>
                     25: #endif
                     26: 
                     27: #include "sysinclude.h"
                     28: #include "mconfig.h"
                     29: #include "config.h"
                     30: #include "kernel/kernel.h"
                     31: #include "dict.h"
                     32: #include "kernel/stack.h"
                     33: #include "arch/unix/plugins.h"
                     34: #include "libopenbios/bindings.h"
                     35: #include "libopenbios/openbios.h"
                     36: #include "openbios-version.h"
                     37: 
                     38: #include "blk.h"
                     39: #include "libopenbios/ofmem.h"
                     40: 
                     41: #define MEMORY_SIZE    (4*1024*1024)   /* 4M ram for hosted system */
                     42: #define DICTIONARY_SIZE        (256*1024)      /* 256k for the dictionary   */
                     43: 
                     44: #if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS==64)
                     45: #define lseek lseek64
                     46: #define __LFS O_LARGEFILE
                     47: #else
                     48: #define __LFS 0
                     49: #endif
                     50: 
                     51: /* prototypes */
                     52: static void exit_terminal(void);
                     53: void boot(void);
                     54: 
                     55: unsigned long virt_offset = 0;
                     56: 
                     57: /* local variables */
                     58: 
                     59: static ucell *memory;
                     60: 
                     61: static int diskemu;
                     62: 
                     63: static int segfault = 0;
                     64: static int verbose = 0;
                     65: 
                     66: #if defined(CONFIG_PPC) || defined(CONFIG_SPARC64)
                     67: unsigned long isa_io_base;
                     68: #endif
                     69: 
                     70: int errno_int; /* implement for fs drivers, needed to build on Mac OS X */
                     71: 
                     72: ucell ofmem_claim(ucell addr, ucell size, ucell align)
                     73: {
                     74:     return 0;
                     75: }
                     76: 
                     77: #ifdef CONFIG_PPC
                     78: extern void flush_icache_range(char *start, char *stop);
                     79: 
                     80: void flush_icache_range(char *start, char *stop)
                     81: {
                     82: }
                     83: #endif
                     84: 
                     85: #if 0
                     86: static void write_dictionary(char *filename)
                     87: {
                     88:        FILE *f;
                     89:        xt_t initxt;
                     90: 
                     91:        initxt = findword("initialize-of");
                     92:        if (!initxt)
                     93:                printk("warning: dictionary needs word called initialize-of\n");
                     94: 
                     95:        f = fopen(filename, "w");
                     96:        if (!f) {
                     97:                printk("panic: can't open dictionary.\n");
                     98:                exit_terminal();
                     99:                exit(1);
                    100:        }
                    101: 
                    102:        fwrite(DICTID, 16, 1, f);
                    103:        fwrite(dict, dicthead, 1, f);
                    104: 
                    105:        /* Write start address and last to relocate on load */
                    106:        fwrite(&dict, sizeof(ucell), 1, f);
                    107:        fwrite(&last, sizeof(ucell), 1, f);
                    108: 
                    109:        fclose(f);
                    110: 
                    111: #ifdef CONFIG_DEBUG_DICTIONARY
                    112:        printk("wrote dictionary to file %s.\n", filename);
                    113: #endif
                    114: }
                    115: #endif
                    116: 
                    117: static ucell read_dictionary(char *fil)
                    118: {
                    119:        int ilen;
                    120:        ucell ret;
                    121:        char *mem;
                    122:        FILE *f;
                    123:        struct stat finfo;
                    124: 
                    125:        if (stat(fil, &finfo))
                    126:                return 0;
                    127: 
                    128:        ilen = finfo.st_size;
                    129: 
                    130:        if ((mem = malloc(ilen)) == NULL) {
                    131:                printk("panic: not enough memory.\n");
                    132:                exit_terminal();
                    133:                exit(1);
                    134:        }
                    135: 
                    136:        f = fopen(fil, "r");
                    137:        if (!f) {
                    138:                printk("panic: can't open dictionary.\n");
                    139:                exit_terminal();
                    140:                exit(1);
                    141:        }
                    142: 
                    143:        if (fread(mem, ilen, 1, f) != 1) {
                    144:                printk("panic: can't read dictionary.\n");
                    145:                fclose(f);
                    146:                exit_terminal();
                    147:                exit(1);
                    148:        }
                    149:        fclose(f);
                    150: 
                    151:        ret = load_dictionary(mem, ilen);
                    152: 
                    153:        free(mem);
                    154:        return ret;
                    155: }
                    156: 
                    157: 
                    158: /*
                    159:  * functions used by primitives
                    160:  */
                    161: 
                    162: int availchar(void)
                    163: {
                    164:        int tmp = getc(stdin);
                    165:        if (tmp != EOF) {
                    166:                ungetc(tmp, stdin);
                    167:                return -1;
                    168:        }
                    169:        return 0;
                    170: }
                    171: 
                    172: u8 inb(u32 reg)
                    173: {
                    174: #ifdef CONFIG_PLUGINS
                    175:        io_ops_t *ior = find_iorange(reg);
                    176:        if (ior)
                    177:                return ior->inb(reg);
                    178: #endif
                    179: 
                    180:        printk("TRAP: io byte read @0x%x", reg);
                    181:        return 0xff;
                    182: }
                    183: 
                    184: u16 inw(u32 reg)
                    185: {
                    186: #ifdef CONFIG_PLUGINS
                    187:        io_ops_t *ior = find_iorange(reg);
                    188:        if (ior)
                    189:                return ior->inw(reg);
                    190: #endif
                    191: 
                    192:        printk("TRAP: io word read @0x%x", reg);
                    193:        return 0xffff;
                    194: }
                    195: 
                    196: u32 inl(u32 reg)
                    197: {
                    198: #ifdef CONFIG_PLUGINS
                    199:        io_ops_t *ior = find_iorange(reg);
                    200:        if (ior)
                    201:                return ior->inl(reg);
                    202: #endif
                    203: 
                    204:        printk("TRAP: io long read @0x%x", reg);
                    205:        return 0xffffffff;
                    206: }
                    207: 
                    208: void outb(u32 reg, u8 val)
                    209: {
                    210: #ifdef CONFIG_PLUGINS
                    211:        io_ops_t *ior = find_iorange(reg);
                    212:        if (ior) {
                    213:                ior->outb(reg, val);
                    214:                return;
                    215:        }
                    216: #endif
                    217: 
                    218:        printk("TRAP: io byte write 0x%x -> 0x%x", val, reg);
                    219: }
                    220: 
                    221: void outw(u32 reg, u16 val)
                    222: {
                    223: #ifdef CONFIG_PLUGINS
                    224:        io_ops_t *ior = find_iorange(reg);
                    225:        if (ior) {
                    226:                ior->outw(reg, val);
                    227:                return;
                    228:        }
                    229: #endif
                    230:        printk("TRAP: io word write 0x%x -> 0x%x", val, reg);
                    231: }
                    232: 
                    233: void outl(u32 reg, u32 val)
                    234: {
                    235: #ifdef CONFIG_PLUGINS
                    236:        io_ops_t *ior = find_iorange(reg);
                    237:        if (ior) {
                    238:                ior->outl(reg, val);
                    239:                return;
                    240:        }
                    241: #endif
                    242:        printk("TRAP: io long write 0x%x -> 0x%x", val, reg);
                    243: }
                    244: 
                    245: /*
                    246:  * terminal initialization and cleanup.
                    247:  */
                    248: 
                    249: static struct termios saved_termios;
                    250: 
                    251: static void init_terminal(void)
                    252: {
                    253:        struct termios termios;
                    254: 
                    255:        tcgetattr(0, &saved_termios);
                    256:        tcgetattr(0, &termios);
                    257:        termios.c_lflag &= ~(ICANON | ECHO);
                    258:         termios.c_cc[VMIN] = 1;
                    259:         termios.c_cc[VTIME] = 3; // 300 ms
                    260:        tcsetattr(0, 0, &termios);
                    261: }
                    262: 
                    263: static void exit_terminal(void)
                    264: {
                    265:        tcsetattr(0, 0, &saved_termios);
                    266: }
                    267: 
                    268: /*
                    269:  *  segmentation fault handler. linux specific?
                    270:  */
                    271: 
                    272: static void
                    273: segv_handler(int signo __attribute__ ((unused)),
                    274:             siginfo_t * si, void *context __attribute__ ((unused)))
                    275: {
                    276:        static int count = 0;
                    277:        ucell addr = 0xdeadbeef;
                    278: 
                    279:        if (count) {
                    280:                printk("Died while dumping forth dictionary core.\n");
                    281:                goto out;
                    282:        }
                    283: 
                    284:        count++;
                    285: 
                    286:        if (PC >= (ucell) dict && PC <= (ucell) dict + dicthead)
                    287:                addr = *(ucell *) PC;
                    288: 
                    289:        printk("panic: segmentation violation at %x\n", (ucell)si->si_addr);
                    290:        printk("dict=0x%x here=0x%x(dict+0x%x) pc=0x%x(dict+0x%x)\n",
                    291:               (ucell)dict, (ucell)dict + dicthead, dicthead, PC, PC - (ucell) dict);
                    292:        printk("dstackcnt=%d rstackcnt=%d instruction=%x\n",
                    293:               dstackcnt, rstackcnt, addr);
                    294: 
                    295: #ifdef CONFIG_DEBUG_DSTACK
                    296:        printdstack();
                    297: #endif
                    298: #ifdef CONFIG_DEBUG_RSTACK
                    299:        printrstack();
                    300: #endif
                    301: #if 0
                    302:        printk("Writing dictionary core file\n");
                    303:        write_dictionary("forth.dict.core");
                    304: #endif
                    305: 
                    306:       out:
                    307:        exit_terminal();
                    308:        exit(1);
                    309: }
                    310: 
                    311: /*
                    312:  *  Interrupt handler. linux specific?
                    313:  *  Restore terminal state on ctrl-C.
                    314:  */
                    315: 
                    316: static void
                    317: int_handler(int signo __attribute__ ((unused)),
                    318:             siginfo_t * si __attribute__ ((unused)),
                    319:             void *context __attribute__ ((unused)))
                    320: {
                    321:     printk("\n");
                    322:     exit_terminal();
                    323:     exit(1);
                    324: }
                    325: 
                    326: /*
                    327:  * allocate memory and prepare engine for memory management.
                    328:  */
                    329: 
                    330: static void init_memory(void)
                    331: {
                    332:        memory = malloc(MEMORY_SIZE);
                    333:        if (!memory) {
                    334:                printk("panic: not enough memory on host system.\n");
                    335:                exit_terminal();
                    336:                exit(1);
                    337:        }
                    338: 
                    339:        memset (memory, 0, MEMORY_SIZE);
                    340:        /* we push start and end of memory to the stack
                    341:         * so that it can be used by the forth word QUIT
                    342:         * to initialize the memory allocator
                    343:         */
                    344: 
                    345:        PUSH((ucell) memory);
                    346:        PUSH((ucell) memory + MEMORY_SIZE);
                    347: }
                    348: 
                    349: void exception(__attribute__((unused)) cell no)
                    350: {
                    351:        /*
                    352:         * this is a noop since the dictionary has to take care
                    353:         * itself of errors it generates outside of the bootstrap
                    354:         */
                    355: }
                    356: 
                    357: static void
                    358: arch_init( void )
                    359: {
                    360:        openbios_init();
                    361:        modules_init();
                    362:        if(diskemu!=-1)
                    363:                blk_init();
                    364: 
                    365:        device_end();
                    366:         bind_func("platform-boot", boot);
                    367: }
                    368: 
                    369: int
                    370: read_from_disk( int channel, int unit, int blk, unsigned long mphys, int size )
                    371: {
                    372:        // channels and units not supported yet.
                    373:        unsigned char *buf=(unsigned char *)mphys;
                    374: 
                    375:        if(diskemu==-1)
                    376:                return -1;
                    377: 
                    378:        //printk("read: ch=%d, unit=%d, blk=%ld, phys=%lx, size=%d\n",
                    379:        //              channel, unit, blk, mphys, size);
                    380: 
                    381:        lseek(diskemu, (ducell)blk*512, SEEK_SET);
                    382:        read(diskemu, buf, size);
                    383: 
                    384:        return 0;
                    385: }
                    386: 
                    387: /*
                    388:  * main loop
                    389:  */
                    390: 
                    391: #define BANNER "OpenBIOS core. (C) 2003-2006 Patrick Mauritz, Stefan Reinauer\n"\
                    392:                "This software comes with absolutely no warranty. "\
                    393:                "All rights reserved.\n\n"
                    394: 
                    395: 
                    396: #define USAGE   "usage: %s [options] [dictionary file|source file]\n\n"
                    397: 
                    398: int main(int argc, char *argv[])
                    399: {
                    400:        struct sigaction sa;
                    401: #if 0
                    402:        unsigned char *dictname = NULL;
                    403: #endif
                    404:        int c;
                    405: 
                    406:        const char *optstring = "VvhsD:P:p:f:?";
                    407: 
                    408:        while (1) {
                    409: #ifdef __GLIBC__
                    410:                int option_index = 0;
                    411:                static struct option long_options[] = {
                    412:                        {"version", 0, NULL, 'V'},
                    413:                        {"verbose", 0, NULL, 'v'},
                    414:                        {"help", 0, NULL, 'h'},
                    415: //                     {"dictionary", 1, NULL, 'D'},
                    416:                        {"segfault", 0, NULL, 's'},
                    417: #ifdef CONFIG_PLUGINS
                    418:                        {"plugin-path", 1, NULL, 'P'},
                    419:                        {"plugin", 1, NULL, 'p'},
                    420: #endif
                    421:                        {"file", 1, NULL, 'f'}
                    422:                };
                    423: 
                    424:                c = getopt_long(argc, argv, optstring, long_options,
                    425:                                &option_index);
                    426: #else
                    427:                c = getopt(argc, argv, optstring);
                    428: #endif
                    429:                if (c == -1)
                    430:                        break;
                    431: 
                    432:                switch (c) {
                    433:                case 'V':
                    434:                         printk(BANNER "Version " OPENBIOS_VERSION_STR "\n");
                    435:                        return 0;
                    436:                case 'h':
                    437:                case '?':
                    438:                         printk(BANNER "Version " OPENBIOS_VERSION_STR "\n"
                    439:                                USAGE, argv[0]);
                    440:                        return 0;
                    441:                case 'v':
                    442:                        verbose = 1;
                    443:                        break;
                    444:                case 's':
                    445:                        segfault = 1;
                    446:                        break;
                    447: #if 0
                    448:                case 'D':
                    449:                        printk("Dumping final dictionary to '%s'\n", optarg);
                    450:                        dictname = optarg;
                    451:                        break;
                    452: #endif
                    453: #ifdef CONFIG_PLUGINS
                    454:                case 'P':
                    455:                        printk("Plugin search path is now '%s'\n", optarg);
                    456:                        plugindir = optarg;
                    457:                        break;
                    458:                case 'p':
                    459:                        printk("Loading plugin %s\n", optarg);
                    460:                        load_plugin(optarg);
                    461:                        break;
                    462: #endif
                    463:                case 'f':
                    464:                        diskemu=open(optarg, O_RDONLY|__LFS);
                    465:                        if(diskemu!=-1)
                    466:                                printk("Using %s as harddisk.\n", optarg);
                    467:                        else
                    468:                                printk("%s not found. no harddisk node.\n",
                    469:                                                optarg);
                    470:                        break;
                    471:                default:
                    472:                        return 1;
                    473:                }
                    474:        }
                    475: 
                    476:        if (argc < optind + 1) {
                    477:                printk(USAGE, argv[0]);
                    478:                return 1;
                    479:        }
                    480: 
                    481:        if ((dict = (unsigned char *) malloc(DICTIONARY_SIZE)) == NULL) {
                    482:                printk("panic: not enough memory.\n");
                    483:                return 1;
                    484:        }
                    485: 
                    486:        dictlimit = DICTIONARY_SIZE;
                    487:        memset(dict, 0, DICTIONARY_SIZE);
                    488: 
                    489:        if (!segfault) {
                    490:                if (verbose)
                    491:                        printk("Installing SIGSEGV handler...");
                    492: 
                    493:                sa.sa_sigaction = segv_handler;
                    494:                sigemptyset(&sa.sa_mask);
                    495:                sa.sa_flags = SA_SIGINFO | SA_NODEFER;
                    496:                sigaction(SIGSEGV, &sa, NULL);
                    497: 
                    498:                if (verbose)
                    499:                        printk("done.\n");
                    500:        }
                    501: 
                    502:        /* set terminal to do non blocking reads */
                    503:        init_terminal();
                    504: 
                    505:         if (verbose)
                    506:             printk("Installing SIGINT handler...");
                    507: 
                    508:         sa.sa_sigaction = int_handler;
                    509:         sigemptyset(&sa.sa_mask);
                    510:         sa.sa_flags = SA_SIGINFO | SA_NODEFER;
                    511:         sigaction(SIGINT, &sa, NULL);
                    512: 
                    513:         if (verbose)
                    514:             printk("done.\n");
                    515: 
                    516:        read_dictionary(argv[optind]);
                    517:        forth_init();
                    518: 
                    519:        PUSH_xt( bind_noname_func(arch_init) );
                    520:        fword("PREPOST-initializer");
                    521: 
                    522:        PC = (cell)findword("initialize-of");
                    523:        if (PC) {
                    524:                if (verbose) {
                    525:                        if (optind + 1 != argc)
                    526:                                printk("Warning: only first dictionary used.\n");
                    527: 
                    528:                        printk("dictionary loaded (%d bytes).\n", dicthead);
                    529:                        printk("Initializing memory...");
                    530:                }
                    531:                init_memory();
                    532: 
                    533:                if (verbose) {
                    534:                        printk("done\n");
                    535: 
                    536:                        printk("Jumping to dictionary...");
                    537:                }
                    538: 
                    539:                enterforth((xt_t)PC);
                    540: #if 0
                    541:                if (dictname != NULL)
                    542:                        write_dictionary(dictname);
                    543: #endif
                    544: 
                    545:                free(memory);
                    546: 
                    547:        } else {                /* input file is not a dictionary */
                    548:                printk("not supported.\n");
                    549:        }
                    550: 
                    551:        exit_terminal();
                    552:        if (diskemu!=-1)
                    553:                close(diskemu);
                    554: 
                    555:        free(dict);
                    556:        return 0;
                    557: }
                    558: 
                    559: #undef printk
                    560: int
                    561: printk( const char *fmt, ... )
                    562: {
                    563:        int i;
                    564: 
                    565:        va_list args;
                    566:        va_start( args, fmt );
                    567:        i = vprintf(fmt, args );
                    568:        va_end( args );
                    569:        return i;
                    570: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.