int mmu_init(void) { if (CPU_ISSUN4 || CPU_ISSUN4C) { pmap_map = pmap_map4; pmap_extract = pmap_extract4; if (CPU_ISSUN4) { /* Find out if we're on a 3-lvl sun4 MMU. */ struct idprom *idp = prom_getidprom(); if (idp->id_machine == ID_SUN4_400) sun4_mmu3l = 1; } /* * XXX - we just guess which MMU cookies are free: * region 0 maps [0-16MB] * segment 0-16 map [0-4MB] * the PROM mappings use high-valued cookies. */ rcookie = 2; scookie = 17; } else if (CPU_ISSUN4M || CPU_ISSUN4D) { char buf[32]; pmap_map = pmap_map_srmmu; pmap_extract = pmap_extract_srmmu; snprintf(buf, sizeof buf, "obmem %lx L!", (u_long)&obmem); prom_interpret(buf); } else return (ENOTSUP); return (0); }
/* * Attach the mainbus. * * Our main job is to attach the CPU (the root node we got in configure()) * and iterate down the list of `mainbus devices' (children of that node). * We also record the `node id' of the default frame buffer, if any. */ static void mainbus_attach(device_t parent, device_t dev, void *aux) { extern struct sparc_bus_dma_tag mainbus_dma_tag; extern struct sparc_bus_space_tag mainbus_space_tag; struct mainbus_attach_args ma; char sbuf[32]; const char *const *ssp, *sp = NULL; char *c; int node0, node, rv, i; static const char *const openboot_special[] = { /* ignore these (end with NULL) */ /* * These are _root_ devices to ignore. Others must be handled * elsewhere. */ "virtual-memory", "aliases", "memory", "openprom", "options", "packages", "chosen", NULL }; if (OF_getprop(findroot(), "banner-name", machine_banner, sizeof machine_banner) < 0) i = 0; else { i = 1; if (((c = strchr(machine_banner, '(')) != NULL) && c != &machine_banner[0]) { while (*c == '(' || *c == ' ') { *c = '\0'; c--; } } } OF_getprop(findroot(), "name", machine_model, sizeof machine_model); prom_getidprom(); if (i) aprint_normal(": %s (%s): hostid %lx\n", machine_model, machine_banner, hostid); else aprint_normal(": %s: hostid %lx\n", machine_model, hostid); aprint_naive("\n"); /* * Locate and configure the ``early'' devices. These must be * configured before we can do the rest. For instance, the * EEPROM contains the Ethernet address for the LANCE chip. * If the device cannot be located or configured, panic. */ if (sparc_ncpus == 0) panic("None of the CPUs found"); /* * Init static interrupt eventcounters */ for (i = 0; i < __arraycount(intr_evcnts); i++) evcnt_attach_static(&intr_evcnts[i]); node = findroot(); /* first early device to be configured is the CPU */ for (node = OF_child(node); node; node = OF_peer(node)) { if (OF_getprop(node, "device_type", sbuf, sizeof(sbuf)) <= 0) continue; if (strcmp(sbuf, "cpu") != 0) continue; memset(&ma, 0, sizeof(ma)); ma.ma_bustag = &mainbus_space_tag; ma.ma_dmatag = &mainbus_dma_tag; ma.ma_node = node; ma.ma_name = "cpu"; config_found(dev, &ma, mbprint); } node = findroot(); /* re-init root node */ /* Find the "options" node */ node0 = OF_child(node); /* * Configure the devices, in PROM order. Skip * PROM entries that are not for devices, or which must be * done before we get here. */ for (node = node0; node; node = OF_peer(node)) { int portid; DPRINTF(ACDB_PROBE, ("Node: %x", node)); if ((OF_getprop(node, "device_type", sbuf, sizeof(sbuf)) > 0) && strcmp(sbuf, "cpu") == 0) continue; OF_getprop(node, "name", sbuf, sizeof(sbuf)); DPRINTF(ACDB_PROBE, (" name %s\n", sbuf)); for (ssp = openboot_special; (sp = *ssp) != NULL; ssp++) if (strcmp(sbuf, sp) == 0) break; if (sp != NULL) continue; /* an "early" device already configured */ memset(&ma, 0, sizeof ma); ma.ma_bustag = &mainbus_space_tag; ma.ma_dmatag = &mainbus_dma_tag; ma.ma_name = sbuf; ma.ma_node = node; if (OF_getprop(node, "upa-portid", &portid, sizeof(portid)) != sizeof(portid) && OF_getprop(node, "portid", &portid, sizeof(portid)) != sizeof(portid)) portid = -1; ma.ma_upaid = portid; if (prom_getprop(node, "reg", sizeof(*ma.ma_reg), &ma.ma_nreg, &ma.ma_reg) != 0) continue; #ifdef DEBUG if (autoconf_debug & ACDB_PROBE) { if (ma.ma_nreg) printf(" reg %08lx.%08lx\n", (long)ma.ma_reg->ur_paddr, (long)ma.ma_reg->ur_len); else printf(" no reg\n"); } #endif rv = prom_getprop(node, "interrupts", sizeof(*ma.ma_interrupts), &ma.ma_ninterrupts, &ma.ma_interrupts); if (rv != 0 && rv != ENOENT) { free(ma.ma_reg, M_DEVBUF); continue; } #ifdef DEBUG if (autoconf_debug & ACDB_PROBE) { if (ma.ma_interrupts) printf(" interrupts %08x\n", *ma.ma_interrupts); else printf(" no interrupts\n"); } #endif rv = prom_getprop(node, "address", sizeof(*ma.ma_address), &ma.ma_naddress, &ma.ma_address); if (rv != 0 && rv != ENOENT) { free(ma.ma_reg, M_DEVBUF); if (ma.ma_ninterrupts) free(ma.ma_interrupts, M_DEVBUF); continue; } #ifdef DEBUG if (autoconf_debug & ACDB_PROBE) { if (ma.ma_naddress) printf(" address %08x\n", *ma.ma_address); else printf(" no address\n"); } #endif (void) config_found(dev, (void *)&ma, mbprint); free(ma.ma_reg, M_DEVBUF); if (ma.ma_ninterrupts) free(ma.ma_interrupts, M_DEVBUF); if (ma.ma_naddress) free(ma.ma_address, M_DEVBUF); } /* Try to attach PROM console */ memset(&ma, 0, sizeof ma); ma.ma_name = "pcons"; (void) config_found(dev, (void *)&ma, mbprint); }