FreeBSD/sys/x86/acpica/madt.c
/*
 * Initialize the local APIC on the BSP.
 */
Initialize the local APIC on the BSP.
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];
	madt = pmap_mapbios(madt_physaddr, madt_length);
	if ((cpu_feature2 & CPUID2_X2APIC) != 0) {
		x2apic_mode = 1;
		reason = NULL;
		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) {
				x2apic_mode = 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) {
				x2apic_mode = 0;
		reason = "inside VMWare without intr redirection";
			}
		} else if (vm_guest == VM_GUEST_XEN) {
			x2apic_mode = 0;
			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");
			if (hw_vendor != NULL) {
				if (!strcmp(hw_vendor, "LENOVO") ||
				    !strcmp(hw_vendor,
				    "ASUSTeK Computer Inc.")) {
					x2apic_mode = 0;
					reason =
				    "for a suspected SandyBridge BIOS bug";
				}
				freeenv(hw_vendor);
			}
		}
		TUNABLE_INT_FETCH("hw.x2apic_enable", &x2apic_mode);
		if (!x2apic_mode && reason != NULL && bootverbose)
			printf("x2APIC available but disabled %s\n", reason);
	}
	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);
	return (0);
}
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 ] ; madt = pmap_mapbios ( madt_physaddr , madt_length ) ; if ( ( cpu_feature2 & CPUID2_X2APIC ) != 0 ) { x2apic_mode = 1 ; reason = NULL ; 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 ) { x2apic_mode = 0 ; reason = " " ; } 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 ) { x2apic_mode = 0 ; reason = " " ; } } else if ( vm_guest == VM_GUEST_XEN ) { x2apic_mode = 0 ; reason = " " ; } else if ( vm_guest == VM_GUEST_NO && CPUID_TO_FAMILY ( cpu_id ) == 0x6 && CPUID_TO_MODEL ( cpu_id ) == 0x2a ) { hw_vendor = kern_getenv ( " " ) ; if ( hw_vendor != NULL ) { if ( ! strcmp ( hw_vendor , " " ) || ! strcmp ( hw_vendor , " " ) ) { x2apic_mode = 0 ; reason = " " ; } freeenv ( hw_vendor ) ; } } TUNABLE_INT_FETCH ( " " , & x2apic_mode ) ; if ( ! x2apic_mode && reason != NULL && bootverbose ) printf ( " \n " , reason ) ; } lapic_init ( madt -> Address ) ; printf ( " \n " , ( int ) sizeof ( madt -> Header . OemId ) , madt -> Header . OemId , ( int ) sizeof ( madt -> Header . OemTableId ) , madt -> Header . OemTableId ) ; return ( 0 ) ; }
Initialize the local APIC on the BSP.
Initialize the local APIC on the BSP .
/*
		 * Automatically detect several configurations where
		 * x2APIC mode is known to cause troubles.  User can
		 * override the setting with hw.x2apic_enable tunable.
		 */ /*
			 * 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.
			 */ /*
	 * We ignore 64-bit local APIC override entries.  Should we
	 * perhaps emit a warning here if we find one?
	 */