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

1.1       root        1: /*
                      2:  * PROM interface support
                      3:  * Copyright 1996 The Australian National University.
                      4:  * Copyright 1996 Fujitsu Laboratories Limited
                      5:  * Copyright 1999 Pete A. Zaitcev
                      6:  * This software may be distributed under the terms of the Gnu
                      7:  * Public License version 2 or later
                      8:  */
                      9: 
                     10: #include <stdarg.h>
                     11: 
                     12: #include "openprom.h"
                     13: #include "config.h"
                     14: #include "libopenbios/bindings.h"
                     15: #include "drivers/drivers.h"
                     16: #include "libopenbios/sys_info.h"
                     17: #include "boot.h"
                     18: #include "romvec.h"
                     19: 
                     20: #ifdef CONFIG_DEBUG_OBP
                     21: #define DPRINTF(fmt, args...)                   \
                     22:     do { printk(fmt , ##args); } while (0)
                     23: #else
                     24: #define DPRINTF(fmt, args...)
                     25: #endif
                     26: 
                     27: char obp_stdin, obp_stdout;
                     28: static int obp_fd_stdin, obp_fd_stdout;
                     29: const char *obp_stdin_path, *obp_stdout_path;
                     30: 
                     31: struct linux_arguments_v0 obp_arg;
                     32: const char *bootpath;
                     33: static const struct linux_arguments_v0 * const obp_argp = &obp_arg;
                     34: 
                     35: static void (*sync_hook)(void);
                     36: 
                     37: static struct linux_romvec romvec0;
                     38: 
                     39: static void doublewalk(__attribute__((unused)) unsigned int ptab1,
                     40:                        __attribute__((unused)) unsigned int va)
                     41: {
                     42: }
                     43: 
                     44: int obp_nextnode(int node)
                     45: {
                     46:     int peer;
                     47: 
                     48:     PUSH(node);
                     49:     fword("peer");
                     50:     peer = POP();
                     51:     DPRINTF("obp_nextnode(0x%x) = 0x%x\n", node, peer);
                     52: 
                     53:     return peer;
                     54: }
                     55: 
                     56: int obp_child(int node)
                     57: {
                     58:     int child;
                     59: 
                     60:     PUSH(node);
                     61:     fword("child");
                     62:     child = POP();
                     63:     DPRINTF("obp_child(0x%x) = 0x%x\n", node, child);
                     64: 
                     65:     return child;
                     66: }
                     67: 
                     68: int obp_proplen(int node, const char *name)
                     69: {
                     70:     int notfound;
                     71: 
                     72:     if (!node) {
                     73:         DPRINTF("obp_proplen(0x0, %s) = -1\n", name);
                     74:         return -1;
                     75:     }
                     76: 
                     77:     push_str(name);
                     78:     PUSH(node);
                     79:     fword("get-package-property");
                     80:     notfound = POP();
                     81: 
                     82:     if (notfound) {
                     83:         DPRINTF("obp_proplen(0x%x, %s) (not found)\n", node, name);
                     84: 
                     85:         return -1;
                     86:     } else {
                     87:         int len;
                     88: 
                     89:         len = POP();
                     90:         (void) POP();
                     91:         DPRINTF("obp_proplen(0x%x, %s) = %d\n", node, name, len);
                     92: 
                     93:         return len;
                     94:     }
                     95: }
                     96: 
                     97: #ifdef CONFIG_DEBUG_OBP
                     98: static int looks_like_string(const char *str, int len)
                     99: {
                    100:     int i;
                    101:     int ret = (str[len-1] == '\0');
                    102:     for (i = 0; i < len-1 && ret; i++)
                    103:     {
                    104:         int ch = str[i] & 0xFF;
                    105:         if (ch < 0x20 || ch > 0x7F)
                    106:             ret = 0;
                    107:     }
                    108:     return ret;
                    109: }
                    110: #endif
                    111: 
                    112: int obp_getprop(int node, const char *name, char *value)
                    113: {
                    114:     int notfound, found;
                    115:     int len;
                    116:     const char *str;
                    117: 
                    118:     if (!node) {
                    119:         DPRINTF("obp_getprop(0x0, %s) = -1\n", name);
                    120:         return -1;
                    121:     }
                    122: 
                    123:     if (!name) {
                    124:         // NULL name means get first property
                    125:         push_str("");
                    126:         PUSH(node);
                    127:         fword("next-property");
                    128:         found = POP();
                    129:         if (found) {
                    130:             len = POP();
                    131:             str = (char *) POP();
                    132:             DPRINTF("obp_getprop(0x%x, NULL) = %s\n", node, str);
                    133: 
                    134:             return (int)str;
                    135:         }
                    136:         DPRINTF("obp_getprop(0x%x, NULL) (not found)\n", node);
                    137: 
                    138:         return -1;
                    139:     } else {
                    140:         push_str(name);
                    141:         PUSH(node);
                    142:         fword("get-package-property");
                    143:         notfound = POP();
                    144:     }
                    145:     if (notfound) {
                    146:         DPRINTF("obp_getprop(0x%x, %s) (not found)\n", node, name);
                    147: 
                    148:         return -1;
                    149:     } else {
                    150:         len = POP();
                    151:         str = (char *) POP();
                    152:         if (len > 0)
                    153:             memcpy(value, str, len);
                    154:         else
                    155:             str = "NULL";
                    156: 
                    157: #ifdef CONFIG_DEBUG_OBP
                    158:         if (looks_like_string(str, len)) {
                    159:             DPRINTF("obp_getprop(0x%x, %s) = %s\n", node, name, str);
                    160:         } else {
                    161:             int i;
                    162:             DPRINTF("obp_getprop(0x%x, %s) = ", node, name);
                    163:             for (i = 0; i < len; i++) {
                    164:                 DPRINTF("%02x%s", str[i] & 0xFF,
                    165:                         (len == 4 || i == len-1) ? "" : " ");
                    166:             }
                    167:             DPRINTF("\n");
                    168:         }
                    169: #endif
                    170: 
                    171:         return len;
                    172:     }
                    173: }
                    174: 
                    175: const char *obp_nextprop(int node, const char *name)
                    176: {
                    177:     int found;
                    178: 
                    179:     if (!name || *name == '\0') {
                    180:         // NULL name means get first property
                    181:         push_str("");
                    182:         name = "NULL";
                    183:     } else {
                    184:         push_str(name);
                    185:     }
                    186:     PUSH(node);
                    187:     fword("next-property");
                    188:     found = POP();
                    189:     if (!found) {
                    190:         DPRINTF("obp_nextprop(0x%x, %s) (not found)\n", node, name);
                    191: 
                    192:         return "";
                    193:     } else {
                    194:         char *str;
                    195: 
                    196:         POP(); /* len */
                    197:         str = (char *) POP();
                    198: 
                    199:         DPRINTF("obp_nextprop(0x%x, %s) = %s\n", node, name, str);
                    200: 
                    201:         return str;
                    202:     }
                    203: }
                    204: 
                    205: int obp_setprop(__attribute__((unused)) int node,
                    206:                        __attribute__((unused)) const char *name,
                    207:                       __attribute__((unused)) char *value,
                    208:                       __attribute__((unused)) int len)
                    209: {
                    210:     DPRINTF("obp_setprop(0x%x, %s) = %s (%d)\n", node, name, value, len);
                    211: 
                    212:     return -1;
                    213: }
                    214: 
                    215: static const struct linux_nodeops nodeops0 = {
                    216:     obp_nextnode_handler,      /* int (*no_nextnode)(int node); */
                    217:     obp_child_handler,         /* int (*no_child)(int node); */
                    218:     obp_proplen_handler,       /* int (*no_proplen)(int node, char *name); */
                    219:     obp_getprop_handler,       /* int (*no_getprop)(int node,char *name,char *val); */
                    220:     obp_setprop_handler,       /* int (*no_setprop)(int node, char *name,
                    221:                                char *val, int len); */
                    222:     obp_nextprop_handler       /* char * (*no_nextprop)(int node, char *name); */
                    223: };
                    224: 
                    225: int obp_nbgetchar(void)
                    226: {
                    227:     return getchar();
                    228: }
                    229: 
                    230: int obp_nbputchar(int ch)
                    231: {
                    232:     putchar(ch);
                    233: 
                    234:     return 0;
                    235: }
                    236: 
                    237: void obp_putstr(char *str, int len)
                    238: {
                    239:     PUSH(pointer2cell(str));
                    240:     PUSH(len);
                    241:     fword("type");
                    242: }
                    243: 
                    244: void obp_printf(const char *fmt, ...)
                    245: {
                    246:     va_list ap;
                    247: 
                    248:     va_start(ap, fmt);
                    249:     printk(fmt, ap);
                    250:     va_end(ap);
                    251: }
                    252: 
                    253: void obp_reboot(char *str)
                    254: {
                    255:     printk("rebooting (%s)\n", str);
                    256:     *reset_reg = 1;
                    257:     printk("reboot failed\n");
                    258:     for (;;) {}
                    259: }
                    260: 
                    261: void obp_abort(void)
                    262: {
                    263:     printk("abort, power off\n");
                    264:     *power_reg = 1;
                    265:     printk("power off failed\n");
                    266:     for (;;) {}
                    267: }
                    268: 
                    269: void obp_halt(void)
                    270: {
                    271:     printk("halt, power off\n");
                    272:     *power_reg = 1;
                    273:     printk("power off failed\n");
                    274:     for (;;) {}
                    275: }
                    276: 
                    277: int obp_devopen(char *str)
                    278: {
                    279:     int ret;
                    280: 
                    281:     push_str(str);
                    282:     fword("open-dev");
                    283:     ret = POP();
                    284:     DPRINTF("obp_devopen(%s) = 0x%x\n", str, ret);
                    285: 
                    286:     return ret;
                    287: }
                    288: 
                    289: int obp_devclose(int dev_desc)
                    290: {
                    291:     int ret = 1;
                    292: 
                    293:     PUSH(dev_desc);
                    294:     fword("close-dev");
                    295: 
                    296:     DPRINTF("obp_devclose(0x%x) = %d\n", dev_desc, ret);
                    297: 
                    298:     return ret;
                    299: }
                    300: 
                    301: int obp_rdblkdev(int dev_desc, int num_blks, int offset, char *buf)
                    302: {
                    303:     int ret, hi, lo, bs;
                    304: 
                    305:     bs = 512;
                    306:     hi = ((uint64_t)offset * bs) >> 32;
                    307:     lo = ((uint64_t)offset * bs) & 0xffffffff;
                    308: 
                    309:     ret = obp_devseek(dev_desc, hi, lo);
                    310: 
                    311:     ret = obp_devread(dev_desc, buf, num_blks * bs) / bs;
                    312: 
                    313:     DPRINTF("obp_rdblkdev(fd 0x%x, num_blks %d, offset %d (hi %d lo %d), buf 0x%x) = %d\n", dev_desc, num_blks, offset, hi, lo, (int)buf, ret);
                    314: 
                    315:     return ret;
                    316: }
                    317: 
                    318: int obp_devread(int dev_desc, char *buf, int nbytes)
                    319: {
                    320:     int ret;
                    321: 
                    322:     PUSH((int)buf);
                    323:     PUSH(nbytes);
                    324:     push_str("read");
                    325:     PUSH(dev_desc);
                    326:     fword("$call-method");
                    327:     ret = POP();
                    328: 
                    329:     DPRINTF("obp_devread(fd 0x%x, buf 0x%x, nbytes %d) = %d\n", dev_desc, (int)buf, nbytes, ret);
                    330: 
                    331:     return ret;
                    332: }
                    333: 
                    334: int obp_devwrite(int dev_desc, char *buf, int nbytes)
                    335: {
                    336: #ifdef CONFIG_DEBUG_OBP_DEVWRITE /* disabled, makes too much noise */
                    337:     int ret;
                    338: #endif
                    339: 
                    340:     PUSH((int)buf);
                    341:     PUSH(nbytes);
                    342:     push_str("write");
                    343:     PUSH(dev_desc);
                    344:     fword("$call-method");
                    345: #ifdef CONFIG_DEBUG_OBP_DEVWRITE
                    346:     ret = POP();
                    347:     DPRINTF("obp_devwrite(fd 0x%x, buf %s, nbytes %d) = %d\n", dev_desc, buf, nbytes, ret);
                    348: #else
                    349:     POP();
                    350: #endif
                    351: 
                    352:     return nbytes;
                    353: }
                    354: 
                    355: int obp_devseek(int dev_desc, int hi, int lo)
                    356: {
                    357:     int ret;
                    358: 
                    359:     PUSH(lo);
                    360:     PUSH(hi);
                    361:     push_str("seek");
                    362:     PUSH(dev_desc);
                    363:     fword("$call-method");
                    364:     ret = POP();
                    365: 
                    366:     DPRINTF("obp_devseek(fd 0x%x, hi %d, lo %d) = %d\n", dev_desc, hi, lo, ret);
                    367: 
                    368:     return ret;
                    369: }
                    370: 
                    371: int obp_inst2pkg(int dev_desc)
                    372: {
                    373:     int ret;
                    374: 
                    375:     PUSH(dev_desc);
                    376:     fword("ihandle>non-interposed-phandle");
                    377:     ret = POP();
                    378: 
                    379:     DPRINTF("obp_inst2pkg(fd 0x%x) = 0x%x\n", dev_desc, ret);
                    380: 
                    381:     return ret;
                    382: }
                    383: 
                    384: int obp_cpustart(__attribute__((unused))unsigned int whichcpu,
                    385:                         __attribute__((unused))int ctxtbl_ptr,
                    386:                         __attribute__((unused))int thiscontext,
                    387:                         __attribute__((unused))char *prog_counter)
                    388: {
                    389:     int cpu, found;
                    390:     struct linux_prom_registers *smp_ctable = (void *)ctxtbl_ptr;
                    391: 
                    392:     DPRINTF("obp_cpustart: cpu %d, ctxptr 0x%x, ctx %d, pc 0x%x\n", whichcpu,
                    393:             smp_ctable->phys_addr, thiscontext, (unsigned int)prog_counter);
                    394: 
                    395:     found = obp_getprop(whichcpu, "mid", (char *)&cpu);
                    396:     if (found == -1)
                    397:         return -1;
                    398:     DPRINTF("cpu found, id %d -> cpu %d\n", whichcpu, cpu);
                    399: 
                    400:     return start_cpu((unsigned int)prog_counter, ((unsigned int)smp_ctable->phys_addr) >> 4,
                    401:               thiscontext, cpu);
                    402: }
                    403: 
                    404: int obp_cpustop(__attribute__((unused)) unsigned int whichcpu)
                    405: {
                    406:     DPRINTF("obp_cpustop: cpu %d\n", whichcpu);
                    407: 
                    408:     return 0;
                    409: }
                    410: 
                    411: int obp_cpuidle(__attribute__((unused)) unsigned int whichcpu)
                    412: {
                    413:     DPRINTF("obp_cpuidle: cpu %d\n", whichcpu);
                    414: 
                    415:     return 0;
                    416: }
                    417: 
                    418: int obp_cpuresume(__attribute__((unused)) unsigned int whichcpu)
                    419: {
                    420:     DPRINTF("obp_cpuresume: cpu %d\n", whichcpu);
                    421: 
                    422:     return 0;
                    423: }
                    424: 
                    425: void obp_fortheval_v2(char *str, int arg0, int arg1, int arg2, int arg3, int arg4)
                    426: {
                    427:   int dstacktmp = 0;
                    428: 
                    429:   // It seems Solaris passes up to 5 arguments which should be pushed onto the Forth
                    430:   // stack for execution. However the API doesn't provide for a way to specify the number
                    431:   // of arguments actually being passed. Hence we preserve the state of the Forth stack 
                    432:   // before, push all the arguments, execute the Forth, then restore the stack to its 
                    433:   // previous state. This enables us to have a variable number of arguments and still 
                    434:   // preserve stack state between subsequent calls.
                    435: 
                    436:   // Preserve stack state
                    437:   dstacktmp = dstackcnt;
                    438: 
                    439:   PUSH(arg4);
                    440:   PUSH(arg3);
                    441:   PUSH(arg2);
                    442:   PUSH(arg1);
                    443:   PUSH(arg0);
                    444: 
                    445:   DPRINTF("obp_fortheval_v2(%x %x %x %x %x %s)\n", arg4, arg3, arg2, arg1, arg0, str);
                    446:   push_str(str);
                    447:   fword("eval");
                    448: 
                    449:   // Restore stack state
                    450:   dstackcnt = dstacktmp;
                    451: }
                    452: 
                    453: void *
                    454: init_openprom(void)
                    455: {
                    456:     /* Setup the openprom vector. Note that all functions should be invoked
                    457:        via their handler (see call-romvec.S) which acts as a proxy to save
                    458:        the globals and setup the stack correctly */
                    459: 
                    460:     // Linux wants a R/W romvec table
                    461:     romvec0.pv_magic_cookie = LINUX_OPPROM_MAGIC;
                    462:     romvec0.pv_romvers = 3;
                    463:     romvec0.pv_plugin_revision = 2;
                    464:     romvec0.pv_printrev = 0x20019;
                    465:     romvec0.pv_v0mem.v0_totphys = &ptphys;
                    466:     romvec0.pv_v0mem.v0_prommap = &ptmap;
                    467:     romvec0.pv_v0mem.v0_available = &ptavail;
                    468:     romvec0.pv_nodeops = &nodeops0;
                    469:     romvec0.pv_bootstr = (void *)doublewalk;
                    470:     romvec0.pv_v0devops.v0_devopen = &obp_devopen_handler;
                    471:     romvec0.pv_v0devops.v0_devclose = &obp_devclose_handler;
                    472:     romvec0.pv_v0devops.v0_rdblkdev = &obp_rdblkdev_handler;
                    473:     romvec0.pv_stdin = &obp_stdin;
                    474:     romvec0.pv_stdout = &obp_stdout;
                    475:     romvec0.pv_getchar = obp_nbgetchar_handler;
                    476:     romvec0.pv_putchar = (void (*)(int))obp_nbputchar_handler;
                    477:     romvec0.pv_nbgetchar = obp_nbgetchar_handler;
                    478:     romvec0.pv_nbputchar = obp_nbputchar_handler;
                    479:     romvec0.pv_putstr = obp_putstr_handler;
                    480:     romvec0.pv_reboot = obp_reboot_handler;
                    481:     romvec0.pv_printf = obp_printf_handler;
                    482:     romvec0.pv_abort = obp_abort_handler;
                    483:     romvec0.pv_halt = obp_halt_handler;
                    484:     romvec0.pv_synchook = &sync_hook;
                    485:     romvec0.pv_v0bootargs = &obp_argp;
                    486:     romvec0.pv_fortheval.v2_eval = obp_fortheval_v2_handler;
                    487:     romvec0.pv_v2devops.v2_inst2pkg = obp_inst2pkg_handler;
                    488:     romvec0.pv_v2devops.v2_dumb_mem_alloc = obp_dumb_memalloc_handler;
                    489:     romvec0.pv_v2devops.v2_dumb_mem_free = obp_dumb_memfree_handler;
                    490:     romvec0.pv_v2devops.v2_dumb_mmap = obp_dumb_mmap_handler;
                    491:     romvec0.pv_v2devops.v2_dumb_munmap = obp_dumb_munmap_handler;
                    492:     romvec0.pv_v2devops.v2_dev_open = obp_devopen_handler;
                    493:     romvec0.pv_v2devops.v2_dev_close = (void (*)(int))obp_devclose_handler;
                    494:     romvec0.pv_v2devops.v2_dev_read = obp_devread_handler;
                    495:     romvec0.pv_v2devops.v2_dev_write = obp_devwrite_handler;
                    496:     romvec0.pv_v2devops.v2_dev_seek = obp_devseek_handler;
                    497: 
                    498:     romvec0.pv_v2bootargs.bootpath = &bootpath;
                    499: 
                    500:     romvec0.pv_v2bootargs.bootargs = &obp_arg.argv[1];
                    501:     romvec0.pv_v2bootargs.fd_stdin = &obp_fd_stdin;
                    502:     romvec0.pv_v2bootargs.fd_stdout = &obp_fd_stdout;
                    503: 
                    504:     push_str(obp_stdin_path);
                    505:     fword("open-dev");
                    506:     obp_fd_stdin = POP();
                    507:     push_str(obp_stdout_path);
                    508:     fword("open-dev");
                    509:     obp_fd_stdout = POP();
                    510: 
                    511:     romvec0.v3_memalloc = obp_memalloc_handler;
                    512: 
                    513:     romvec0.v3_cpustart = obp_cpustart_handler;
                    514:     romvec0.v3_cpustop = obp_cpustop_handler;
                    515:     romvec0.v3_cpuidle = obp_cpuidle_handler;
                    516:     romvec0.v3_cpuresume = obp_cpuresume_handler;
                    517: 
                    518:     return &romvec0;
                    519: }

unix.superglobalmegacorp.com

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