/* * Obtain the MAC address via the Redboot environment. */ static int ar71xx_redboot_get_macaddr(void) { char *var; int count = 0, i; uint32_t macaddr[ETHER_ADDR_LEN]; uint8_t tmpmac[ETHER_ADDR_LEN]; /* * "ethaddr" is passed via envp on RedBoot platforms * "kmac" is passed via argv on RouterBOOT platforms */ if ((var = kern_getenv("ethaddr")) != NULL || (var = kern_getenv("kmac")) != NULL) { count = sscanf(var, "%x%*c%x%*c%x%*c%x%*c%x%*c%x", &macaddr[0], &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], &macaddr[5]); if (count < 6) { memset(macaddr, 0, sizeof(macaddr)); } else { for (i = 0; i < ETHER_ADDR_LEN; i++) tmpmac[i] = macaddr[i] & 0xff; (void) ar71xx_mac_addr_init(ar71xx_board_mac_addr, tmpmac, 0, /* offset */ 0); /* is_local */ } freeenv(var); return (0); } return (-1); }
static int atkbdc_getquirks(void) { int i; char* bios_vendor = kern_getenv("smbios.bios.vendor"); char* maker = kern_getenv("smbios.system.maker"); char* product = kern_getenv("smbios.system.product"); for (i=0; quirks[i].quirk != 0; ++i) if (QUIRK_STR_MATCH(quirks[i].bios_vendor, bios_vendor) && QUIRK_STR_MATCH(quirks[i].maker, maker) && QUIRK_STR_MATCH(quirks[i].product, product)) return (quirks[i].quirk); return (0); }
static void vfs_mountroot_conf0(struct sbuf *sb) { char *s, *tok, *mnt, *opt; int error; sbuf_printf(sb, ".onfail panic\n"); sbuf_printf(sb, ".timeout %d\n", root_mount_timeout); if (boothowto & RB_ASKNAME) sbuf_printf(sb, ".ask\n"); #ifdef ROOTDEVNAME if (boothowto & RB_DFLTROOT) sbuf_printf(sb, "%s\n", ROOTDEVNAME); #endif if (boothowto & RB_CDROM) { sbuf_printf(sb, "cd9660:/dev/cd0 ro\n"); sbuf_printf(sb, ".timeout 0\n"); sbuf_printf(sb, "cd9660:/dev/acd0 ro\n"); sbuf_printf(sb, ".timeout %d\n", root_mount_timeout); } s = kern_getenv("vfs.root.mountfrom"); if (s != NULL) { opt = kern_getenv("vfs.root.mountfrom.options"); tok = s; error = parse_token(&tok, &mnt); while (!error) { sbuf_printf(sb, "%s %s\n", mnt, (opt != NULL) ? opt : ""); free(mnt, M_TEMP); error = parse_token(&tok, &mnt); } if (opt != NULL) freeenv(opt); freeenv(s); } if (rootdevnames[0] != NULL) sbuf_printf(sb, "%s\n", rootdevnames[0]); if (rootdevnames[1] != NULL) sbuf_printf(sb, "%s\n", rootdevnames[1]); #ifdef ROOTDEVNAME if (!(boothowto & RB_DFLTROOT)) sbuf_printf(sb, "%s\n", ROOTDEVNAME); #endif if (!(boothowto & RB_ASKNAME)) sbuf_printf(sb, ".ask\n"); }
static bool dmi_found(const struct dmi_system_id *dsi) { char *hw_vendor, *hw_prod; int i, slot; bool res; hw_vendor = kern_getenv("smbios.planar.maker"); hw_prod = kern_getenv("smbios.planar.product"); res = true; for (i = 0; i < nitems(dsi->matches); i++) { slot = dsi->matches[i].slot; switch (slot) { case DMI_NONE: break; case DMI_SYS_VENDOR: case DMI_BOARD_VENDOR: if (hw_vendor != NULL && !strcmp(hw_vendor, dsi->matches[i].substr)) { break; } else { res = false; goto out; } case DMI_PRODUCT_NAME: case DMI_BOARD_NAME: if (hw_prod != NULL && !strcmp(hw_prod, dsi->matches[i].substr)) { break; } else { res = false; goto out; } default: res = false; goto out; } } out: freeenv(hw_vendor); freeenv(hw_prod); return (res); }
int proto_probe(device_t dev, const char *prefix, char ***devnamesp) { char **devnames = *devnamesp; const char *dn, *ep, *ev; size_t pfxlen; int idx, names; if (devnames == NULL) { pfxlen = strlen(prefix); names = 1; /* NULL pointer */ ev = kern_getenv("hw.proto.attach"); if (ev != NULL) { dn = ev; while (*dn != '\0') { ep = dn; while (*ep != ',' && *ep != '\0') ep++; if ((ep - dn) > pfxlen && strncmp(dn, prefix, pfxlen) == 0) names++; dn = (*ep == ',') ? ep + 1 : ep; } } devnames = malloc(names * sizeof(caddr_t), M_DEVBUF, M_WAITOK | M_ZERO); *devnamesp = devnames; if (ev != NULL) { dn = ev; idx = 0; while (*dn != '\0') { ep = dn; while (*ep != ',' && *ep != '\0') ep++; if ((ep - dn) > pfxlen && strncmp(dn, prefix, pfxlen) == 0) { devnames[idx] = malloc(ep - dn + 1, M_DEVBUF, M_WAITOK | M_ZERO); memcpy(devnames[idx], dn, ep - dn); idx++; } dn = (*ep == ',') ? ep + 1 : ep; } freeenv(__DECONST(char *, ev)); } } dn = device_get_desc(dev); while (*devnames != NULL) { if (strcmp(dn, *devnames) == 0) return (BUS_PROBE_SPECIFIC); devnames++; } return (BUS_PROBE_HOOVER); }
static void parse_dir_ask_printenv(const char *var) { char *val; val = kern_getenv(var); if (val != NULL) { printf(" %s=%s\n", var, val); freeenv(val); } }
static void xen_pv_set_boothowto(void) { int i; char *env; /* get equivalents from the environment */ for (i = 0; howto_names[i].ev != NULL; i++) { if ((env = kern_getenv(howto_names[i].ev)) != NULL) { boothowto |= howto_names[i].mask; freeenv(env); } } }
/* Convert the U-Boot command line into FreeBSD kenv and boot options. */ static void cmdline_set_env(char *cmdline, const char *guard) { char *cmdline_next, *env; size_t size, guard_len; int i; size = strlen(cmdline); /* Skip leading spaces. */ for (; isspace(*cmdline) && (size > 0); cmdline++) size--; /* Test and remove guard. */ if (guard != NULL && guard[0] != '\0') { guard_len = strlen(guard); if (strncasecmp(cmdline, guard, guard_len) != 0) return; cmdline += guard_len; size -= guard_len; } /* Skip leading spaces. */ for (; isspace(*cmdline) && (size > 0); cmdline++) size--; /* Replace ',' with '\0'. */ /* TODO: implement escaping for ',' character. */ cmdline_next = cmdline; while(strsep(&cmdline_next, ",") != NULL) ; init_static_kenv(cmdline, 0); /* Parse boothowto. */ for (i = 0; howto_names[i].ev != NULL; i++) { env = kern_getenv(howto_names[i].ev); if (env != NULL) { if (strtoul(env, NULL, 10) != 0) boothowto |= howto_names[i].mask; freeenv(env); } } }
static int detect_hs21(struct bce_softc *bce_sc) { char *sysenv; int found, i; found = 0; sysenv = kern_getenv("smbios.system.product"); if (sysenv == NULL) return (found); for (i = 0; i < nitems(hs21_type_lists); i++) { if (bce_sc->bce_chipid == hs21_type_lists[i].id && strncmp(sysenv, hs21_type_lists[i].prod, strlen(hs21_type_lists[i].prod)) == 0) { found++; break; } } freeenv(sysenv); return (found); }
static void mips_init(void) { struct mem_region mr[FDT_MEM_REGIONS]; uint64_t val; int i, j, mr_cnt; char *memsize; printf("entry: mips_init()\n"); bootverbose = 1; for (i = 0; i < 10; i++) phys_avail[i] = 0; dump_avail[0] = phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end); /* * The most low memory MT7621 can have. Currently MT7621 is the chip * that supports the most memory, so that seems reasonable. */ realmem = btoc(448 * 1024 * 1024); if (fdt_get_mem_regions(mr, &mr_cnt, &val) == 0) { physmem = btoc(val); printf("RAM size: %ldMB (from FDT)\n", ctob(physmem) / (1024 * 1024)); KASSERT((phys_avail[0] >= mr[0].mr_start) && \ (phys_avail[0] < (mr[0].mr_start + mr[0].mr_size)), ("First region is not within FDT memory range")); /* Limit size of the first region */ phys_avail[1] = (mr[0].mr_start + MIN(mr[0].mr_size, ctob(realmem))); dump_avail[1] = phys_avail[1]; /* Add the rest of the regions */ for (i = 1, j = 2; i < mr_cnt; i++, j+=2) { phys_avail[j] = mr[i].mr_start; phys_avail[j+1] = (mr[i].mr_start + mr[i].mr_size); dump_avail[j] = phys_avail[j]; dump_avail[j+1] = phys_avail[j+1]; } } else { if ((memsize = kern_getenv("memsize")) != NULL) { physmem = btoc(strtol(memsize, NULL, 0) << 20); printf("RAM size: %ldMB (from memsize)\n", ctob(physmem) / (1024 * 1024)); } else { /* All else failed, assume 32MB */ physmem = btoc(32 * 1024 * 1024); printf("RAM size: %ldMB (assumed)\n", ctob(physmem) / (1024 * 1024)); } if (ctob(physmem) < (448 * 1024 * 1024)) { /* * Anything up to 448MB is assumed to be directly * mappable as low memory... */ dump_avail[1] = phys_avail[1] = ctob(physmem); } else if (mtk_soc_get_socid() == MTK_SOC_MT7621) { /* * On MT7621 the low memory is limited to 448MB, the * rest is high memory, mapped at 0x20000000 */ phys_avail[1] = 448 * 1024 * 1024; phys_avail[2] = 0x20000000; phys_avail[3] = phys_avail[2] + ctob(physmem) - phys_avail[1]; dump_avail[1] = phys_avail[1] - phys_avail[0]; dump_avail[2] = phys_avail[2]; dump_avail[3] = phys_avail[3] - phys_avail[2]; } else { /* * We have > 448MB RAM and we're not MT7621? Currently * there is no such chip, so we'll just limit the RAM to * 32MB and let the user know... */ printf("Unknown chip, assuming 32MB RAM\n"); physmem = btoc(32 * 1024 * 1024); dump_avail[1] = phys_avail[1] = ctob(physmem); } } if (physmem < realmem) realmem = physmem; init_param1(); init_param2(physmem); mips_cpu_init(); pmap_bootstrap(); mips_proc0_init(); mutex_init(); kdb_init(); #ifdef KDB if (boothowto & RB_KDB) kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); #endif }
/* * Initialize the local APIC on the BSP. */ static int madt_setup_local(void) { ACPI_TABLE_DMAR *dmartbl; vm_paddr_t dmartbl_physaddr; const char *reason; char *hw_vendor; u_int p[4]; int user_x2apic; bool bios_x2apic; madt = pmap_mapbios(madt_physaddr, madt_length); if ((cpu_feature2 & CPUID2_X2APIC) != 0) { reason = NULL; /* * Automatically detect several configurations where * x2APIC mode is known to cause troubles. User can * override the setting with hw.x2apic_enable tunable. */ dmartbl_physaddr = acpi_find_table(ACPI_SIG_DMAR); if (dmartbl_physaddr != 0) { dmartbl = acpi_map_table(dmartbl_physaddr, ACPI_SIG_DMAR); if ((dmartbl->Flags & ACPI_DMAR_X2APIC_OPT_OUT) != 0) reason = "by DMAR table"; acpi_unmap_table(dmartbl); } if (vm_guest == VM_GUEST_VMWARE) { vmware_hvcall(VMW_HVCMD_GETVCPU_INFO, p); if ((p[0] & VMW_VCPUINFO_VCPU_RESERVED) != 0 || (p[0] & VMW_VCPUINFO_LEGACY_X2APIC) == 0) reason = "inside VMWare without intr redirection"; } else if (vm_guest == VM_GUEST_XEN) { reason = "due to running under XEN"; } else if (vm_guest == VM_GUEST_NO && CPUID_TO_FAMILY(cpu_id) == 0x6 && CPUID_TO_MODEL(cpu_id) == 0x2a) { hw_vendor = kern_getenv("smbios.planar.maker"); /* * It seems that some Lenovo and ASUS * SandyBridge-based notebook BIOSes have a * bug which prevents booting AP in x2APIC * mode. Since the only way to detect mobile * CPU is to check northbridge pci id, which * cannot be done that early, disable x2APIC * for all Lenovo and ASUS SandyBridge * machines. */ if (hw_vendor != NULL) { if (!strcmp(hw_vendor, "LENOVO") || !strcmp(hw_vendor, "ASUSTeK Computer Inc.")) { reason = "for a suspected SandyBridge BIOS bug"; } freeenv(hw_vendor); } } bios_x2apic = lapic_is_x2apic(); if (reason != NULL && bios_x2apic) { if (bootverbose) printf("x2APIC should be disabled %s but " "already enabled by BIOS; enabling.\n", reason); reason = NULL; } if (reason == NULL) x2apic_mode = 1; else if (bootverbose) printf("x2APIC available but disabled %s\n", reason); user_x2apic = x2apic_mode; TUNABLE_INT_FETCH("hw.x2apic_enable", &user_x2apic); if (user_x2apic != x2apic_mode) { if (bios_x2apic && !user_x2apic) printf("x2APIC disabled by tunable and " "enabled by BIOS; ignoring tunable."); else x2apic_mode = user_x2apic; } } lapic_init(madt->Address); printf("ACPI APIC Table: <%.*s %.*s>\n", (int)sizeof(madt->Header.OemId), madt->Header.OemId, (int)sizeof(madt->Header.OemTableId), madt->Header.OemTableId); /* * We ignore 64-bit local APIC override entries. Should we * perhaps emit a warning here if we find one? */ return (0); }
/* * bios32_init * * Locate various bios32 entities. */ static void bios32_init(void *junk) { u_long sigaddr; struct bios32_SDheader *sdh; struct PnPBIOS_table *pt; u_int8_t ck, *cv; int i; char *p; /* * BIOS32 Service Directory, PCI BIOS */ /* look for the signature */ if ((sigaddr = bios_sigsearch(0, "_32_", 4, 16, 0)) != 0) { /* get a virtual pointer to the structure */ sdh = (struct bios32_SDheader *)(uintptr_t)BIOS_PADDRTOVADDR(sigaddr); for (cv = (u_int8_t *)sdh, ck = 0, i = 0; i < (sdh->len * 16); i++) { ck += cv[i]; } /* If checksum is OK, enable use of the entrypoint */ if ((ck == 0) && (BIOS_START <= sdh->entry ) && (sdh->entry < (BIOS_START + BIOS_SIZE))) { bios32_SDCI = BIOS_PADDRTOVADDR(sdh->entry); if (bootverbose) { printf("bios32: Found BIOS32 Service Directory header at %p\n", sdh); printf("bios32: Entry = 0x%x (%x) Rev = %d Len = %d\n", sdh->entry, bios32_SDCI, sdh->revision, sdh->len); } /* Allow user override of PCI BIOS search */ if (((p = kern_getenv("machdep.bios.pci")) == NULL) || strcmp(p, "disable")) { /* See if there's a PCI BIOS entrypoint here */ PCIbios.ident.id = 0x49435024; /* PCI systems should have this */ if (!bios32_SDlookup(&PCIbios) && bootverbose) printf("pcibios: PCI BIOS entry at 0x%x+0x%x\n", PCIbios.base, PCIbios.entry); } if (p != NULL) freeenv(p); } else { printf("bios32: Bad BIOS32 Service Directory\n"); } } /* * PnP BIOS * * Allow user override of PnP BIOS search */ if ((((p = kern_getenv("machdep.bios.pnp")) == NULL) || strcmp(p, "disable")) && ((sigaddr = bios_sigsearch(0, "$PnP", 4, 16, 0)) != 0)) { /* get a virtual pointer to the structure */ pt = (struct PnPBIOS_table *)(uintptr_t)BIOS_PADDRTOVADDR(sigaddr); for (cv = (u_int8_t *)pt, ck = 0, i = 0; i < pt->len; i++) { ck += cv[i]; } /* If checksum is OK, enable use of the entrypoint */ if (ck == 0) { PnPBIOStable = pt; if (bootverbose) { printf("pnpbios: Found PnP BIOS data at %p\n", pt); printf("pnpbios: Entry = %x:%x Rev = %d.%d\n", pt->pmentrybase, pt->pmentryoffset, pt->version >> 4, pt->version & 0xf); if ((pt->control & 0x3) == 0x01) printf("pnpbios: Event flag at %x\n", pt->evflagaddr); if (pt->oemdevid != 0) printf("pnpbios: OEM ID %x\n", pt->oemdevid); } } else {