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 sval release(uval b, uval virt, uval size) { struct of_malloc_s *cp; uval i; uval end; end = virt + size; /* you cannot release OF's own space */ if (virt >= (uval)_start && end < (uval)_end) { return OF_FAILURE; } cp = DRELA(&claimed[0], b); /* don't care about speed at the moment */ for (i = 0; i < sizeof (claimed)/sizeof (claimed[0]); i++) { if (virt == cp[i].ofm_start && end == cp[i].ofm_end) { cp[i].ofm_start = 0; cp[i].ofm_end = 0; return OF_SUCCESS; } } return OF_FAILURE; }
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); }
static int rtas_instantiate_rtas(u32 nargs, u32 nrets, s32 argp[], s32 retp[], ulong b) { if (nargs == 1) { if (nrets == 1) { void *rtas_base_address = (void *)(ulong)argp[0]; u32 sz = (_rtas_image_end - _rtas_image_start); memcpy(rtas_base_address, DRELA(&_rtas_image_start[0], b), sz); retp[0] = (ulong)rtas_base_address; return OF_SUCCESS; } } return OF_FAILURE; }
static sval claim(uval b, uval virt, uval size, uval align, uval *baseaddr) { struct of_malloc_s *cp; uval i; sval e; uval end; if (align != 0) { /* we don't do this now */ return OF_FAILURE; } end = virt + size; /* you cannot claim OF's own space */ if (virt >= (uval)_start && end < (uval)_end) { return OF_FAILURE; } cp = DRELA(&claimed[0], b); /* don't care about speed at the moment */ e = -1; for (i = 0; i < sizeof (claimed)/sizeof (claimed[0]); i++) { if (cp[i].ofm_end == 0) { if (e == -1) { e = i; } continue; } if (virt >= cp[i].ofm_start && virt < cp[i].ofm_end) { return OF_FAILURE; } if (end >= cp[i].ofm_start && end < cp[i].ofm_end) { return OF_FAILURE; } } /* e points to the first empty */ cp[e].ofm_start = virt; cp[e].ofm_end = end; *baseaddr = virt; return OF_SUCCESS; }
static int rtas_open(u32 b) { u32 ih = DRELA((u32)&_ih_rtas, b); return ih; }
void ofh_cons_init(uval chan, uval b) { *DRELA(&ofh_cchan, b) = chan; }