void vbus_attach(device_t parent, device_t self, void *aux) { struct vbus_softc *sc = device_private(self); struct mainbus_attach_args *ma = aux; int node; sc->sc_bustag = vbus_alloc_bus_tag(sc, ma->ma_bustag); sc->sc_dmatag = ma->ma_dmatag; printf("\n"); for (node = OF_child(ma->ma_node); node; node = OF_peer(node)) { struct vbus_attach_args va; char buf[32]; bzero(&va, sizeof(va)); va.va_node = node; if (OF_getprop(node, "name", buf, sizeof(buf)) <= 0) continue; va.va_name = buf; va.va_bustag = sc->sc_bustag; va.va_dmatag = sc->sc_dmatag; prom_getprop(node, "reg", sizeof(*va.va_reg), &va.va_nreg, (void **)&va.va_reg); prom_getprop(node, "interrupts", sizeof(*va.va_intr), &va.va_nintr, (void **)&va.va_intr); config_found(self, &va, vbus_print); } struct vbus_attach_args va; bzero(&va, sizeof(va)); va.va_name = "rtc"; config_found(self, &va, vbus_print); }
static int sbbc_find_dip(dev_info_t *dip, void *arg) { char *node_name; sbbc_find_dip_t *dip_struct = (sbbc_find_dip_t *)arg; char status[OBP_MAXPROPNAME]; /* * Need to find a node named "bootbus-controller" that is neither * disabled nor failed. If a node is not ok, there will be an * OBP status property. Therefore, we will look for a node * without the status property. */ node_name = ddi_node_name(dip); if (strcmp(node_name, "bootbus-controller") == 0 && DDI_CF2(dip) && (prom_getprop(ddi_get_nodeid(dip), "status", (caddr_t)status) == -1) && (prom_getprop(ddi_get_nodeid(ddi_get_parent(dip)), "status", (caddr_t)status) == -1)) { if (dip != dip_struct->cur_dip) { dip_struct->new_dip = (void *)dip; return (DDI_WALK_TERMINATE); } } return (DDI_WALK_CONTINUE); }
static int walk_cpus_cb(pnode_t node, void *arg, void *result) { walk_cpu_data_t *wcd = arg; /* * Sun4v doesn't support port_id on guest. */ #ifndef sun4v int port_id; #endif /* sun4v */ if (!prom_devicetype(node, OBP_CPU)) return (PROM_WALK_CONTINUE); #ifndef sun4v if ((prom_getprop(node, "portid", (caddr_t)&port_id) == -1) && (prom_getprop(node, "upa-portid", (caddr_t)&port_id) == -1) && (prom_getprop(node, "cpuid", (caddr_t)&port_id) == -1)) { warn("cpu node %x has no identifying properties\n", node); return (PROM_WALK_CONTINUE); } #endif /* sun4v */ if (wcd->wcd_cb(node, wcd->wcd_arg, result) != 0) return (PROM_WALK_TERMINATE); return (PROM_WALK_CONTINUE); }
static int cpuunit_setup_attach_args(struct cpuunit_softc *sc, bus_space_tag_t bustag, int node, struct cpuunit_attach_args *cpua) { int n, error; memset(cpua, 0, sizeof(*cpua)); error = prom_getprop(node, "name", 1, &n, &cpua->cpua_name); if (error) return (error); cpua->cpua_name[n] = '\0'; error = prom_getprop(node, "device_type", 1, &n, &cpua->cpua_type); if (error) { free(cpua->cpua_name, M_DEVBUF); return (error); } cpua->cpua_bustag = bustag; cpua->cpua_node = node; cpua->cpua_device_id = sc->sc_device_id; return (0); }
void ibd_init(void) { pnode_t chosen; char *mtuprop = "ipib-frame-size"; char *bcastprop = "ipib-broadcast"; char *addrprop = "ipib-address"; char *cidprop = "client-id"; int cidlen; uint8_t dhcpcid[DHCP_MAX_CID_LEN]; mac_state.mac_addr_len = IPOIB_ADDRL; mac_state.mac_addr_buf = bkmem_alloc(mac_state.mac_addr_len); if (mac_state.mac_addr_buf == NULL) prom_panic("ibd_init: Cannot allocate memory."); chosen = prom_finddevice("/chosen"); if (chosen == OBP_NONODE || chosen == OBP_BADNODE) prom_panic("ibd_init: Cannot find /chosen."); if (prom_getprop(chosen, addrprop, (caddr_t)mac_state.mac_addr_buf) != IPOIB_ADDRL) prom_panic("ibd_init: Cannot find /chosen:ipib-address\n."); if (prom_getprop(chosen, bcastprop, (caddr_t)&ibdbroadcastaddr) != IPOIB_ADDRL) prom_panic("ibd_init: Cannot find /chosen:ipib-broadcast\n."); if (((cidlen = prom_getproplen(chosen, cidprop)) <= 0) || (cidlen > DHCP_MAX_CID_LEN) || (prom_getprop(chosen, cidprop, (caddr_t)&dhcpcid) != cidlen)) prom_panic("ibd_init: Invalid /chosen:client-id\n."); dhcp_set_client_id(dhcpcid, cidlen); /* * Note that prom reports mtu including 20 bytes of * addressing information. */ if (prom_getprop(chosen, mtuprop, (caddr_t)&mac_state.mac_mtu) <= 0) mac_state.mac_mtu = IBDSIZE + IPOIB_ADDRL; /* * Tell upper layers that we can support a little * more. We will be taking off these 20 bytes at * the start before we invoke prom_write() to send * over the wire. */ mac_state.mac_arp_timeout = IBD_ARP_TIMEOUT; mac_state.mac_in_timeout = IBD_IN_TIMEOUT; mac_state.mac_arp = ibd_arp; mac_state.mac_rarp = ibd_revarp; mac_state.mac_header_len = ibd_header_len; mac_state.mac_input = ibd_input; mac_state.mac_output = ibd_output; }
int mc_get_dimm_size(pnode_t nodeid) { uint64_t psi_addr; uint_t dimmtype; int i, rlen; struct sf_memunit_regspec reg; rlen = prom_getproplen(nodeid, "reg"); if (rlen != sizeof (struct sf_memunit_regspec)) return (-1); if (prom_getprop(nodeid, "reg", (caddr_t)®) < 0) return (-1); psi_addr = ((uint64_t)reg.regspec_addr_hi) << 32; psi_addr |= (uint64_t)reg.regspec_addr_lo; psi_addr = STARFIRE_MC_DIMMTYPE_ADDR(psi_addr); if (psi_addr == (uint64_t)-1) return (-1); dimmtype = ldphysio(psi_addr); dimmtype &= STARFIRE_MC_DIMMSIZE_MASK; for (i = 0; dimmsize_table[i].mc_type != 0; i++) if (dimmsize_table[i].mc_type == dimmtype) break; return (dimmsize_table[i].mc_module_size); }
/* * This routine returns B_TRUE if the bootpath corresponds to * IP over IB driver. * * The format of the bootpath for the IP over IB looks like * /pci@1f,700000/pci@1/ib@0:port=1,pkey=8001,protocol=ip * * The minor node portion "port=1,pkey=8001,protocol=ip" represents * IP over IB driver. */ static boolean_t netboot_over_ib(char *bootpath) { char *temp; boolean_t ret = B_FALSE; pnode_t node = prom_finddevice(bootpath); int len; char devicetype[OBP_MAXDRVNAME]; /* Is this IB node ? */ len = prom_getproplen(node, OBP_DEVICETYPE); if (len <= 1 || len >= OBP_MAXDRVNAME) return (B_FALSE); (void) prom_getprop(node, OBP_DEVICETYPE, (caddr_t)devicetype); if (strncmp("ib", devicetype, 2) == 0) { /* Check for proper IP over IB string */ if ((temp = strstr(bootpath, ":port=")) != NULL) { if ((temp = strstr(temp, ",pkey=")) != NULL) if ((temp = strstr(temp, ",protocol=ip")) != NULL) { ret = B_TRUE; } } } return (ret); }
/* * The first psycho must always programmed up for the system clock and error * handling purposes. */ static void have_pci(pnode_t node) { int size; uint_t portid; char compatible[OBP_MAXDRVNAME]; size = GETPROPLEN(node, "portid"); if (size == -1) size = GETPROPLEN(node, "upa-portid"); if (size == -1) return; if (size > sizeof (portid)) cmn_err(CE_PANIC, "portid size wrong"); if (GETPROP(node, "portid", (caddr_t)&portid) == -1) if (GETPROP(node, "upa-portid", (caddr_t)&portid) == -1) cmn_err(CE_PANIC, "portid not found"); niobus++; /* * Need two physical TSBs for Schizo compatible nodes, * one otherwise. */ compatible[0] = '\0'; (void) prom_getprop(node, OBP_COMPATIBLE, compatible); if (strcmp(compatible, "pci108e,8001") == 0) niommu_tsbs += IOMMU_PER_SCHIZO; else niommu_tsbs++; }
static int promfs_mountroot(char *str) { (void) prom_getprop(prom_chosennode(), str, (caddr_t)&fsih); return (fsih == -1); }
/* * Note that this routine does not take into account the endianness * of the host or the device (or PROM) when retrieving properties. */ static int getlongprop_buf(int id, char *name, char *buf, int maxlen) { int size; size = prom_getproplen((pnode_t)id, name); if (size <= 0 || (size > maxlen - 1)) return (-1); if (-1 == prom_getprop((pnode_t)id, name, buf)) return (-1); /* * Workaround for bugid 1085575 - OBP may return a "name" property * without null terminating the string with '\0'. When this occurs, * append a '\0' and return (size + 1). */ if (strcmp("name", name) == 0) { if (buf[size - 1] != '\0') { buf[size] = '\0'; size += 1; } } return (size); }
void system_check(void) { char buf[PROM_VERS_MAX_LEN]; pnode_t n; char arch[128]; size_t len; bootplat_defaults_t *plat_defaults; /* * This is a sun4v machine iff the device_type property * exists on the root node and has the value "sun4v". * Some older sunfire proms do not have such a property. */ is_sun4v = 0; n = prom_rootnode(); len = prom_getproplen(n, "device_type"); if (len > 0 && len < sizeof (arch)) { (void) prom_getprop(n, "device_type", arch); arch[len] = '\0'; dprintf("device_type=%s\n", arch); if (strcmp(arch, "sun4v") == 0) { is_sun4v = 1; } } else { dprintf("device_type: no such property, len=%d\n", (int)len); } if (!is_sun4v && cpu_is_ultrasparc_1()) { printf("UltraSPARC I processors are not supported by this " "release of Solaris.\n"); prom_exit_to_mon(); } /* * Set up defaults per platform */ plat_defaults = (is_sun4v) ? &sun4v_plat_defaults : &sun4u_plat_defaults; default_name = plat_defaults->plat_defaults_name; default_path = plat_defaults->plat_defaults_path; vac = plat_defaults->plat_defaults_vac; dprintf("default_name: %s\n", default_name); dprintf("default_path: %s\n", default_path); dprintf("vac: %d\n", vac); if (prom_version_check(buf, PROM_VERS_MAX_LEN, NULL) != PROM_VER64_OK) { printf("The firmware on this system does not support the 64-bit" " OS.\n\tPlease upgrade to at least the following version:" "\n\n\t%s\n", buf); prom_exit_to_mon(); } }
void * mmap(void *addr, size_t len, int32_t prot, uint32_t flags, ihandle_t fildes, int32_t off) { ihandle_t dev_ihandle, parent_ihandle; phandle_t dev_phandle, parent_phandle; void *rp; static char reg_prop[100], dev_name[100], bus_type[100]; uint32_t *reg_ptr; uint_t adr_cells, size_cells; dev_ihandle = fildes; dev_phandle = prom_getphandle(dev_ihandle); prom_getprop(dev_phandle, "reg", reg_prop); reg_ptr = (uint32_t *)reg_prop; parent_ihandle = get_parent_ihandle(dev_ihandle); parent_phandle = prom_getphandle(parent_ihandle); prom_getprop(parent_phandle, "#address-cells", (caddr_t)&adr_cells); prom_getprop(parent_phandle, "#size-cells", (caddr_t)&size_cells); prom_getprop(dev_phandle, "name", dev_name); prom_getprop(parent_phandle, "device_type", bus_type); /* * Flashprom devices need special handling of offset arg * as specified by the /dev/flashprom driver */ if ((strcmp(dev_name, "flashprom") == 0)) { if (off != NULL) { reg_ptr += ((off >> 28) & 0xf) * (adr_cells + size_cells); off = (off & 0xfffffff); *(reg_ptr + 1) += off; } rp = (void *)prom_mapin(parent_ihandle, reg_ptr, adr_cells, len); return ((void *)((int32_t)rp & 0xffffffff)); }
static int get_intprop(pnode_t node, caddr_t prop, void *dst) { int len, glen; len = sizeof (uint_t); glen = prom_getprop(node, prop, dst); if (glen != len) return (ERR); return (0); }
void kmdb_prom_preserve_kctx_init(void) { pnode_t pnode; int val; pnode = (pnode_t)prom_getphandle(prom_mmu_ihandle()); if (prom_getprop(pnode, PROM_KCTX_PRESERVED_PROPNAME, (caddr_t)&val) == 0) { kmdb_prom_preserve_kctx = 1; } }
pnode_t kmdb_prom_getcpu_propnode(pnode_t node) { int val; pnode_t pnode; char name[OBP_MAXPROPNAME]; /* * Check for the CMT case where cpu nodes are "strand" nodes * In this case, the "cpu node" properties are contained in * its parent "core" node. */ if (prom_getprop(node, "portid", (caddr_t)&val) == -1 && prom_getprop(node, "upa-portid", (caddr_t)&val) == -1 && prom_getprop((pnode = prom_parentnode(node)), "name", name) != -1 && strcmp(name, "core") == 0) return (pnode); return (node); }
static void cpuunit_attach(device_t parent, device_t self, void *aux) { struct cpuunit_softc *sc = device_private(self); struct mainbus_attach_args *ma = aux; int node, error; bus_space_tag_t sbt; sc->sc_node = ma->ma_node; sc->sc_st = ma->ma_bustag; sc->sc_device_id = prom_getpropint(sc->sc_node, "device-id", -1); sc->sc_board = prom_getpropint(sc->sc_node, "board#", -1); printf(": board #%d, ID %d\n", sc->sc_board, sc->sc_device_id); /* * Initialize the bus space tag we pass on to our children. */ sbt = sc->sc_bustag = malloc(sizeof(*sbt), M_DEVBUF, M_WAITOK); memcpy(sbt, sc->sc_st, sizeof(*sbt)); sbt->cookie = sc; sbt->parent = sc->sc_st; sbt->nranges = 0; sbt->ranges = NULL; /* * Collect address translations from the OBP. */ error = prom_getprop(sc->sc_node, "ranges", sizeof(struct openprom_range), &sbt->nranges, &sbt->ranges); if (error) { printf("%s: error %d getting \"ranges\" property\n", device_xname(self), error); panic("cpuunit_attach"); } /* Attach the CPU (and possibly bootbus) child nodes. */ for (node = firstchild(sc->sc_node); node != 0; node = nextsibling(node)) { struct cpuunit_attach_args cpua; if (cpuunit_setup_attach_args(sc, sbt, node, &cpua)) panic("cpuunit_attach: failed to set up attach args"); (void) config_found(self, &cpua, cpuunit_print); cpuunit_destroy_attach_args(&cpua); } }
/* * Here we use the "screen-#columns" and "screen-#rows" settings of * PROM to help us decide the console size and cursor position. The * actual sizes of PROM's TEM and the console might be different with * those "screen-#.." settings, in cases that they are too big to * accommodate. */ void prom_get_tem_size(size_t *height, size_t *width) { char buf[MAXPATHLEN]; char name[16]; pnode_t node; int len; if ((node = prom_optionsnode()) == OBP_BADNODE) return; (void) prom_strcpy(name, "screen-#rows"); if ((len = prom_getproplen(node, (caddr_t)name)) > 0) { (void) prom_getprop(node, (caddr_t)name, (caddr_t)buf); *height = prom_atol(buf, len); } (void) prom_strcpy(name, "screen-#columns"); if ((len = prom_getproplen(node, (caddr_t)name)) > 0) { (void) prom_getprop(node, (caddr_t)name, (caddr_t)buf); *width = prom_atol(buf, len); } }
ihandle_t prom_memory_ihandle(void) { static ihandle_t imemory; if (imemory != (ihandle_t)0) return (imemory); if (prom_getproplen(prom_chosennode(), "memory") != sizeof (ihandle_t)) return (imemory = (ihandle_t)-1); (void) prom_getprop(prom_chosennode(), "memory", (caddr_t)(&imemory)); return (imemory); }
static int impl_name(char *buf, size_t bufsz) { pnode_t n = prom_rootnode(); size_t len = prom_getproplen(n, "name"); if (len == 0 || len >= bufsz) return (-1); (void) prom_getprop(n, "name", buf); buf[len] = '\0'; return (0); }
static void central_attach(device_t parent, device_t self, void *aux) { struct central_softc *sc = device_private(self); struct mainbus_attach_args *ma = aux; int node0, node; sc->sc_bt = ma->ma_bustag; sc->sc_node = ma->ma_node; sc->sc_cbt = central_alloc_bus_tag(sc); prom_getprop(sc->sc_node, "ranges", sizeof(struct central_range), &sc->sc_nrange, (void **)&sc->sc_range); printf("\n"); node0 = firstchild(sc->sc_node); for (node = node0; node; node = nextsibling(node)) { struct central_attach_args ca; bzero(&ca, sizeof(ca)); ca.ca_node = node; ca.ca_bustag = sc->sc_cbt; if (central_get_string(ca.ca_node, "name", &ca.ca_name)) { printf("can't fetch name for node 0x%x\n", node); continue; } prom_getprop(node, "reg", sizeof(struct central_reg), &ca.ca_nreg, (void **)&ca.ca_reg); (void)config_found(self, (void *)&ca, central_print); if (ca.ca_name != NULL) free(ca.ca_name, M_DEVBUF); } }
/* * Assign memnode to lgroups */ void plat_fill_mc(pnode_t nodeid) { int portid; /* * Enchilada memory controller portid == global CPU id */ if ((prom_getprop(nodeid, "portid", (caddr_t)&portid) == -1) || (portid < 0)) return; if (portid < max_mem_nodes) plat_assign_lgrphand_to_mem_node(portid, portid); }
/* * Mount root fs so we can read statefile, etc * * sets global * cb_rih */ int cb_mountroot() { chosen = prom_chosennode(); if (chosen == OBP_BADNODE) { prom_printf("Missing chosen node\n"); return (ERR); } if (prom_getprop(chosen, "bootfs", (caddr_t)&cb_rih) == -1) { prom_printf("Missing bootfs ihandle\n"); return (ERR); } return (0); }
/* * determine the board number associated with this nodeid */ static int get_boardnum(int nid, dev_info_t *par) { int board_num; if (prom_getprop((pnode_t)nid, OBP_BOARDNUM, (caddr_t)&board_num) != -1) return (board_num); /* * Look at current node and up the parent chain * till we find a node with an OBP_BOARDNUM. */ while (par) { nid = ddi_get_nodeid(par); if (prom_getprop((pnode_t)nid, OBP_BOARDNUM, (caddr_t)&board_num) != -1) return (board_num); par = ddi_get_parent(par); } return (-1); }
/* * Ask prom to open a disk file given either the OBP device path, or the * device path representing the target drive/partition and the fs-relative * path of the file. Handle file pathnames with or without leading '/'. * if fs points to a null char, it indicates that we are opening a device. */ int cpr_statefile_open(char *path, char *fs_dev) { int plen, dlen; int handle; char fs_pkg[OBP_MAXPATHLEN]; char fs_name[OBP_MAXDRVNAME]; /* * instead of using specialstate, we use fs as the flag */ if (*fs_dev == '\0') { /* device open */ statefile_special = 1; handle = prom_open(path); /* IEEE1275 prom_open returns 0 on failure; we return -1 */ return (handle ? handle : -1); } /* * No cif for $open-package, so we have to use interpret */ if (prom_getprop(chosen, "fs-package", fs_pkg) == -1) { prom_printf("Missing fs-package name\n"); return (-1); } plen = prom_strlen(fs_pkg); dlen = prom_strlen(fs_dev); prom_interpret("$open-package swap l!", plen, (uintptr_t)fs_pkg, dlen, (uintptr_t)fs_dev, (uintptr_t)&cb_rih); if (cb_rih == OBP_BADNODE || cb_rih == 0) { prom_printf("Can't open %s\n", fs_pkg); return (-1); } if (volname) { return (cpr_fs_volopen(volname)); } /* * Prepend '/' if it's not there already */ if (*path != '/') { (void) prom_sprintf(fs_name, "/%s", path); return (cpr_fs_open(fs_name)); } else return (cpr_fs_open(path)); }
int prom_devicetype(pnode_t id, char *type) { register int len; char buf[OBP_MAXDRVNAME]; len = prom_getproplen(id, OBP_DEVICETYPE); if (len <= 0 || len >= OBP_MAXDRVNAME) return (0); (void) prom_getprop(id, OBP_DEVICETYPE, (caddr_t)buf); if (prom_strcmp(type, buf) == 0) return (1); return (0); }
int prom_getnode_byname(pnode_t id, char *name) { int len; char buf[OBP_MAXDRVNAME]; len = prom_getproplen(id, OBP_NAME); if (len <= 0 || len >= OBP_MAXDRVNAME) return (0); (void) prom_getprop(id, OBP_NAME, (caddr_t)buf); if (prom_strcmp(name, buf) == 0) return (1); return (0); }
/* * returns non-zero on error, otherwise returns 0 and * sets the result code based on (prop value == "true") */ static int cpr_get_bool_prop(char *name, int *result) { char value[PROP_BOOL_LEN]; pnode_t node; int len, err; if (err = cpr_get_options_node(&node)) return (err); len = prom_getproplen(node, name); if (len < 0 || len >= sizeof (value)) return (ENXIO); bzero(value, sizeof (value)); if (prom_getprop(node, name, value) != len) return (ENOENT); *result = (strcmp(value, "true") == 0); return (0); }
/** * @brief Initializes the OpenBoot PROM interface on an early boot stage. * Before using any routines in the prom library, prom_init() must be * called. This should be one of the first things to be done on bootup, * since it provides the output sink and the prom version that it used * for feedback and debugging purposes. */ void prom_init() { node_chosen = prom_finddevice("/chosen"); if (!node_chosen || (int) node_chosen == -1) prom_exit(); if(prom_getprop(node_chosen, "stdout", &node_stdout, sizeof(node_stdout)) <= 0) node_stdout = 0; if(prom_getprop(node_stdin, "stdin", &node_stdin, sizeof(node_stdin)) <= 0) node_stdin = 0; node_root = prom_finddevice("/"); if (!node_root || (int) node_root == -1) { printk("Error: / device not found.\n"); prom_exit(); } if(prom_getprop(node_root, "compatible", prom_subarch, sizeof(prom_subarch)) <= 0) { printk("Note: compatible property not set.\n"); /* not important, we can check compatibility with the %ver register */ strncpy(prom_subarch, "unknown", 7); } node_obp = prom_finddevice("/openprom"); if (!node_obp || (int) node_obp == -1) { printk("Error: /openprom device not found.\n"); prom_exit(); } if(prom_getprop(node_obp, "version", prom_version, sizeof(prom_version)) <= 0) { printk("Error: /openprom version property not found.\n"); prom_exit(); } if(strncmp("OBP ", prom_version, 4)) { printk("Error: Unknown OpenPROM version.\n"); prom_exit(); } prom_getprop(node_chosen, "bootpath", prom_bootpath, sizeof(prom_bootpath)); prom_getprop(node_chosen, "bootargs", prom_bootargs, sizeof(prom_bootargs)); /* if we found stdout, we can now clear the screen for the boot messages */ if(node_stdout != 0) clear_screen(); }
uint64_t mc_get_asr_addr(pnode_t nodeid) { int rlen; uint64_t psi_addr; struct sf_memunit_regspec reg; rlen = prom_getproplen(nodeid, "reg"); if (rlen != sizeof (struct sf_memunit_regspec)) return ((uint64_t)-1); if (prom_getprop(nodeid, "reg", (caddr_t)®) < 0) return ((uint64_t)-1); psi_addr = ((uint64_t)reg.regspec_addr_hi) << 32; psi_addr |= (uint64_t)reg.regspec_addr_lo; return (STARFIRE_MC_ASR_ADDR(psi_addr)); }
uint64_t mc_get_alignment_mask(pnode_t nodeid) { uint64_t psi_addr, seg_sz; uint_t mcreg, seg_sz_mask; int i, rlen; struct sf_memunit_regspec reg; rlen = prom_getproplen(nodeid, "reg"); if (rlen != sizeof (struct sf_memunit_regspec)) return (-1); if (prom_getprop(nodeid, "reg", (caddr_t)®) < 0) return (-1); psi_addr = ((uint64_t)reg.regspec_addr_hi) << 32; psi_addr |= (uint64_t)reg.regspec_addr_lo; psi_addr = STARFIRE_MC_ASR_ADDR(psi_addr); if (psi_addr == (uint64_t)-1) return (-1); mcreg = ldphysio(psi_addr); seg_sz_mask = (mcreg & STARFIRE_MC_MASK_MASK) >> 8; for (i = 0; mc_seg_table[i].seg_size != 0; i++) if (mc_seg_table[i].seg_mask == seg_sz_mask) break; if (mc_seg_table[i].seg_size == 0) seg_sz = mc_get_mem_alignment(); else seg_sz = mc_seg_table[i].seg_size; #ifdef DEBUG printf("nodeid %x, mc asr addr %lx, val %x, seg_sz_mask %x, " "seg_sz %lx\n", nodeid, psi_addr, mcreg, seg_sz_mask, seg_sz); #endif /* DEBUG */ return (seg_sz - 1); }