Changeset View
Changeset View
Standalone View
Standalone View
sys/x86/x86/mptable.c
| Show All 24 Lines | |||||
| * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
| * SUCH DAMAGE. | * SUCH DAMAGE. | ||||
| */ | */ | ||||
| #include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
| __FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
| #include "opt_mptable_force_htt.h" | #include "opt_mptable_force_htt.h" | ||||
| #include "opt_mptable_linux_bug_compat.h" | |||||
| #include <sys/param.h> | #include <sys/param.h> | ||||
| #include <sys/systm.h> | #include <sys/systm.h> | ||||
| #include <sys/bus.h> | #include <sys/bus.h> | ||||
| #include <sys/kernel.h> | #include <sys/kernel.h> | ||||
| #include <sys/limits.h> | #include <sys/limits.h> | ||||
| #include <sys/malloc.h> | #include <sys/malloc.h> | ||||
| #include <sys/smp.h> | #include <sys/smp.h> | ||||
| #ifdef NEW_PCIB | #ifdef NEW_PCIB | ||||
| ▲ Show 20 Lines • Show All 199 Lines • ▼ Show 20 Lines | lookup_bus_type(char *name) | ||||
| for (x = 0; x < MAX_BUSTYPE; ++x) | for (x = 0; x < MAX_BUSTYPE; ++x) | ||||
| if (strncmp(bus_type_table[x].name, name, 6) == 0) | if (strncmp(bus_type_table[x].name, name, 6) == 0) | ||||
| return (bus_type_table[x].type); | return (bus_type_table[x].type); | ||||
| return (UNKNOWN_BUSTYPE); | return (UNKNOWN_BUSTYPE); | ||||
| } | } | ||||
| #ifdef MPTABLE_LINUX_BUG_COMPAT | |||||
| /* Compute the correct entry_count value. */ | |||||
| static void | |||||
| compute_entry_count(void) | |||||
| { | |||||
| u_char *end = (u_char *)(mpct) + mpct->base_table_length; | |||||
| u_char *entry = (u_char *)(mpct + 1); | |||||
| size_t nentries = 0; | |||||
| while (entry < end) { | |||||
| switch (*entry) { | |||||
| case MPCT_ENTRY_PROCESSOR: | |||||
| case MPCT_ENTRY_IOAPIC: | |||||
| case MPCT_ENTRY_BUS: | |||||
| case MPCT_ENTRY_INT: | |||||
| case MPCT_ENTRY_LOCAL_INT: | |||||
| break; | |||||
| default: | |||||
| panic("%s: Unknown MP Config Entry %d\n", __func__, | |||||
| (int)*entry); | |||||
| } | |||||
| entry += basetable_entry_types[*entry].length; | |||||
| nentries++; | |||||
| } | |||||
| mpct->entry_count = (uint16_t)(nentries); | |||||
| } | |||||
| #endif | |||||
| /* | /* | ||||
| * Look for an Intel MP spec table (ie, SMP capable hardware). | * Look for an Intel MP spec table (ie, SMP capable hardware). | ||||
| */ | */ | ||||
| static int | static int | ||||
| mptable_probe(void) | mptable_probe(void) | ||||
| { | { | ||||
| int x; | int x; | ||||
| u_long segment; | u_long segment; | ||||
| Show All 12 Lines | if ((x = search_for_sig(target, 1024 / 4)) >= 0) | ||||
| goto found; | goto found; | ||||
| } | } | ||||
| /* search the BIOS */ | /* search the BIOS */ | ||||
| target = (u_int32_t) BIOS_BASE; | target = (u_int32_t) BIOS_BASE; | ||||
| if ((x = search_for_sig(target, BIOS_COUNT)) >= 0) | if ((x = search_for_sig(target, BIOS_COUNT)) >= 0) | ||||
| goto found; | goto found; | ||||
| #ifdef MPTABLE_LINUX_BUG_COMPAT | |||||
| /* | |||||
| * Linux assumes that it always has 640 kB of base memory and | |||||
| * searches for the MP table at 639k regardless of whether that | |||||
| * address is present in the system memory map. Some VM systems | |||||
| * rely on this buggy behaviour. | |||||
| */ | |||||
| if ((x = search_for_sig(639 * 1024, 1024 / 4)) >= 0) | |||||
| goto found; | |||||
| #endif | |||||
| /* nothing found */ | /* nothing found */ | ||||
| return (ENXIO); | return (ENXIO); | ||||
| found: | found: | ||||
| mpfps = (mpfps_t)BIOS_PADDRTOVADDR(x); | mpfps = (mpfps_t)BIOS_PADDRTOVADDR(x); | ||||
| /* Map in the configuration table if it exists. */ | /* Map in the configuration table if it exists. */ | ||||
| if (mpfps->config_type != 0) { | if (mpfps->config_type != 0) { | ||||
| Show All 32 Lines | if (mpct->signature[0] != 'P' || mpct->signature[1] != 'C' || | ||||
| __func__, mpct->signature[0], mpct->signature[1], | __func__, mpct->signature[0], mpct->signature[1], | ||||
| mpct->signature[2], mpct->signature[3]); | mpct->signature[2], mpct->signature[3]); | ||||
| return (ENXIO); | return (ENXIO); | ||||
| } | } | ||||
| if (bootverbose) | if (bootverbose) | ||||
| printf( | printf( | ||||
| "MP Configuration Table version 1.%d found at %p\n", | "MP Configuration Table version 1.%d found at %p\n", | ||||
| mpct->spec_rev, mpct); | mpct->spec_rev, mpct); | ||||
| #ifdef MPTABLE_LINUX_BUG_COMPAT | |||||
| /* | |||||
| * Linux ignores entry_count and instead scans the MP table | |||||
| * until it runs out of bytes of table (as specified by the | |||||
| * base_table_length field). Some VM systems rely on this | |||||
| * buggy behaviour and record an entry_count of zero. | |||||
| */ | |||||
| if (mpct->entry_count == 0) | |||||
| compute_entry_count(); | |||||
| #endif | |||||
| } | } | ||||
| return (-100); | return (-100); | ||||
| } | } | ||||
| /* | /* | ||||
| * Run through the MP table enumerating CPUs. | * Run through the MP table enumerating CPUs. | ||||
| */ | */ | ||||
| ▲ Show 20 Lines • Show All 930 Lines • Show Last 20 Lines | |||||