Annotation of qemu/roms/openbios/arch/unix/unix.c, revision 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.