const void * mpbios_search(struct device *self, paddr_t start, int count, struct mp_map *map) { struct mp_map t; int i, len; const struct mpbios_fps *m; int end = count - sizeof(*m); const u_int8_t *base = mpbios_map(start, count, &t); if (mp_verbose) printf("%s: scanning 0x%lx to 0x%lx for MP signature\n", self->dv_xname, start, start + count - sizeof(*m)); for (i = 0; i <= end; i += 4) { m = (struct mpbios_fps *)&base[i]; if ((m->signature == MP_FP_SIG) && ((len = m->length << 4) != 0) && mpbios_cksum(m, (m->length << 4)) == 0) { mpbios_unmap(&t); return (mpbios_map(start + i, len, map)); } } mpbios_unmap(&t); return (0); }
const void * mpbios_search(device_t self, paddr_t start, int count, struct mp_map *map) { struct mp_map t; int i, len; const struct mpbios_fps *m; int end = count - sizeof(*m); const uint8_t *base = mpbios_map (start, count, &t); if (mp_verbose) aprint_verbose_dev(self, "scanning 0x%jx to 0x%jx for MP signature\n", (uintmax_t)start, (uintmax_t)(start+count-sizeof(*m))); for (i = 0; i <= end; i += 4) { m = (const struct mpbios_fps *)&base[i]; if ((m->signature == MP_FP_SIG) && ((len = m->length << 4) != 0) && mpbios_cksum(m, (m->length << 4)) == 0) { mpbios_unmap (&t); return mpbios_map (start+i, len, map); } } mpbios_unmap(&t); return 0; }
/* * Look for an Intel MP spec table, indicating SMP capable hardware. */ int mpbios_probe(struct device *self) { paddr_t ebda, memtop; paddr_t cthpa; int cthlen; const u_int8_t *mpbios_page; int scan_loc; struct mp_map t; /* * Skip probe if someone else (e.g. acpi) already provided the * necessary details. */ if (mp_busses) return (0); /* see if EBDA exists */ mpbios_page = mpbios_map(0, PAGE_SIZE, &t); /* XXX Ugly magic constants below. */ ebda = *(const u_int16_t *)(&mpbios_page[0x40e]); ebda <<= 4; memtop = *(const u_int16_t *)(&mpbios_page[0x413]); memtop <<= 10; mpbios_page = NULL; mpbios_unmap(&t); scan_loc = 0; if (ebda && ebda < IOM_BEGIN ) { mp_fps = mpbios_search(self, ebda, 1024, &mp_fp_map); if (mp_fps != NULL) goto found; } scan_loc = 1; if (memtop && memtop <= IOM_BEGIN ) { mp_fps = mpbios_search(self, memtop - 1024, 1024, &mp_fp_map); if (mp_fps != NULL) goto found; } scan_loc = 2; mp_fps = mpbios_search(self, BIOS_BASE, BIOS_COUNT, &mp_fp_map); if (mp_fps != NULL) goto found; /* nothing found */ return (0); found: if (mp_verbose) printf("%s: MP floating pointer found in %s at 0x%lx\n", self->dv_xname, loc_where[scan_loc], mp_fp_map.pa); if (mp_fps->pap == 0) { if (mp_fps->mpfb1 == 0) { printf("%s: MP fps invalid: " "no default config and no configuration table\n", self->dv_xname); goto err; } printf("%s: MP default configuration %d\n", self->dv_xname, mp_fps->mpfb1); return (10); } cthpa = mp_fps->pap; mp_cth = mpbios_map(cthpa, sizeof (*mp_cth), &mp_cfg_table_map); cthlen = mp_cth->base_len; mpbios_unmap(&mp_cfg_table_map); mp_cth = mpbios_map(cthpa, cthlen, &mp_cfg_table_map); if (mp_verbose) printf("%s: MP config table at 0x%lx, %d bytes long\n", self->dv_xname, cthpa, cthlen); if (mp_cth->signature != MP_CT_SIG) { printf("%s: MP signature mismatch (%x vs %x)\n", self->dv_xname, MP_CT_SIG, mp_cth->signature); goto err; } if (mpbios_cksum(mp_cth, cthlen)) { printf ("%s: MP Configuration Table checksum mismatch\n", self->dv_xname); goto err; } return (10); err: if (mp_fps) { mp_fps = NULL; mpbios_unmap(&mp_fp_map); } if (mp_cth) { mp_cth = NULL; mpbios_unmap(&mp_cfg_table_map); } return (0); }
/* * Look for an Intel MP spec table, indicating SMP capable hardware. */ int mpbios_probe(device_t self) { paddr_t ebda, memtop; paddr_t cthpa; int cthlen; const uint8_t *mpbios_page; int scan_loc; struct mp_map t; /* If MP is disabled, don't use MPBIOS or the ioapics. */ if ((boothowto & RB_MD1) != 0) return 0; /* see if EBDA exists */ mpbios_page = mpbios_map (0, PAGE_SIZE, &t); ebda = *(const uint16_t *) (&mpbios_page[0x40e]); ebda <<= 4; memtop = *(const uint16_t *) (&mpbios_page[0x413]); memtop <<= 10; mpbios_page = NULL; mpbios_unmap(&t); scan_loc = 0; if (ebda && ebda < IOM_BEGIN ) { mp_fps = mpbios_search(self, ebda, 1024, &mp_fp_map); if (mp_fps != NULL) goto found; } scan_loc = 1; if (memtop && memtop <= IOM_BEGIN ) { mp_fps = mpbios_search(self, memtop - 1024, 1024, &mp_fp_map); if (mp_fps != NULL) goto found; } scan_loc = 2; mp_fps = mpbios_search(self, BIOS_BASE, BIOS_COUNT, &mp_fp_map); if (mp_fps != NULL) goto found; /* nothing found */ return 0; found: if (mp_verbose) aprint_verbose_dev(self, "MP floating pointer found in %s at 0x%jx\n", loc_where[scan_loc], (uintmax_t)mp_fp_map.pa); if (mp_fps->pap == 0) { if (mp_fps->mpfb1 == 0) { aprint_error_dev(self, "MP fps invalid: " "no default config and no configuration table\n"); goto err; } return 10; } cthpa = mp_fps->pap; mp_cth = mpbios_map (cthpa, sizeof (*mp_cth), &mp_cfg_table_map); cthlen = mp_cth->base_len; mpbios_unmap(&mp_cfg_table_map); mp_cth = mpbios_map (cthpa, cthlen, &mp_cfg_table_map); if (mp_verbose) aprint_verbose_dev(self, "MP config table at 0x%jx, %d bytes long\n", (uintmax_t)cthpa, cthlen); if (mp_cth->signature != MP_CT_SIG) { aprint_error_dev(self, "MP signature mismatch (%x vs %x)\n", MP_CT_SIG, mp_cth->signature); goto err; } if (mpbios_cksum(mp_cth, cthlen)) { aprint_error_dev(self, "MP Configuration Table checksum mismatch\n"); goto err; } return 10; err: if (mp_fps) { mp_fps = NULL; mpbios_unmap(&mp_fp_map); } if (mp_cth) { mp_cth = NULL; mpbios_unmap(&mp_cfg_table_map); } return 0; }