sval ofh_finddevice(uval nargs, uval nrets, sval argp[], sval retp[], uval b) { if (nargs == 1) { if (nrets == 1) { sval *ap = DRELA(&ofh_active_package, b); const char *devspec = (const char *)argp[0]; sval *ph = &retp[0]; void *mem = ofd_mem(b); /* good enuff */ if (devspec[0] == '\0') { if (*ap == -1) { return OF_FAILURE; } *ph = *ap; } else { *ph = ofd_node_find(mem, devspec); if (*ph <= 0) { return OF_FAILURE; } } *ap = *ph; return OF_SUCCESS; } } return OF_FAILURE; }
static void ofd_bootargs(void) { static const char *sepr[] = {" -- ", " || "}; char *p; ofdn_t chosen; int sepr_index; int rc; if (builtin_cmdline[0] == '\0') { chosen = ofd_node_find((void *)oftree, "/chosen"); rc = ofd_getprop((void *)oftree, chosen, "bootargs", builtin_cmdline, CONFIG_CMDLINE_SIZE); } /* look for delimiter: "--" or "||" */ for (sepr_index = 0; sepr_index < ARRAY_SIZE(sepr); sepr_index++){ p = strstr(builtin_cmdline, sepr[sepr_index]); if (p != NULL) { /* Xen proper should never know about the dom0 args. */ *p = '\0'; p += strlen(sepr[sepr_index]); dom0_cmdline = p; break; } } xen_cmdline = builtin_cmdline; }
static ofdn_t ofd_cpus_props(void *m, struct domain *d) { static const char path[] = "/cpus"; static const char cpu[] = "cpu"; u32 val = 1; ofdn_t n; ofdn_t c; static u32 ibm_pft_size[] = { 0x0, 0x0 }; n = ofd_node_find(m, path); if (n == 0) { n = ofd_node_add(m, OFD_ROOT, path, sizeof (path)); ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1); } ofd_prop_add(m, n, "#address-cells", &val, sizeof(val)); ofd_prop_add(m, n, "#size-cells", &val, sizeof(val)); ofd_prop_add(m, n, "smp-enabled", NULL, 0); #ifdef HV_EXPOSE_PERFORMANCE_MONITOR ofd_prop_add(m, n, "performance-monitor", NULL, 0); #endif c = ofd_node_find_by_prop(m, n, "device_type", cpu, sizeof (cpu)); if (ofd_boot_cpu == -1) ofd_boot_cpu = c; while (c > 0) { /* We do not use the OF tree to identify secondary processors * so we must prune them from the tree */ if (c == ofd_boot_cpu) { ofdn_t p; ibm_pft_size[1] = d->arch.htab.log_num_ptes + LOG_PTE_SIZE; ofd_prop_add(m, c, "ibm,pft-size", ibm_pft_size, sizeof (ibm_pft_size)); /* get rid of non-standard properties */ p = ofd_prop_find(m, c, "cpu#"); if (p > 0) { ofd_prop_remove(m, c, p); } /* FIXME: Check the the "l2-cache" property who's * contents is an orphaned phandle? */ } else ofd_node_prune(m, c); c = ofd_node_find_next(m, c); } return n; }
static ofdn_t ofd_options_props(void *m) { static const char path[] = "/options"; static const char boot[] = "true"; ofdn_t n; n = ofd_node_find(m, path); if (n == 0) { n = ofd_node_add(m, OFD_ROOT, path, sizeof (path)); ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1); } ofd_prop_add(m, n, "auto-boot?", boot, sizeof(boot)); return n; }
static ofdn_t ofd_aliases_props(void *m) { static const char path[] = "/aliases"; static const char screen[] = "/vdevice/vty@0"; ofdn_t n; n = ofd_node_find(m, path); if (n == 0) { n = ofd_node_add(m, OFD_ROOT, path, sizeof (path)); ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1); } ofd_prop_add(m, n, "screen", screen, sizeof(screen)); return n; }
static ofdn_t ofd_chosen_props(void *m) { ofdn_t n; ofdn_t p; static const char path[] = "/chosen"; static const char console[] = " console=hvc0 nosmp"; char b[257]; uval sz = 0; // " root=/dev/hda " // " rootfstype=ramfs " // "init=/bin/sh " // "root=/dev/nfsroot " // "nfsroot=9.2.208.21:/,rsize=1024,wsize=1024 " // "ether=0,0,eth0 " //nfsaddrs=<wst-IP> :<srv-IP> :<gw-IP> :<netm-IP> :<hostname> //"nfsaddrs=9.2.208.161:9.2.208.21:9.2.208.2:255.255.248.0:freakazoid " //"nfsaddrs=9.2.208.161:9.2.208.21:9.2.208.2:255.255.248.0:freakazoid:eth0 " n = ofd_node_find(m, path); if (n == 0) { n = ofd_node_add(m, OFD_ROOT, path, sizeof (path)); ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1); } sz = strlen(default_bootargs); memcpy(b, default_bootargs, sz); assert(sz + sizeof(console) <= 256, "boot args not big enough\n"); memcpy(b + sz, console, sizeof (console)); sz += sizeof (console); ofd_prop_add(m, n, "bootargs", b, sz); ofd_prop_add(m, n, "bootpath", NULL, 0); hputs("Remove /chosen/mmu, stub will replace\n"); p = ofd_prop_find(m, n, "mmu"); if (p > 0) { ofd_prop_remove(m, n, p); } return n; }
ofdn_t ofd_xics_props(void *m) { ofdn_t n; static const char path[] = "/interrupt-controller"; static const char compat[] = "IBM,ppc-xicp"; static const char model[] = "IBM, BoaC, PowerPC-PIC, 00"; static const char dtype[] = "PowerPC-External-Interrupt-Presentation"; /* * I don't think these are used for anything but linux wants * it. I seems to describe some per processor location for * IPIs but that is a complete guess. */ static const uval32 reg[] = { 0x000003e0, 0x0f000000, 0x00000000, 0x00001000, 0x000003e0, 0x0f001000, 0x00000000, 0x00001000, 0x000003e0, 0x0f002000, 0x00000000, 0x00001000, 0x000003e0, 0x0f003000, 0x00000000, 0x00001000, 0x000003e0, 0x0f004000, 0x00000000, 0x00001000, 0x000003e0, 0x0f005000, 0x00000000, 0x00001000, 0x000003e0, 0x0f006000, 0x00000000, 0x00001000, 0x000003e0, 0x0f007000, 0x00000000, 0x00001000, 0x000003e0, 0x0f008000, 0x00000000, 0x00001000, 0x000003e0, 0x0f009000, 0x00000000, 0x00001000, 0x000003e0, 0x0f00a000, 0x00000000, 0x00001000, 0x000003e0, 0x0f00b000, 0x00000000, 0x00001000, 0x000003e0, 0x0f00c000, 0x00000000, 0x00001000, 0x000003e0, 0x0f00d000, 0x00000000, 0x00001000, 0x000003e0, 0x0f00e000, 0x00000000, 0x00001000, 0x000003e0, 0x0f00f000, 0x00000000, 0x00001000, }; n = ofd_node_find(m, path); if (n == 0) { n = ofd_node_add(m, OFD_ROOT, path, sizeof (path)); ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1); } ofd_prop_add(m, n, "built-in", NULL, 0); ofd_prop_add(m, n, "compatible", compat, sizeof(compat)); ofd_prop_add(m, n, "device_type", dtype, sizeof(dtype)); ofd_prop_add(m, n, "model", model, sizeof(model)); ofd_prop_add(m, n, "reg", reg, sizeof(reg)); return n; }
static ofdn_t ofd_chosen_props(void *m, const char *cmdline) { ofdn_t n; ofdn_t p; static const char path[] = "/chosen"; char bootargs[256] = { 0, }; int bsz; int sz; int rm; n = ofd_node_find(m, path); if (n == 0) { n = ofd_node_add(m, OFD_ROOT, path, sizeof (path)); ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1); } if (cmdline) strlcpy(bootargs, cmdline, sizeof(bootargs)); bsz = strlen(bootargs) + 1; rm = sizeof (bootargs) - bsz; if (default_bootargs != NULL) { sz = strlen(default_bootargs); if (sz > rm) { panic("default_bootargs is too big: 0x%x > 0x%x\n", sz, rm); } else if (sz > 0) { memcpy(&bootargs[bsz - 1], default_bootargs, sz + 1); bsz += sz; rm -= sz; } } printk("DOM0 bootargs: %s\n", bootargs); ofd_prop_add(m, n, "bootargs", bootargs, bsz); ofd_prop_add(m, n, "bootpath", NULL, 0); printk("Remove /chosen/mmu, stub will replace\n"); p = ofd_prop_find(m, n, "mmu"); if (p > 0) { ofd_prop_remove(m, n, p); } return n; }
static ofdn_t ofd_aliases_props(void *m) { static const char path[] = "/aliases"; static const char vty[] = "/vdevice/vty@0"; static const char net[] = "/vdevice/l-lan@1"; ofdn_t n; n = ofd_node_find(m, path); if (n == 0) { n = ofd_node_add(m, OFD_ROOT, path, sizeof (path)); ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1); } ofd_prop_add(m, n, "screen", vty, sizeof(vty)); ofd_prop_add(m, n, "net", net, sizeof(net)); ofd_prop_add(m, n, "network", net, sizeof(net)); return n; }
static ofdn_t ofd_openprom_props(void *m) { static const char path[] = "/openprom"; static const char vernum[] = "IBM,XenOF0.1"; ofdn_t n; n = ofd_node_find(m, path); if (n == 0) { n = ofd_node_add(m, OFD_ROOT, path, sizeof (path)); ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1); } /* I want to override */ ofd_prop_add(m, n, "model", vernum, sizeof(vernum)); ofd_prop_add(m, n, "ibm,fw-vernum_encoded", vernum, sizeof(vernum)); ofd_prop_add(m, n, "relative-addressing", NULL, 0); return n; }
void ofh_rtas_init(ulong b) { static const char path[] = "/rtas"; ofdn_t n; void *m = ofd_mem(b); u32 sz; n = ofd_node_find(m, DRELA(&path[0], b)); if (n <= 0) return; sz = (_rtas_image_end - _rtas_image_start); /* Round size up to a multiple of 0x1000 */ sz = ALIGN_UP(sz, PAGE_SIZE); ofd_prop_add(m, n, DRELA((const char *)"rtas-size", b), &sz, sizeof(sz)); /* create an IO node */ ofd_io_create(m, n, (ulong)rtas_open); }
sval ofh_canon(uval nargs, uval nrets, sval argp[], sval retp[], uval b) { if (nargs == 3) { if (nrets == 1) { const char *dev_spec = (const char *)argp[0]; char *buf = (char *)argp[1]; uval sz = argp[2]; uval *len = &retp[0]; void *mem = ofd_mem(b); ofdn_t ph; ph = ofd_node_find(mem, dev_spec); if (ph > 0) { *len = ofd_node_to_path(mem, ph, buf, sz); return OF_SUCCESS; } } } return OF_FAILURE; }
void ofd_platform_probe(void* ofd) { (void)ofd; sval rc; uval rets[1]; rc = hcall_mem_define(rets, MMIO_ADDR, 0xf2000000, 0x02000000); assert(rc == H_Success, "Can't define HT region\n"); hprintf("Defined HyperTransport MMIO: %lx\n", rets[0]); /* G5's have a little-endian openpic */ ofd_openpic_probe(ofd, 1); /* Define the ibm,dma-window corresponding to a complete DART */ uval32 ofd_pci_dma_window[] = { 0, 0, 0, 0, 0, 1<<31 }; ofdn_t n = ofd_node_find(ofd, "pci"); if (n > 0) ofd_prop_add(ofd, n, "ibm,dma-window", &ofd_pci_dma_window, sizeof (ofd_pci_dma_window)); }
static ofdn_t ofd_memory_props(void *m, uval mem_size) { ofdn_t n = 0; char fmt[] = "/memory@%lx"; char name[] = "memory"; uval32 v; uval start = 0; ofdn_t old; /* Remove all old memory props */ do { old = ofd_node_find_by_prop(m, OFD_ROOT, "device_type", name, sizeof(name)); if (old <= 0) break; ofd_node_prune(m, old); } while (1); while (start < mem_size) { /* FIXME: these two properties need to be set during parition * contruction */ struct reg { uval64 addr; uval64 sz; }; char path[64]; uval l = snprintf(path, 64, fmt, start); n = ofd_node_add(m, OFD_ROOT, path, l+1); ofd_prop_add(m, n, "name", name, sizeof (name)); v = 1; ofd_prop_add(m, n, "#address-cells", &v, sizeof (v)); v = 0; ofd_prop_add(m, n, "#size-cells", &v, sizeof (v)); ofd_prop_add(m, n, "device_type", name, sizeof (name)); /* physical addresses usable without regard to OF */ struct reg reg; reg.addr = start; reg.sz = mem_size - start; if (reg.sz > CHUNK_SIZE) { reg.sz = CHUNK_SIZE; } /* free list of physical addresses available after OF and * client program have been accounted for */ /* FIXME: obviously making this up */ if (start == 0) { struct reg avail = { .addr = 0, .sz = CHUNK_SIZE - (1024 * 1024), }; ofd_prop_add(m, n, "available", &avail, sizeof (avail)); } ofd_prop_add(m, n, "reg", ®, sizeof (reg)); start += reg.sz; } return n; } static ofdn_t ofd_prune(void *m, const char *devspec) { ofdn_t n; int rc = -1; while ((n = ofd_node_find(m, devspec)) > 0) { rc = ofd_node_prune(m, n); } return rc; }
static ofdn_t ofd_cpus_props(void *m, struct partition_status *ps) { static const char path[] = "/cpus"; static const char cpu[] = "cpu"; uval32 val = 1; ofdn_t n; ofdn_t c; static uval32 ibm_pft_size[] = { 0x0, 0x0 }; n = ofd_node_find(m, path); if (n == 0) { n = ofd_node_add(m, OFD_ROOT, path, sizeof (path)); ofd_prop_add(m, n, "name", &path[1], sizeof (path) - 1); } ofd_prop_add(m, n, "#address-cells", &val, sizeof(val)); ofd_prop_add(m, n, "#size-cells", &val, sizeof(val)); ofd_prop_add(m, n, "smp-enabled", NULL, 0); #ifdef HV_EXPOSE_PERFORMANCE_MONITOR ofd_prop_add(m, n, "performance-monitor", NULL, 0); #endif c = ofd_node_find_by_prop(m, n, "device_type", cpu, sizeof (cpu)); //assert(c > 0, "can't get first processor\n"); while (c > 0) { ibm_pft_size[1] = ps->log_htab_bytes; ofd_prop_add(m, c, "ibm,pft-size", ibm_pft_size, sizeof (ibm_pft_size)); /* FIXME: we don't sleep to good yet so if on simulator lie * about the clock speed */ if (onsim()) { val = 100000000; ofd_prop_add(m, c, "clock-frequency", &val, sizeof(val)); ofd_prop_add(m, c, "timebase-frequency", &val, sizeof(val)); } /* FIXME: Check the the "l2-cache" property who's * contents is an orphaned phandle? */ ofd_per_proc_props(m, c, ps->lpid); c = ofd_node_find_next(m, c); /* Since we are not MP yet we can prune the rest of the CPUs */ while (c > 0) { ofdn_t nc; nc = ofd_node_find_next(m, c); ofd_node_prune(m, c); c = nc; } } ofd_proc_props(m, ps->lpid); return n; }