diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2010-12-29 14:36:26 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2010-12-29 14:36:26 -0500 |
commit | d50e8fc7e38d88909448a723cb1f825bb3af30e2 (patch) | |
tree | 099e969b273c3d180c89aa64b1e359ef66a9fc5d /arch/x86/kernel | |
parent | a387e95a49743cf9835c5299ca549232618d8249 (diff) | |
parent | 0aa002fe602939370e9476e5ec32b562000a0425 (diff) |
Merge branch 'x86/apic-cleanups' into x86/numa
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 48 | ||||
-rw-r--r-- | arch/x86/kernel/apb_timer.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 151 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 62 | ||||
-rw-r--r-- | arch/x86/kernel/early_printk.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/early_printk_mrst.c | 319 | ||||
-rw-r--r-- | arch/x86/kernel/head32.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/mpparse.c | 114 | ||||
-rw-r--r-- | arch/x86/kernel/reboot_fixups_32.c | 16 | ||||
-rw-r--r-- | arch/x86/kernel/setup.c | 5 |
11 files changed, 164 insertions, 559 deletions
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 9e13763b6092..f60153d5de57 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -84,7 +84,6 @@ obj-$(CONFIG_DOUBLEFAULT) += doublefault_32.o | |||
84 | obj-$(CONFIG_KGDB) += kgdb.o | 84 | obj-$(CONFIG_KGDB) += kgdb.o |
85 | obj-$(CONFIG_VM86) += vm86_32.o | 85 | obj-$(CONFIG_VM86) += vm86_32.o |
86 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 86 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
87 | obj-$(CONFIG_EARLY_PRINTK_MRST) += early_printk_mrst.o | ||
88 | 87 | ||
89 | obj-$(CONFIG_HPET_TIMER) += hpet.o | 88 | obj-$(CONFIG_HPET_TIMER) += hpet.o |
90 | obj-$(CONFIG_APB_TIMER) += apb_timer.o | 89 | obj-$(CONFIG_APB_TIMER) += apb_timer.o |
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 71232b941b6c..1a5b9a8e6c4f 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -847,18 +847,6 @@ static int __init acpi_parse_fadt(struct acpi_table_header *table) | |||
847 | * returns 0 on success, < 0 on error | 847 | * returns 0 on success, < 0 on error |
848 | */ | 848 | */ |
849 | 849 | ||
850 | static void __init acpi_register_lapic_address(unsigned long address) | ||
851 | { | ||
852 | mp_lapic_addr = address; | ||
853 | |||
854 | set_fixmap_nocache(FIX_APIC_BASE, address); | ||
855 | if (boot_cpu_physical_apicid == -1U) { | ||
856 | boot_cpu_physical_apicid = read_apic_id(); | ||
857 | apic_version[boot_cpu_physical_apicid] = | ||
858 | GET_APIC_VERSION(apic_read(APIC_LVR)); | ||
859 | } | ||
860 | } | ||
861 | |||
862 | static int __init early_acpi_parse_madt_lapic_addr_ovr(void) | 850 | static int __init early_acpi_parse_madt_lapic_addr_ovr(void) |
863 | { | 851 | { |
864 | int count; | 852 | int count; |
@@ -880,7 +868,7 @@ static int __init early_acpi_parse_madt_lapic_addr_ovr(void) | |||
880 | return count; | 868 | return count; |
881 | } | 869 | } |
882 | 870 | ||
883 | acpi_register_lapic_address(acpi_lapic_addr); | 871 | register_lapic_address(acpi_lapic_addr); |
884 | 872 | ||
885 | return count; | 873 | return count; |
886 | } | 874 | } |
@@ -907,7 +895,7 @@ static int __init acpi_parse_madt_lapic_entries(void) | |||
907 | return count; | 895 | return count; |
908 | } | 896 | } |
909 | 897 | ||
910 | acpi_register_lapic_address(acpi_lapic_addr); | 898 | register_lapic_address(acpi_lapic_addr); |
911 | 899 | ||
912 | count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC, | 900 | count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC, |
913 | acpi_parse_sapic, MAX_APICS); | 901 | acpi_parse_sapic, MAX_APICS); |
@@ -949,32 +937,6 @@ static int __init acpi_parse_madt_lapic_entries(void) | |||
949 | extern int es7000_plat; | 937 | extern int es7000_plat; |
950 | #endif | 938 | #endif |
951 | 939 | ||
952 | static void assign_to_mp_irq(struct mpc_intsrc *m, | ||
953 | struct mpc_intsrc *mp_irq) | ||
954 | { | ||
955 | memcpy(mp_irq, m, sizeof(struct mpc_intsrc)); | ||
956 | } | ||
957 | |||
958 | static int mp_irq_cmp(struct mpc_intsrc *mp_irq, | ||
959 | struct mpc_intsrc *m) | ||
960 | { | ||
961 | return memcmp(mp_irq, m, sizeof(struct mpc_intsrc)); | ||
962 | } | ||
963 | |||
964 | static void save_mp_irq(struct mpc_intsrc *m) | ||
965 | { | ||
966 | int i; | ||
967 | |||
968 | for (i = 0; i < mp_irq_entries; i++) { | ||
969 | if (!mp_irq_cmp(&mp_irqs[i], m)) | ||
970 | return; | ||
971 | } | ||
972 | |||
973 | assign_to_mp_irq(m, &mp_irqs[mp_irq_entries]); | ||
974 | if (++mp_irq_entries == MAX_IRQ_SOURCES) | ||
975 | panic("Max # of irq sources exceeded!!\n"); | ||
976 | } | ||
977 | |||
978 | void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) | 940 | void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) |
979 | { | 941 | { |
980 | int ioapic; | 942 | int ioapic; |
@@ -1005,7 +967,7 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) | |||
1005 | mp_irq.dstapic = mp_ioapics[ioapic].apicid; /* APIC ID */ | 967 | mp_irq.dstapic = mp_ioapics[ioapic].apicid; /* APIC ID */ |
1006 | mp_irq.dstirq = pin; /* INTIN# */ | 968 | mp_irq.dstirq = pin; /* INTIN# */ |
1007 | 969 | ||
1008 | save_mp_irq(&mp_irq); | 970 | mp_save_irq(&mp_irq); |
1009 | 971 | ||
1010 | isa_irq_to_gsi[bus_irq] = gsi; | 972 | isa_irq_to_gsi[bus_irq] = gsi; |
1011 | } | 973 | } |
@@ -1080,7 +1042,7 @@ void __init mp_config_acpi_legacy_irqs(void) | |||
1080 | mp_irq.srcbusirq = i; /* Identity mapped */ | 1042 | mp_irq.srcbusirq = i; /* Identity mapped */ |
1081 | mp_irq.dstirq = pin; | 1043 | mp_irq.dstirq = pin; |
1082 | 1044 | ||
1083 | save_mp_irq(&mp_irq); | 1045 | mp_save_irq(&mp_irq); |
1084 | } | 1046 | } |
1085 | } | 1047 | } |
1086 | 1048 | ||
@@ -1117,7 +1079,7 @@ static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger, | |||
1117 | mp_irq.dstapic = mp_ioapics[ioapic].apicid; | 1079 | mp_irq.dstapic = mp_ioapics[ioapic].apicid; |
1118 | mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi); | 1080 | mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi); |
1119 | 1081 | ||
1120 | save_mp_irq(&mp_irq); | 1082 | mp_save_irq(&mp_irq); |
1121 | #endif | 1083 | #endif |
1122 | return 0; | 1084 | return 0; |
1123 | } | 1085 | } |
diff --git a/arch/x86/kernel/apb_timer.c b/arch/x86/kernel/apb_timer.c index 92543c73cf8e..7c9ab59653e8 100644 --- a/arch/x86/kernel/apb_timer.c +++ b/arch/x86/kernel/apb_timer.c | |||
@@ -315,6 +315,7 @@ static void apbt_setup_irq(struct apbt_dev *adev) | |||
315 | 315 | ||
316 | if (system_state == SYSTEM_BOOTING) { | 316 | if (system_state == SYSTEM_BOOTING) { |
317 | irq_modify_status(adev->irq, 0, IRQ_MOVE_PCNTXT); | 317 | irq_modify_status(adev->irq, 0, IRQ_MOVE_PCNTXT); |
318 | irq_set_affinity(adev->irq, cpumask_of(adev->cpu)); | ||
318 | /* APB timer irqs are set up as mp_irqs, timer is edge type */ | 319 | /* APB timer irqs are set up as mp_irqs, timer is edge type */ |
319 | __set_irq_handler(adev->irq, handle_edge_irq, 0, "edge"); | 320 | __set_irq_handler(adev->irq, handle_edge_irq, 0, "edge"); |
320 | if (request_irq(adev->irq, apbt_interrupt_handler, | 321 | if (request_irq(adev->irq, apbt_interrupt_handler, |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 3f838d537392..c0f6426cd337 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -1195,12 +1195,15 @@ static void __cpuinit lapic_setup_esr(void) | |||
1195 | oldvalue, value); | 1195 | oldvalue, value); |
1196 | } | 1196 | } |
1197 | 1197 | ||
1198 | |||
1199 | /** | 1198 | /** |
1200 | * setup_local_APIC - setup the local APIC | 1199 | * setup_local_APIC - setup the local APIC |
1200 | * | ||
1201 | * Used to setup local APIC while initializing BSP or bringin up APs. | ||
1202 | * Always called with preemption disabled. | ||
1201 | */ | 1203 | */ |
1202 | void __cpuinit setup_local_APIC(void) | 1204 | void __cpuinit setup_local_APIC(void) |
1203 | { | 1205 | { |
1206 | int cpu = smp_processor_id(); | ||
1204 | unsigned int value, queued; | 1207 | unsigned int value, queued; |
1205 | int i, j, acked = 0; | 1208 | int i, j, acked = 0; |
1206 | unsigned long long tsc = 0, ntsc; | 1209 | unsigned long long tsc = 0, ntsc; |
@@ -1225,8 +1228,6 @@ void __cpuinit setup_local_APIC(void) | |||
1225 | #endif | 1228 | #endif |
1226 | perf_events_lapic_init(); | 1229 | perf_events_lapic_init(); |
1227 | 1230 | ||
1228 | preempt_disable(); | ||
1229 | |||
1230 | /* | 1231 | /* |
1231 | * Double-check whether this APIC is really registered. | 1232 | * Double-check whether this APIC is really registered. |
1232 | * This is meaningless in clustered apic mode, so we skip it. | 1233 | * This is meaningless in clustered apic mode, so we skip it. |
@@ -1342,21 +1343,19 @@ void __cpuinit setup_local_APIC(void) | |||
1342 | * TODO: set up through-local-APIC from through-I/O-APIC? --macro | 1343 | * TODO: set up through-local-APIC from through-I/O-APIC? --macro |
1343 | */ | 1344 | */ |
1344 | value = apic_read(APIC_LVT0) & APIC_LVT_MASKED; | 1345 | value = apic_read(APIC_LVT0) & APIC_LVT_MASKED; |
1345 | if (!smp_processor_id() && (pic_mode || !value)) { | 1346 | if (!cpu && (pic_mode || !value)) { |
1346 | value = APIC_DM_EXTINT; | 1347 | value = APIC_DM_EXTINT; |
1347 | apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", | 1348 | apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", cpu); |
1348 | smp_processor_id()); | ||
1349 | } else { | 1349 | } else { |
1350 | value = APIC_DM_EXTINT | APIC_LVT_MASKED; | 1350 | value = APIC_DM_EXTINT | APIC_LVT_MASKED; |
1351 | apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", | 1351 | apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", cpu); |
1352 | smp_processor_id()); | ||
1353 | } | 1352 | } |
1354 | apic_write(APIC_LVT0, value); | 1353 | apic_write(APIC_LVT0, value); |
1355 | 1354 | ||
1356 | /* | 1355 | /* |
1357 | * only the BP should see the LINT1 NMI signal, obviously. | 1356 | * only the BP should see the LINT1 NMI signal, obviously. |
1358 | */ | 1357 | */ |
1359 | if (!smp_processor_id()) | 1358 | if (!cpu) |
1360 | value = APIC_DM_NMI; | 1359 | value = APIC_DM_NMI; |
1361 | else | 1360 | else |
1362 | value = APIC_DM_NMI | APIC_LVT_MASKED; | 1361 | value = APIC_DM_NMI | APIC_LVT_MASKED; |
@@ -1364,11 +1363,9 @@ void __cpuinit setup_local_APIC(void) | |||
1364 | value |= APIC_LVT_LEVEL_TRIGGER; | 1363 | value |= APIC_LVT_LEVEL_TRIGGER; |
1365 | apic_write(APIC_LVT1, value); | 1364 | apic_write(APIC_LVT1, value); |
1366 | 1365 | ||
1367 | preempt_enable(); | ||
1368 | |||
1369 | #ifdef CONFIG_X86_MCE_INTEL | 1366 | #ifdef CONFIG_X86_MCE_INTEL |
1370 | /* Recheck CMCI information after local APIC is up on CPU #0 */ | 1367 | /* Recheck CMCI information after local APIC is up on CPU #0 */ |
1371 | if (smp_processor_id() == 0) | 1368 | if (!cpu) |
1372 | cmci_recheck(); | 1369 | cmci_recheck(); |
1373 | #endif | 1370 | #endif |
1374 | } | 1371 | } |
@@ -1530,13 +1527,60 @@ static int __init detect_init_APIC(void) | |||
1530 | return 0; | 1527 | return 0; |
1531 | } | 1528 | } |
1532 | #else | 1529 | #else |
1530 | |||
1531 | static int apic_verify(void) | ||
1532 | { | ||
1533 | u32 features, h, l; | ||
1534 | |||
1535 | /* | ||
1536 | * The APIC feature bit should now be enabled | ||
1537 | * in `cpuid' | ||
1538 | */ | ||
1539 | features = cpuid_edx(1); | ||
1540 | if (!(features & (1 << X86_FEATURE_APIC))) { | ||
1541 | pr_warning("Could not enable APIC!\n"); | ||
1542 | return -1; | ||
1543 | } | ||
1544 | set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC); | ||
1545 | mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; | ||
1546 | |||
1547 | /* The BIOS may have set up the APIC at some other address */ | ||
1548 | rdmsr(MSR_IA32_APICBASE, l, h); | ||
1549 | if (l & MSR_IA32_APICBASE_ENABLE) | ||
1550 | mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; | ||
1551 | |||
1552 | pr_info("Found and enabled local APIC!\n"); | ||
1553 | return 0; | ||
1554 | } | ||
1555 | |||
1556 | int apic_force_enable(void) | ||
1557 | { | ||
1558 | u32 h, l; | ||
1559 | |||
1560 | if (disable_apic) | ||
1561 | return -1; | ||
1562 | |||
1563 | /* | ||
1564 | * Some BIOSes disable the local APIC in the APIC_BASE | ||
1565 | * MSR. This can only be done in software for Intel P6 or later | ||
1566 | * and AMD K7 (Model > 1) or later. | ||
1567 | */ | ||
1568 | rdmsr(MSR_IA32_APICBASE, l, h); | ||
1569 | if (!(l & MSR_IA32_APICBASE_ENABLE)) { | ||
1570 | pr_info("Local APIC disabled by BIOS -- reenabling.\n"); | ||
1571 | l &= ~MSR_IA32_APICBASE_BASE; | ||
1572 | l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE; | ||
1573 | wrmsr(MSR_IA32_APICBASE, l, h); | ||
1574 | enabled_via_apicbase = 1; | ||
1575 | } | ||
1576 | return apic_verify(); | ||
1577 | } | ||
1578 | |||
1533 | /* | 1579 | /* |
1534 | * Detect and initialize APIC | 1580 | * Detect and initialize APIC |
1535 | */ | 1581 | */ |
1536 | static int __init detect_init_APIC(void) | 1582 | static int __init detect_init_APIC(void) |
1537 | { | 1583 | { |
1538 | u32 h, l, features; | ||
1539 | |||
1540 | /* Disabled by kernel option? */ | 1584 | /* Disabled by kernel option? */ |
1541 | if (disable_apic) | 1585 | if (disable_apic) |
1542 | return -1; | 1586 | return -1; |
@@ -1566,38 +1610,12 @@ static int __init detect_init_APIC(void) | |||
1566 | "you can enable it with \"lapic\"\n"); | 1610 | "you can enable it with \"lapic\"\n"); |
1567 | return -1; | 1611 | return -1; |
1568 | } | 1612 | } |
1569 | /* | 1613 | if (apic_force_enable()) |
1570 | * Some BIOSes disable the local APIC in the APIC_BASE | 1614 | return -1; |
1571 | * MSR. This can only be done in software for Intel P6 or later | 1615 | } else { |
1572 | * and AMD K7 (Model > 1) or later. | 1616 | if (apic_verify()) |
1573 | */ | 1617 | return -1; |
1574 | rdmsr(MSR_IA32_APICBASE, l, h); | ||
1575 | if (!(l & MSR_IA32_APICBASE_ENABLE)) { | ||
1576 | pr_info("Local APIC disabled by BIOS -- reenabling.\n"); | ||
1577 | l &= ~MSR_IA32_APICBASE_BASE; | ||
1578 | l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE; | ||
1579 | wrmsr(MSR_IA32_APICBASE, l, h); | ||
1580 | enabled_via_apicbase = 1; | ||
1581 | } | ||
1582 | } | ||
1583 | /* | ||
1584 | * The APIC feature bit should now be enabled | ||
1585 | * in `cpuid' | ||
1586 | */ | ||
1587 | features = cpuid_edx(1); | ||
1588 | if (!(features & (1 << X86_FEATURE_APIC))) { | ||
1589 | pr_warning("Could not enable APIC!\n"); | ||
1590 | return -1; | ||
1591 | } | 1618 | } |
1592 | set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC); | ||
1593 | mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; | ||
1594 | |||
1595 | /* The BIOS may have set up the APIC at some other address */ | ||
1596 | rdmsr(MSR_IA32_APICBASE, l, h); | ||
1597 | if (l & MSR_IA32_APICBASE_ENABLE) | ||
1598 | mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; | ||
1599 | |||
1600 | pr_info("Found and enabled local APIC!\n"); | ||
1601 | 1619 | ||
1602 | apic_pm_activate(); | 1620 | apic_pm_activate(); |
1603 | 1621 | ||
@@ -1609,28 +1627,6 @@ no_apic: | |||
1609 | } | 1627 | } |
1610 | #endif | 1628 | #endif |
1611 | 1629 | ||
1612 | #ifdef CONFIG_X86_64 | ||
1613 | void __init early_init_lapic_mapping(void) | ||
1614 | { | ||
1615 | /* | ||
1616 | * If no local APIC can be found then go out | ||
1617 | * : it means there is no mpatable and MADT | ||
1618 | */ | ||
1619 | if (!smp_found_config) | ||
1620 | return; | ||
1621 | |||
1622 | set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr); | ||
1623 | apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n", | ||
1624 | APIC_BASE, mp_lapic_addr); | ||
1625 | |||
1626 | /* | ||
1627 | * Fetch the APIC ID of the BSP in case we have a | ||
1628 | * default configuration (or the MP table is broken). | ||
1629 | */ | ||
1630 | boot_cpu_physical_apicid = read_apic_id(); | ||
1631 | } | ||
1632 | #endif | ||
1633 | |||
1634 | /** | 1630 | /** |
1635 | * init_apic_mappings - initialize APIC mappings | 1631 | * init_apic_mappings - initialize APIC mappings |
1636 | */ | 1632 | */ |
@@ -1656,10 +1652,7 @@ void __init init_apic_mappings(void) | |||
1656 | * acpi_register_lapic_address() | 1652 | * acpi_register_lapic_address() |
1657 | */ | 1653 | */ |
1658 | if (!acpi_lapic && !smp_found_config) | 1654 | if (!acpi_lapic && !smp_found_config) |
1659 | set_fixmap_nocache(FIX_APIC_BASE, apic_phys); | 1655 | register_lapic_address(apic_phys); |
1660 | |||
1661 | apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n", | ||
1662 | APIC_BASE, apic_phys); | ||
1663 | } | 1656 | } |
1664 | 1657 | ||
1665 | /* | 1658 | /* |
@@ -1681,6 +1674,22 @@ void __init init_apic_mappings(void) | |||
1681 | } | 1674 | } |
1682 | } | 1675 | } |
1683 | 1676 | ||
1677 | void __init register_lapic_address(unsigned long address) | ||
1678 | { | ||
1679 | mp_lapic_addr = address; | ||
1680 | |||
1681 | if (!x2apic_mode) { | ||
1682 | set_fixmap_nocache(FIX_APIC_BASE, address); | ||
1683 | apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n", | ||
1684 | APIC_BASE, mp_lapic_addr); | ||
1685 | } | ||
1686 | if (boot_cpu_physical_apicid == -1U) { | ||
1687 | boot_cpu_physical_apicid = read_apic_id(); | ||
1688 | apic_version[boot_cpu_physical_apicid] = | ||
1689 | GET_APIC_VERSION(apic_read(APIC_LVR)); | ||
1690 | } | ||
1691 | } | ||
1692 | |||
1684 | /* | 1693 | /* |
1685 | * This initializes the IO-APIC and APIC hardware if this is | 1694 | * This initializes the IO-APIC and APIC hardware if this is |
1686 | * a UP kernel. | 1695 | * a UP kernel. |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 7cc0a721f628..bb61a552d8c6 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -126,6 +126,26 @@ static int __init parse_noapic(char *str) | |||
126 | } | 126 | } |
127 | early_param("noapic", parse_noapic); | 127 | early_param("noapic", parse_noapic); |
128 | 128 | ||
129 | /* Will be called in mpparse/acpi/sfi codes for saving IRQ info */ | ||
130 | void mp_save_irq(struct mpc_intsrc *m) | ||
131 | { | ||
132 | int i; | ||
133 | |||
134 | apic_printk(APIC_VERBOSE, "Int: type %d, pol %d, trig %d, bus %02x," | ||
135 | " IRQ %02x, APIC ID %x, APIC INT %02x\n", | ||
136 | m->irqtype, m->irqflag & 3, (m->irqflag >> 2) & 3, m->srcbus, | ||
137 | m->srcbusirq, m->dstapic, m->dstirq); | ||
138 | |||
139 | for (i = 0; i < mp_irq_entries; i++) { | ||
140 | if (!memcmp(&mp_irqs[i], m, sizeof(*m))) | ||
141 | return; | ||
142 | } | ||
143 | |||
144 | memcpy(&mp_irqs[mp_irq_entries], m, sizeof(*m)); | ||
145 | if (++mp_irq_entries == MAX_IRQ_SOURCES) | ||
146 | panic("Max # of irq sources exceeded!!\n"); | ||
147 | } | ||
148 | |||
129 | struct irq_pin_list { | 149 | struct irq_pin_list { |
130 | int apic, pin; | 150 | int apic, pin; |
131 | struct irq_pin_list *next; | 151 | struct irq_pin_list *next; |
@@ -136,6 +156,7 @@ static struct irq_pin_list *alloc_irq_pin_list(int node) | |||
136 | return kzalloc_node(sizeof(struct irq_pin_list), GFP_KERNEL, node); | 156 | return kzalloc_node(sizeof(struct irq_pin_list), GFP_KERNEL, node); |
137 | } | 157 | } |
138 | 158 | ||
159 | |||
139 | /* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */ | 160 | /* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */ |
140 | #ifdef CONFIG_SPARSE_IRQ | 161 | #ifdef CONFIG_SPARSE_IRQ |
141 | static struct irq_cfg irq_cfgx[NR_IRQS_LEGACY]; | 162 | static struct irq_cfg irq_cfgx[NR_IRQS_LEGACY]; |
@@ -1934,8 +1955,7 @@ void disable_IO_APIC(void) | |||
1934 | * | 1955 | * |
1935 | * by Matt Domsch <Matt_Domsch@dell.com> Tue Dec 21 12:25:05 CST 1999 | 1956 | * by Matt Domsch <Matt_Domsch@dell.com> Tue Dec 21 12:25:05 CST 1999 |
1936 | */ | 1957 | */ |
1937 | 1958 | void __init setup_ioapic_ids_from_mpc_nocheck(void) | |
1938 | void __init setup_ioapic_ids_from_mpc(void) | ||
1939 | { | 1959 | { |
1940 | union IO_APIC_reg_00 reg_00; | 1960 | union IO_APIC_reg_00 reg_00; |
1941 | physid_mask_t phys_id_present_map; | 1961 | physid_mask_t phys_id_present_map; |
@@ -1944,15 +1964,6 @@ void __init setup_ioapic_ids_from_mpc(void) | |||
1944 | unsigned char old_id; | 1964 | unsigned char old_id; |
1945 | unsigned long flags; | 1965 | unsigned long flags; |
1946 | 1966 | ||
1947 | if (acpi_ioapic) | ||
1948 | return; | ||
1949 | /* | ||
1950 | * Don't check I/O APIC IDs for xAPIC systems. They have | ||
1951 | * no meaning without the serial APIC bus. | ||
1952 | */ | ||
1953 | if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) | ||
1954 | || APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) | ||
1955 | return; | ||
1956 | /* | 1967 | /* |
1957 | * This is broken; anything with a real cpu count has to | 1968 | * This is broken; anything with a real cpu count has to |
1958 | * circumvent this idiocy regardless. | 1969 | * circumvent this idiocy regardless. |
@@ -2006,7 +2017,6 @@ void __init setup_ioapic_ids_from_mpc(void) | |||
2006 | physids_or(phys_id_present_map, phys_id_present_map, tmp); | 2017 | physids_or(phys_id_present_map, phys_id_present_map, tmp); |
2007 | } | 2018 | } |
2008 | 2019 | ||
2009 | |||
2010 | /* | 2020 | /* |
2011 | * We need to adjust the IRQ routing table | 2021 | * We need to adjust the IRQ routing table |
2012 | * if the ID changed. | 2022 | * if the ID changed. |
@@ -2018,9 +2028,12 @@ void __init setup_ioapic_ids_from_mpc(void) | |||
2018 | = mp_ioapics[apic_id].apicid; | 2028 | = mp_ioapics[apic_id].apicid; |
2019 | 2029 | ||
2020 | /* | 2030 | /* |
2021 | * Read the right value from the MPC table and | 2031 | * Update the ID register according to the right value |
2022 | * write it into the ID register. | 2032 | * from the MPC table if they are different. |
2023 | */ | 2033 | */ |
2034 | if (mp_ioapics[apic_id].apicid == reg_00.bits.ID) | ||
2035 | continue; | ||
2036 | |||
2024 | apic_printk(APIC_VERBOSE, KERN_INFO | 2037 | apic_printk(APIC_VERBOSE, KERN_INFO |
2025 | "...changing IO-APIC physical APIC ID to %d ...", | 2038 | "...changing IO-APIC physical APIC ID to %d ...", |
2026 | mp_ioapics[apic_id].apicid); | 2039 | mp_ioapics[apic_id].apicid); |
@@ -2042,6 +2055,21 @@ void __init setup_ioapic_ids_from_mpc(void) | |||
2042 | apic_printk(APIC_VERBOSE, " ok.\n"); | 2055 | apic_printk(APIC_VERBOSE, " ok.\n"); |
2043 | } | 2056 | } |
2044 | } | 2057 | } |
2058 | |||
2059 | void __init setup_ioapic_ids_from_mpc(void) | ||
2060 | { | ||
2061 | |||
2062 | if (acpi_ioapic) | ||
2063 | return; | ||
2064 | /* | ||
2065 | * Don't check I/O APIC IDs for xAPIC systems. They have | ||
2066 | * no meaning without the serial APIC bus. | ||
2067 | */ | ||
2068 | if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) | ||
2069 | || APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) | ||
2070 | return; | ||
2071 | setup_ioapic_ids_from_mpc_nocheck(); | ||
2072 | } | ||
2045 | #endif | 2073 | #endif |
2046 | 2074 | ||
2047 | int no_timer_check __initdata; | 2075 | int no_timer_check __initdata; |
@@ -3639,7 +3667,7 @@ int __init io_apic_get_redir_entries (int ioapic) | |||
3639 | return reg_01.bits.entries + 1; | 3667 | return reg_01.bits.entries + 1; |
3640 | } | 3668 | } |
3641 | 3669 | ||
3642 | void __init probe_nr_irqs_gsi(void) | 3670 | static void __init probe_nr_irqs_gsi(void) |
3643 | { | 3671 | { |
3644 | int nr; | 3672 | int nr; |
3645 | 3673 | ||
@@ -3956,7 +3984,7 @@ static struct resource * __init ioapic_setup_resources(int nr_ioapics) | |||
3956 | return res; | 3984 | return res; |
3957 | } | 3985 | } |
3958 | 3986 | ||
3959 | void __init ioapic_init_mappings(void) | 3987 | void __init ioapic_and_gsi_init(void) |
3960 | { | 3988 | { |
3961 | unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; | 3989 | unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; |
3962 | struct resource *ioapic_res; | 3990 | struct resource *ioapic_res; |
@@ -3994,6 +4022,8 @@ fake_ioapic_page: | |||
3994 | ioapic_res->end = ioapic_phys + IO_APIC_SLOT_SIZE - 1; | 4022 | ioapic_res->end = ioapic_phys + IO_APIC_SLOT_SIZE - 1; |
3995 | ioapic_res++; | 4023 | ioapic_res++; |
3996 | } | 4024 | } |
4025 | |||
4026 | probe_nr_irqs_gsi(); | ||
3997 | } | 4027 | } |
3998 | 4028 | ||
3999 | void __init ioapic_insert_resources(void) | 4029 | void __init ioapic_insert_resources(void) |
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index 4572f25f9325..cd28a350f7f9 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c | |||
@@ -240,7 +240,7 @@ static int __init setup_early_printk(char *buf) | |||
240 | if (!strncmp(buf, "xen", 3)) | 240 | if (!strncmp(buf, "xen", 3)) |
241 | early_console_register(&xenboot_console, keep); | 241 | early_console_register(&xenboot_console, keep); |
242 | #endif | 242 | #endif |
243 | #ifdef CONFIG_X86_MRST_EARLY_PRINTK | 243 | #ifdef CONFIG_EARLY_PRINTK_MRST |
244 | if (!strncmp(buf, "mrst", 4)) { | 244 | if (!strncmp(buf, "mrst", 4)) { |
245 | mrst_early_console_init(); | 245 | mrst_early_console_init(); |
246 | early_console_register(&early_mrst_console, keep); | 246 | early_console_register(&early_mrst_console, keep); |
@@ -250,7 +250,6 @@ static int __init setup_early_printk(char *buf) | |||
250 | hsu_early_console_init(); | 250 | hsu_early_console_init(); |
251 | early_console_register(&early_hsu_console, keep); | 251 | early_console_register(&early_hsu_console, keep); |
252 | } | 252 | } |
253 | |||
254 | #endif | 253 | #endif |
255 | buf++; | 254 | buf++; |
256 | } | 255 | } |
diff --git a/arch/x86/kernel/early_printk_mrst.c b/arch/x86/kernel/early_printk_mrst.c deleted file mode 100644 index 65df603622b2..000000000000 --- a/arch/x86/kernel/early_printk_mrst.c +++ /dev/null | |||
@@ -1,319 +0,0 @@ | |||
1 | /* | ||
2 | * early_printk_mrst.c - early consoles for Intel MID platforms | ||
3 | * | ||
4 | * Copyright (c) 2008-2010, Intel Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; version 2 | ||
9 | * of the License. | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * This file implements two early consoles named mrst and hsu. | ||
14 | * mrst is based on Maxim3110 spi-uart device, it exists in both | ||
15 | * Moorestown and Medfield platforms, while hsu is based on a High | ||
16 | * Speed UART device which only exists in the Medfield platform | ||
17 | */ | ||
18 | |||
19 | #include <linux/serial_reg.h> | ||
20 | #include <linux/serial_mfd.h> | ||
21 | #include <linux/kmsg_dump.h> | ||
22 | #include <linux/console.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/io.h> | ||
27 | |||
28 | #include <asm/fixmap.h> | ||
29 | #include <asm/pgtable.h> | ||
30 | #include <asm/mrst.h> | ||
31 | |||
32 | #define MRST_SPI_TIMEOUT 0x200000 | ||
33 | #define MRST_REGBASE_SPI0 0xff128000 | ||
34 | #define MRST_REGBASE_SPI1 0xff128400 | ||
35 | #define MRST_CLK_SPI0_REG 0xff11d86c | ||
36 | |||
37 | /* Bit fields in CTRLR0 */ | ||
38 | #define SPI_DFS_OFFSET 0 | ||
39 | |||
40 | #define SPI_FRF_OFFSET 4 | ||
41 | #define SPI_FRF_SPI 0x0 | ||
42 | #define SPI_FRF_SSP 0x1 | ||
43 | #define SPI_FRF_MICROWIRE 0x2 | ||
44 | #define SPI_FRF_RESV 0x3 | ||
45 | |||
46 | #define SPI_MODE_OFFSET 6 | ||
47 | #define SPI_SCPH_OFFSET 6 | ||
48 | #define SPI_SCOL_OFFSET 7 | ||
49 | #define SPI_TMOD_OFFSET 8 | ||
50 | #define SPI_TMOD_TR 0x0 /* xmit & recv */ | ||
51 | #define SPI_TMOD_TO 0x1 /* xmit only */ | ||
52 | #define SPI_TMOD_RO 0x2 /* recv only */ | ||
53 | #define SPI_TMOD_EPROMREAD 0x3 /* eeprom read mode */ | ||
54 | |||
55 | #define SPI_SLVOE_OFFSET 10 | ||
56 | #define SPI_SRL_OFFSET 11 | ||
57 | #define SPI_CFS_OFFSET 12 | ||
58 | |||
59 | /* Bit fields in SR, 7 bits */ | ||
60 | #define SR_MASK 0x7f /* cover 7 bits */ | ||
61 | #define SR_BUSY (1 << 0) | ||
62 | #define SR_TF_NOT_FULL (1 << 1) | ||
63 | #define SR_TF_EMPT (1 << 2) | ||
64 | #define SR_RF_NOT_EMPT (1 << 3) | ||
65 | #define SR_RF_FULL (1 << 4) | ||
66 | #define SR_TX_ERR (1 << 5) | ||
67 | #define SR_DCOL (1 << 6) | ||
68 | |||
69 | struct dw_spi_reg { | ||
70 | u32 ctrl0; | ||
71 | u32 ctrl1; | ||
72 | u32 ssienr; | ||
73 | u32 mwcr; | ||
74 | u32 ser; | ||
75 | u32 baudr; | ||
76 | u32 txfltr; | ||
77 | u32 rxfltr; | ||
78 | u32 txflr; | ||
79 | u32 rxflr; | ||
80 | u32 sr; | ||
81 | u32 imr; | ||
82 | u32 isr; | ||
83 | u32 risr; | ||
84 | u32 txoicr; | ||
85 | u32 rxoicr; | ||
86 | u32 rxuicr; | ||
87 | u32 msticr; | ||
88 | u32 icr; | ||
89 | u32 dmacr; | ||
90 | u32 dmatdlr; | ||
91 | u32 dmardlr; | ||
92 | u32 idr; | ||
93 | u32 version; | ||
94 | |||
95 | /* Currently operates as 32 bits, though only the low 16 bits matter */ | ||
96 | u32 dr; | ||
97 | } __packed; | ||
98 | |||
99 | #define dw_readl(dw, name) __raw_readl(&(dw)->name) | ||
100 | #define dw_writel(dw, name, val) __raw_writel((val), &(dw)->name) | ||
101 | |||
102 | /* Default use SPI0 register for mrst, we will detect Penwell and use SPI1 */ | ||
103 | static unsigned long mrst_spi_paddr = MRST_REGBASE_SPI0; | ||
104 | |||
105 | static u32 *pclk_spi0; | ||
106 | /* Always contains an accessable address, start with 0 */ | ||
107 | static struct dw_spi_reg *pspi; | ||
108 | |||
109 | static struct kmsg_dumper dw_dumper; | ||
110 | static int dumper_registered; | ||
111 | |||
112 | static void dw_kmsg_dump(struct kmsg_dumper *dumper, | ||
113 | enum kmsg_dump_reason reason, | ||
114 | const char *s1, unsigned long l1, | ||
115 | const char *s2, unsigned long l2) | ||
116 | { | ||
117 | int i; | ||
118 | |||
119 | /* When run to this, we'd better re-init the HW */ | ||
120 | mrst_early_console_init(); | ||
121 | |||
122 | for (i = 0; i < l1; i++) | ||
123 | early_mrst_console.write(&early_mrst_console, s1 + i, 1); | ||
124 | for (i = 0; i < l2; i++) | ||
125 | early_mrst_console.write(&early_mrst_console, s2 + i, 1); | ||
126 | } | ||
127 | |||
128 | /* Set the ratio rate to 115200, 8n1, IRQ disabled */ | ||
129 | static void max3110_write_config(void) | ||
130 | { | ||
131 | u16 config; | ||
132 | |||
133 | config = 0xc001; | ||
134 | dw_writel(pspi, dr, config); | ||
135 | } | ||
136 | |||
137 | /* Translate char to a eligible word and send to max3110 */ | ||
138 | static void max3110_write_data(char c) | ||
139 | { | ||
140 | u16 data; | ||
141 | |||
142 | data = 0x8000 | c; | ||
143 | dw_writel(pspi, dr, data); | ||
144 | } | ||
145 | |||
146 | void mrst_early_console_init(void) | ||
147 | { | ||
148 | u32 ctrlr0 = 0; | ||
149 | u32 spi0_cdiv; | ||
150 | u32 freq; /* Freqency info only need be searched once */ | ||
151 | |||
152 | /* Base clk is 100 MHz, the actual clk = 100M / (clk_divider + 1) */ | ||
153 | pclk_spi0 = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, | ||
154 | MRST_CLK_SPI0_REG); | ||
155 | spi0_cdiv = ((*pclk_spi0) & 0xe00) >> 9; | ||
156 | freq = 100000000 / (spi0_cdiv + 1); | ||
157 | |||
158 | if (mrst_identify_cpu() == MRST_CPU_CHIP_PENWELL) | ||
159 | mrst_spi_paddr = MRST_REGBASE_SPI1; | ||
160 | |||
161 | pspi = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, | ||
162 | mrst_spi_paddr); | ||
163 | |||
164 | /* Disable SPI controller */ | ||
165 | dw_writel(pspi, ssienr, 0); | ||
166 | |||
167 | /* Set control param, 8 bits, transmit only mode */ | ||
168 | ctrlr0 = dw_readl(pspi, ctrl0); | ||
169 | |||
170 | ctrlr0 &= 0xfcc0; | ||
171 | ctrlr0 |= 0xf | (SPI_FRF_SPI << SPI_FRF_OFFSET) | ||
172 | | (SPI_TMOD_TO << SPI_TMOD_OFFSET); | ||
173 | dw_writel(pspi, ctrl0, ctrlr0); | ||
174 | |||
175 | /* | ||
176 | * Change the spi0 clk to comply with 115200 bps, use 100000 to | ||
177 | * calculate the clk dividor to make the clock a little slower | ||
178 | * than real baud rate. | ||
179 | */ | ||
180 | dw_writel(pspi, baudr, freq/100000); | ||
181 | |||
182 | /* Disable all INT for early phase */ | ||
183 | dw_writel(pspi, imr, 0x0); | ||
184 | |||
185 | /* Set the cs to spi-uart */ | ||
186 | dw_writel(pspi, ser, 0x2); | ||
187 | |||
188 | /* Enable the HW, the last step for HW init */ | ||
189 | dw_writel(pspi, ssienr, 0x1); | ||
190 | |||
191 | /* Set the default configuration */ | ||
192 | max3110_write_config(); | ||
193 | |||
194 | /* Register the kmsg dumper */ | ||
195 | if (!dumper_registered) { | ||
196 | dw_dumper.dump = dw_kmsg_dump; | ||
197 | kmsg_dump_register(&dw_dumper); | ||
198 | dumper_registered = 1; | ||
199 | } | ||
200 | } | ||
201 | |||
202 | /* Slave select should be called in the read/write function */ | ||
203 | static void early_mrst_spi_putc(char c) | ||
204 | { | ||
205 | unsigned int timeout; | ||
206 | u32 sr; | ||
207 | |||
208 | timeout = MRST_SPI_TIMEOUT; | ||
209 | /* Early putc needs to make sure the TX FIFO is not full */ | ||
210 | while (--timeout) { | ||
211 | sr = dw_readl(pspi, sr); | ||
212 | if (!(sr & SR_TF_NOT_FULL)) | ||
213 | cpu_relax(); | ||
214 | else | ||
215 | break; | ||
216 | } | ||
217 | |||
218 | if (!timeout) | ||
219 | pr_warning("MRST earlycon: timed out\n"); | ||
220 | else | ||
221 | max3110_write_data(c); | ||
222 | } | ||
223 | |||
224 | /* Early SPI only uses polling mode */ | ||
225 | static void early_mrst_spi_write(struct console *con, const char *str, unsigned n) | ||
226 | { | ||
227 | int i; | ||
228 | |||
229 | for (i = 0; i < n && *str; i++) { | ||
230 | if (*str == '\n') | ||
231 | early_mrst_spi_putc('\r'); | ||
232 | early_mrst_spi_putc(*str); | ||
233 | str++; | ||
234 | } | ||
235 | } | ||
236 | |||
237 | struct console early_mrst_console = { | ||
238 | .name = "earlymrst", | ||
239 | .write = early_mrst_spi_write, | ||
240 | .flags = CON_PRINTBUFFER, | ||
241 | .index = -1, | ||
242 | }; | ||
243 | |||
244 | /* | ||
245 | * Following is the early console based on Medfield HSU (High | ||
246 | * Speed UART) device. | ||
247 | */ | ||
248 | #define HSU_PORT2_PADDR 0xffa28180 | ||
249 | |||
250 | static void __iomem *phsu; | ||
251 | |||
252 | void hsu_early_console_init(void) | ||
253 | { | ||
254 | u8 lcr; | ||
255 | |||
256 | phsu = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, | ||
257 | HSU_PORT2_PADDR); | ||
258 | |||
259 | /* Disable FIFO */ | ||
260 | writeb(0x0, phsu + UART_FCR); | ||
261 | |||
262 | /* Set to default 115200 bps, 8n1 */ | ||
263 | lcr = readb(phsu + UART_LCR); | ||
264 | writeb((0x80 | lcr), phsu + UART_LCR); | ||
265 | writeb(0x18, phsu + UART_DLL); | ||
266 | writeb(lcr, phsu + UART_LCR); | ||
267 | writel(0x3600, phsu + UART_MUL*4); | ||
268 | |||
269 | writeb(0x8, phsu + UART_MCR); | ||
270 | writeb(0x7, phsu + UART_FCR); | ||
271 | writeb(0x3, phsu + UART_LCR); | ||
272 | |||
273 | /* Clear IRQ status */ | ||
274 | readb(phsu + UART_LSR); | ||
275 | readb(phsu + UART_RX); | ||
276 | readb(phsu + UART_IIR); | ||
277 | readb(phsu + UART_MSR); | ||
278 | |||
279 | /* Enable FIFO */ | ||
280 | writeb(0x7, phsu + UART_FCR); | ||
281 | } | ||
282 | |||
283 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | ||
284 | |||
285 | static void early_hsu_putc(char ch) | ||
286 | { | ||
287 | unsigned int timeout = 10000; /* 10ms */ | ||
288 | u8 status; | ||
289 | |||
290 | while (--timeout) { | ||
291 | status = readb(phsu + UART_LSR); | ||
292 | if (status & BOTH_EMPTY) | ||
293 | break; | ||
294 | udelay(1); | ||
295 | } | ||
296 | |||
297 | /* Only write the char when there was no timeout */ | ||
298 | if (timeout) | ||
299 | writeb(ch, phsu + UART_TX); | ||
300 | } | ||
301 | |||
302 | static void early_hsu_write(struct console *con, const char *str, unsigned n) | ||
303 | { | ||
304 | int i; | ||
305 | |||
306 | for (i = 0; i < n && *str; i++) { | ||
307 | if (*str == '\n') | ||
308 | early_hsu_putc('\r'); | ||
309 | early_hsu_putc(*str); | ||
310 | str++; | ||
311 | } | ||
312 | } | ||
313 | |||
314 | struct console early_hsu_console = { | ||
315 | .name = "earlyhsu", | ||
316 | .write = early_hsu_write, | ||
317 | .flags = CON_PRINTBUFFER, | ||
318 | .index = -1, | ||
319 | }; | ||
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index 763310165fa0..7f138b3c3c52 100644 --- a/arch/x86/kernel/head32.c +++ b/arch/x86/kernel/head32.c | |||
@@ -61,6 +61,9 @@ void __init i386_start_kernel(void) | |||
61 | case X86_SUBARCH_MRST: | 61 | case X86_SUBARCH_MRST: |
62 | x86_mrst_early_setup(); | 62 | x86_mrst_early_setup(); |
63 | break; | 63 | break; |
64 | case X86_SUBARCH_CE4100: | ||
65 | x86_ce4100_early_setup(); | ||
66 | break; | ||
64 | default: | 67 | default: |
65 | i386_default_early_setup(); | 68 | i386_default_early_setup(); |
66 | break; | 69 | break; |
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 9af64d9c4b67..01b0f6d06451 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c | |||
@@ -118,21 +118,8 @@ static void __init MP_bus_info(struct mpc_bus *m) | |||
118 | 118 | ||
119 | static void __init MP_ioapic_info(struct mpc_ioapic *m) | 119 | static void __init MP_ioapic_info(struct mpc_ioapic *m) |
120 | { | 120 | { |
121 | if (!(m->flags & MPC_APIC_USABLE)) | 121 | if (m->flags & MPC_APIC_USABLE) |
122 | return; | 122 | mp_register_ioapic(m->apicid, m->apicaddr, gsi_top); |
123 | |||
124 | printk(KERN_INFO "I/O APIC #%d Version %d at 0x%X.\n", | ||
125 | m->apicid, m->apicver, m->apicaddr); | ||
126 | |||
127 | mp_register_ioapic(m->apicid, m->apicaddr, gsi_top); | ||
128 | } | ||
129 | |||
130 | static void print_MP_intsrc_info(struct mpc_intsrc *m) | ||
131 | { | ||
132 | apic_printk(APIC_VERBOSE, "Int: type %d, pol %d, trig %d, bus %02x," | ||
133 | " IRQ %02x, APIC ID %x, APIC INT %02x\n", | ||
134 | m->irqtype, m->irqflag & 3, (m->irqflag >> 2) & 3, m->srcbus, | ||
135 | m->srcbusirq, m->dstapic, m->dstirq); | ||
136 | } | 123 | } |
137 | 124 | ||
138 | static void __init print_mp_irq_info(struct mpc_intsrc *mp_irq) | 125 | static void __init print_mp_irq_info(struct mpc_intsrc *mp_irq) |
@@ -144,73 +131,11 @@ static void __init print_mp_irq_info(struct mpc_intsrc *mp_irq) | |||
144 | mp_irq->srcbusirq, mp_irq->dstapic, mp_irq->dstirq); | 131 | mp_irq->srcbusirq, mp_irq->dstapic, mp_irq->dstirq); |
145 | } | 132 | } |
146 | 133 | ||
147 | static void __init assign_to_mp_irq(struct mpc_intsrc *m, | ||
148 | struct mpc_intsrc *mp_irq) | ||
149 | { | ||
150 | mp_irq->dstapic = m->dstapic; | ||
151 | mp_irq->type = m->type; | ||
152 | mp_irq->irqtype = m->irqtype; | ||
153 | mp_irq->irqflag = m->irqflag; | ||
154 | mp_irq->srcbus = m->srcbus; | ||
155 | mp_irq->srcbusirq = m->srcbusirq; | ||
156 | mp_irq->dstirq = m->dstirq; | ||
157 | } | ||
158 | |||
159 | static void __init assign_to_mpc_intsrc(struct mpc_intsrc *mp_irq, | ||
160 | struct mpc_intsrc *m) | ||
161 | { | ||
162 | m->dstapic = mp_irq->dstapic; | ||
163 | m->type = mp_irq->type; | ||
164 | m->irqtype = mp_irq->irqtype; | ||
165 | m->irqflag = mp_irq->irqflag; | ||
166 | m->srcbus = mp_irq->srcbus; | ||
167 | m->srcbusirq = mp_irq->srcbusirq; | ||
168 | m->dstirq = mp_irq->dstirq; | ||
169 | } | ||
170 | |||
171 | static int __init mp_irq_mpc_intsrc_cmp(struct mpc_intsrc *mp_irq, | ||
172 | struct mpc_intsrc *m) | ||
173 | { | ||
174 | if (mp_irq->dstapic != m->dstapic) | ||
175 | return 1; | ||
176 | if (mp_irq->type != m->type) | ||
177 | return 2; | ||
178 | if (mp_irq->irqtype != m->irqtype) | ||
179 | return 3; | ||
180 | if (mp_irq->irqflag != m->irqflag) | ||
181 | return 4; | ||
182 | if (mp_irq->srcbus != m->srcbus) | ||
183 | return 5; | ||
184 | if (mp_irq->srcbusirq != m->srcbusirq) | ||
185 | return 6; | ||
186 | if (mp_irq->dstirq != m->dstirq) | ||
187 | return 7; | ||
188 | |||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static void __init MP_intsrc_info(struct mpc_intsrc *m) | ||
193 | { | ||
194 | int i; | ||
195 | |||
196 | print_MP_intsrc_info(m); | ||
197 | |||
198 | for (i = 0; i < mp_irq_entries; i++) { | ||
199 | if (!mp_irq_mpc_intsrc_cmp(&mp_irqs[i], m)) | ||
200 | return; | ||
201 | } | ||
202 | |||
203 | assign_to_mp_irq(m, &mp_irqs[mp_irq_entries]); | ||
204 | if (++mp_irq_entries == MAX_IRQ_SOURCES) | ||
205 | panic("Max # of irq sources exceeded!!\n"); | ||
206 | } | ||
207 | #else /* CONFIG_X86_IO_APIC */ | 134 | #else /* CONFIG_X86_IO_APIC */ |
208 | static inline void __init MP_bus_info(struct mpc_bus *m) {} | 135 | static inline void __init MP_bus_info(struct mpc_bus *m) {} |
209 | static inline void __init MP_ioapic_info(struct mpc_ioapic *m) {} | 136 | static inline void __init MP_ioapic_info(struct mpc_ioapic *m) {} |
210 | static inline void __init MP_intsrc_info(struct mpc_intsrc *m) {} | ||
211 | #endif /* CONFIG_X86_IO_APIC */ | 137 | #endif /* CONFIG_X86_IO_APIC */ |
212 | 138 | ||
213 | |||
214 | static void __init MP_lintsrc_info(struct mpc_lintsrc *m) | 139 | static void __init MP_lintsrc_info(struct mpc_lintsrc *m) |
215 | { | 140 | { |
216 | apic_printk(APIC_VERBOSE, "Lint: type %d, pol %d, trig %d, bus %02x," | 141 | apic_printk(APIC_VERBOSE, "Lint: type %d, pol %d, trig %d, bus %02x," |
@@ -222,7 +147,6 @@ static void __init MP_lintsrc_info(struct mpc_lintsrc *m) | |||
222 | /* | 147 | /* |
223 | * Read/parse the MPC | 148 | * Read/parse the MPC |
224 | */ | 149 | */ |
225 | |||
226 | static int __init smp_check_mpc(struct mpc_table *mpc, char *oem, char *str) | 150 | static int __init smp_check_mpc(struct mpc_table *mpc, char *oem, char *str) |
227 | { | 151 | { |
228 | 152 | ||
@@ -275,18 +199,6 @@ static void __init smp_dump_mptable(struct mpc_table *mpc, unsigned char *mpt) | |||
275 | 199 | ||
276 | void __init default_smp_read_mpc_oem(struct mpc_table *mpc) { } | 200 | void __init default_smp_read_mpc_oem(struct mpc_table *mpc) { } |
277 | 201 | ||
278 | static void __init smp_register_lapic_address(unsigned long address) | ||
279 | { | ||
280 | mp_lapic_addr = address; | ||
281 | |||
282 | set_fixmap_nocache(FIX_APIC_BASE, address); | ||
283 | if (boot_cpu_physical_apicid == -1U) { | ||
284 | boot_cpu_physical_apicid = read_apic_id(); | ||
285 | apic_version[boot_cpu_physical_apicid] = | ||
286 | GET_APIC_VERSION(apic_read(APIC_LVR)); | ||
287 | } | ||
288 | } | ||
289 | |||
290 | static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) | 202 | static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) |
291 | { | 203 | { |
292 | char str[16]; | 204 | char str[16]; |
@@ -301,17 +213,13 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) | |||
301 | #ifdef CONFIG_X86_32 | 213 | #ifdef CONFIG_X86_32 |
302 | generic_mps_oem_check(mpc, oem, str); | 214 | generic_mps_oem_check(mpc, oem, str); |
303 | #endif | 215 | #endif |
304 | /* save the local APIC address, it might be non-default */ | 216 | /* Initialize the lapic mapping */ |
305 | if (!acpi_lapic) | 217 | if (!acpi_lapic) |
306 | mp_lapic_addr = mpc->lapic; | 218 | register_lapic_address(mpc->lapic); |
307 | 219 | ||
308 | if (early) | 220 | if (early) |
309 | return 1; | 221 | return 1; |
310 | 222 | ||
311 | /* Initialize the lapic mapping */ | ||
312 | if (!acpi_lapic) | ||
313 | smp_register_lapic_address(mpc->lapic); | ||
314 | |||
315 | if (mpc->oemptr) | 223 | if (mpc->oemptr) |
316 | x86_init.mpparse.smp_read_mpc_oem(mpc); | 224 | x86_init.mpparse.smp_read_mpc_oem(mpc); |
317 | 225 | ||
@@ -337,7 +245,7 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) | |||
337 | skip_entry(&mpt, &count, sizeof(struct mpc_ioapic)); | 245 | skip_entry(&mpt, &count, sizeof(struct mpc_ioapic)); |
338 | break; | 246 | break; |
339 | case MP_INTSRC: | 247 | case MP_INTSRC: |
340 | MP_intsrc_info((struct mpc_intsrc *)mpt); | 248 | mp_save_irq((struct mpc_intsrc *)mpt); |
341 | skip_entry(&mpt, &count, sizeof(struct mpc_intsrc)); | 249 | skip_entry(&mpt, &count, sizeof(struct mpc_intsrc)); |
342 | break; | 250 | break; |
343 | case MP_LINTSRC: | 251 | case MP_LINTSRC: |
@@ -429,13 +337,13 @@ static void __init construct_default_ioirq_mptable(int mpc_default_type) | |||
429 | 337 | ||
430 | intsrc.srcbusirq = i; | 338 | intsrc.srcbusirq = i; |
431 | intsrc.dstirq = i ? i : 2; /* IRQ0 to INTIN2 */ | 339 | intsrc.dstirq = i ? i : 2; /* IRQ0 to INTIN2 */ |
432 | MP_intsrc_info(&intsrc); | 340 | mp_save_irq(&intsrc); |
433 | } | 341 | } |
434 | 342 | ||
435 | intsrc.irqtype = mp_ExtINT; | 343 | intsrc.irqtype = mp_ExtINT; |
436 | intsrc.srcbusirq = 0; | 344 | intsrc.srcbusirq = 0; |
437 | intsrc.dstirq = 0; /* 8259A to INTIN0 */ | 345 | intsrc.dstirq = 0; /* 8259A to INTIN0 */ |
438 | MP_intsrc_info(&intsrc); | 346 | mp_save_irq(&intsrc); |
439 | } | 347 | } |
440 | 348 | ||
441 | 349 | ||
@@ -784,11 +692,11 @@ static void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) | |||
784 | int i; | 692 | int i; |
785 | 693 | ||
786 | apic_printk(APIC_VERBOSE, "OLD "); | 694 | apic_printk(APIC_VERBOSE, "OLD "); |
787 | print_MP_intsrc_info(m); | 695 | print_mp_irq_info(m); |
788 | 696 | ||
789 | i = get_MP_intsrc_index(m); | 697 | i = get_MP_intsrc_index(m); |
790 | if (i > 0) { | 698 | if (i > 0) { |
791 | assign_to_mpc_intsrc(&mp_irqs[i], m); | 699 | memcpy(m, &mp_irqs[i], sizeof(*m)); |
792 | apic_printk(APIC_VERBOSE, "NEW "); | 700 | apic_printk(APIC_VERBOSE, "NEW "); |
793 | print_mp_irq_info(&mp_irqs[i]); | 701 | print_mp_irq_info(&mp_irqs[i]); |
794 | return; | 702 | return; |
@@ -875,14 +783,14 @@ static int __init replace_intsrc_all(struct mpc_table *mpc, | |||
875 | if (nr_m_spare > 0) { | 783 | if (nr_m_spare > 0) { |
876 | apic_printk(APIC_VERBOSE, "*NEW* found\n"); | 784 | apic_printk(APIC_VERBOSE, "*NEW* found\n"); |
877 | nr_m_spare--; | 785 | nr_m_spare--; |
878 | assign_to_mpc_intsrc(&mp_irqs[i], m_spare[nr_m_spare]); | 786 | memcpy(m_spare[nr_m_spare], &mp_irqs[i], sizeof(mp_irqs[i])); |
879 | m_spare[nr_m_spare] = NULL; | 787 | m_spare[nr_m_spare] = NULL; |
880 | } else { | 788 | } else { |
881 | struct mpc_intsrc *m = (struct mpc_intsrc *)mpt; | 789 | struct mpc_intsrc *m = (struct mpc_intsrc *)mpt; |
882 | count += sizeof(struct mpc_intsrc); | 790 | count += sizeof(struct mpc_intsrc); |
883 | if (check_slot(mpc_new_phys, mpc_new_length, count) < 0) | 791 | if (check_slot(mpc_new_phys, mpc_new_length, count) < 0) |
884 | goto out; | 792 | goto out; |
885 | assign_to_mpc_intsrc(&mp_irqs[i], m); | 793 | memcpy(m, &mp_irqs[i], sizeof(*m)); |
886 | mpc->length = count; | 794 | mpc->length = count; |
887 | mpt += sizeof(struct mpc_intsrc); | 795 | mpt += sizeof(struct mpc_intsrc); |
888 | } | 796 | } |
diff --git a/arch/x86/kernel/reboot_fixups_32.c b/arch/x86/kernel/reboot_fixups_32.c index fda313ebbb03..c8e41e90f59c 100644 --- a/arch/x86/kernel/reboot_fixups_32.c +++ b/arch/x86/kernel/reboot_fixups_32.c | |||
@@ -43,17 +43,33 @@ static void rdc321x_reset(struct pci_dev *dev) | |||
43 | outb(1, 0x92); | 43 | outb(1, 0x92); |
44 | } | 44 | } |
45 | 45 | ||
46 | static void ce4100_reset(struct pci_dev *dev) | ||
47 | { | ||
48 | int i; | ||
49 | |||
50 | for (i = 0; i < 10; i++) { | ||
51 | outb(0x2, 0xcf9); | ||
52 | udelay(50); | ||
53 | } | ||
54 | } | ||
55 | |||
46 | struct device_fixup { | 56 | struct device_fixup { |
47 | unsigned int vendor; | 57 | unsigned int vendor; |
48 | unsigned int device; | 58 | unsigned int device; |
49 | void (*reboot_fixup)(struct pci_dev *); | 59 | void (*reboot_fixup)(struct pci_dev *); |
50 | }; | 60 | }; |
51 | 61 | ||
62 | /* | ||
63 | * PCI ids solely used for fixups_table go here | ||
64 | */ | ||
65 | #define PCI_DEVICE_ID_INTEL_CE4100 0x0708 | ||
66 | |||
52 | static const struct device_fixup fixups_table[] = { | 67 | static const struct device_fixup fixups_table[] = { |
53 | { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, cs5530a_warm_reset }, | 68 | { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, cs5530a_warm_reset }, |
54 | { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, cs5536_warm_reset }, | 69 | { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, cs5536_warm_reset }, |
55 | { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE, cs5530a_warm_reset }, | 70 | { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE, cs5530a_warm_reset }, |
56 | { PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6030, rdc321x_reset }, | 71 | { PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6030, rdc321x_reset }, |
72 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CE4100, ce4100_reset }, | ||
57 | }; | 73 | }; |
58 | 74 | ||
59 | /* | 75 | /* |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index df172c1e8238..0afb8c7e3803 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -1035,10 +1035,7 @@ void __init setup_arch(char **cmdline_p) | |||
1035 | #endif | 1035 | #endif |
1036 | 1036 | ||
1037 | init_apic_mappings(); | 1037 | init_apic_mappings(); |
1038 | ioapic_init_mappings(); | 1038 | ioapic_and_gsi_init(); |
1039 | |||
1040 | /* need to wait for io_apic is mapped */ | ||
1041 | probe_nr_irqs_gsi(); | ||
1042 | 1039 | ||
1043 | kvm_guest_init(); | 1040 | kvm_guest_init(); |
1044 | 1041 | ||