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 |