diff options
Diffstat (limited to 'arch/x86/kernel/acpi')
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 105 | ||||
-rw-r--r-- | arch/x86/kernel/acpi/cstate.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/acpi/processor.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/acpi/realmode/wakeup.lds.S | 3 | ||||
-rw-r--r-- | arch/x86/kernel/acpi/sleep.c | 24 |
5 files changed, 20 insertions, 117 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index eae642b0f345..87eee07da21f 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -834,106 +834,6 @@ static int __init acpi_parse_madt_lapic_entries(void) | |||
834 | extern int es7000_plat; | 834 | extern int es7000_plat; |
835 | #endif | 835 | #endif |
836 | 836 | ||
837 | static struct { | ||
838 | int gsi_base; | ||
839 | int gsi_end; | ||
840 | } mp_ioapic_routing[MAX_IO_APICS]; | ||
841 | |||
842 | int mp_find_ioapic(int gsi) | ||
843 | { | ||
844 | int i = 0; | ||
845 | |||
846 | /* Find the IOAPIC that manages this GSI. */ | ||
847 | for (i = 0; i < nr_ioapics; i++) { | ||
848 | if ((gsi >= mp_ioapic_routing[i].gsi_base) | ||
849 | && (gsi <= mp_ioapic_routing[i].gsi_end)) | ||
850 | return i; | ||
851 | } | ||
852 | |||
853 | printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi); | ||
854 | return -1; | ||
855 | } | ||
856 | |||
857 | int mp_find_ioapic_pin(int ioapic, int gsi) | ||
858 | { | ||
859 | if (WARN_ON(ioapic == -1)) | ||
860 | return -1; | ||
861 | if (WARN_ON(gsi > mp_ioapic_routing[ioapic].gsi_end)) | ||
862 | return -1; | ||
863 | |||
864 | return gsi - mp_ioapic_routing[ioapic].gsi_base; | ||
865 | } | ||
866 | |||
867 | static u8 __init uniq_ioapic_id(u8 id) | ||
868 | { | ||
869 | #ifdef CONFIG_X86_32 | ||
870 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && | ||
871 | !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) | ||
872 | return io_apic_get_unique_id(nr_ioapics, id); | ||
873 | else | ||
874 | return id; | ||
875 | #else | ||
876 | int i; | ||
877 | DECLARE_BITMAP(used, 256); | ||
878 | bitmap_zero(used, 256); | ||
879 | for (i = 0; i < nr_ioapics; i++) { | ||
880 | struct mpc_ioapic *ia = &mp_ioapics[i]; | ||
881 | __set_bit(ia->apicid, used); | ||
882 | } | ||
883 | if (!test_bit(id, used)) | ||
884 | return id; | ||
885 | return find_first_zero_bit(used, 256); | ||
886 | #endif | ||
887 | } | ||
888 | |||
889 | static int bad_ioapic(unsigned long address) | ||
890 | { | ||
891 | if (nr_ioapics >= MAX_IO_APICS) { | ||
892 | printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " | ||
893 | "(found %d)\n", MAX_IO_APICS, nr_ioapics); | ||
894 | panic("Recompile kernel with bigger MAX_IO_APICS!\n"); | ||
895 | } | ||
896 | if (!address) { | ||
897 | printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address" | ||
898 | " found in table, skipping!\n"); | ||
899 | return 1; | ||
900 | } | ||
901 | return 0; | ||
902 | } | ||
903 | |||
904 | void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) | ||
905 | { | ||
906 | int idx = 0; | ||
907 | |||
908 | if (bad_ioapic(address)) | ||
909 | return; | ||
910 | |||
911 | idx = nr_ioapics; | ||
912 | |||
913 | mp_ioapics[idx].type = MP_IOAPIC; | ||
914 | mp_ioapics[idx].flags = MPC_APIC_USABLE; | ||
915 | mp_ioapics[idx].apicaddr = address; | ||
916 | |||
917 | set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); | ||
918 | mp_ioapics[idx].apicid = uniq_ioapic_id(id); | ||
919 | mp_ioapics[idx].apicver = io_apic_get_version(idx); | ||
920 | |||
921 | /* | ||
922 | * Build basic GSI lookup table to facilitate gsi->io_apic lookups | ||
923 | * and to prevent reprogramming of IOAPIC pins (PCI GSIs). | ||
924 | */ | ||
925 | mp_ioapic_routing[idx].gsi_base = gsi_base; | ||
926 | mp_ioapic_routing[idx].gsi_end = gsi_base + | ||
927 | io_apic_get_redir_entries(idx); | ||
928 | |||
929 | printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " | ||
930 | "GSI %d-%d\n", idx, mp_ioapics[idx].apicid, | ||
931 | mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr, | ||
932 | mp_ioapic_routing[idx].gsi_base, mp_ioapic_routing[idx].gsi_end); | ||
933 | |||
934 | nr_ioapics++; | ||
935 | } | ||
936 | |||
937 | int __init acpi_probe_gsi(void) | 837 | int __init acpi_probe_gsi(void) |
938 | { | 838 | { |
939 | int idx; | 839 | int idx; |
@@ -948,7 +848,7 @@ int __init acpi_probe_gsi(void) | |||
948 | 848 | ||
949 | max_gsi = 0; | 849 | max_gsi = 0; |
950 | for (idx = 0; idx < nr_ioapics; idx++) { | 850 | for (idx = 0; idx < nr_ioapics; idx++) { |
951 | gsi = mp_ioapic_routing[idx].gsi_end; | 851 | gsi = mp_gsi_routing[idx].gsi_end; |
952 | 852 | ||
953 | if (gsi > max_gsi) | 853 | if (gsi > max_gsi) |
954 | max_gsi = gsi; | 854 | max_gsi = gsi; |
@@ -1180,9 +1080,8 @@ static int __init acpi_parse_madt_ioapic_entries(void) | |||
1180 | * If MPS is present, it will handle them, | 1080 | * If MPS is present, it will handle them, |
1181 | * otherwise the system will stay in PIC mode | 1081 | * otherwise the system will stay in PIC mode |
1182 | */ | 1082 | */ |
1183 | if (acpi_disabled || acpi_noirq) { | 1083 | if (acpi_disabled || acpi_noirq) |
1184 | return -ENODEV; | 1084 | return -ENODEV; |
1185 | } | ||
1186 | 1085 | ||
1187 | if (!cpu_has_apic) | 1086 | if (!cpu_has_apic) |
1188 | return -ENODEV; | 1087 | return -ENODEV; |
diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c index 8c44c232efcb..59cdfa4686b2 100644 --- a/arch/x86/kernel/acpi/cstate.c +++ b/arch/x86/kernel/acpi/cstate.c | |||
@@ -48,7 +48,7 @@ void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags, | |||
48 | * P4, Core and beyond CPUs | 48 | * P4, Core and beyond CPUs |
49 | */ | 49 | */ |
50 | if (c->x86_vendor == X86_VENDOR_INTEL && | 50 | if (c->x86_vendor == X86_VENDOR_INTEL && |
51 | (c->x86 > 0x6 || (c->x86 == 6 && c->x86_model >= 14))) | 51 | (c->x86 > 0xf || (c->x86 == 6 && c->x86_model >= 14))) |
52 | flags->bm_control = 0; | 52 | flags->bm_control = 0; |
53 | } | 53 | } |
54 | EXPORT_SYMBOL(acpi_processor_power_init_bm_check); | 54 | EXPORT_SYMBOL(acpi_processor_power_init_bm_check); |
diff --git a/arch/x86/kernel/acpi/processor.c b/arch/x86/kernel/acpi/processor.c index d296f4a195c9..d85d1b2432ba 100644 --- a/arch/x86/kernel/acpi/processor.c +++ b/arch/x86/kernel/acpi/processor.c | |||
@@ -79,7 +79,8 @@ void arch_acpi_processor_init_pdc(struct acpi_processor *pr) | |||
79 | struct cpuinfo_x86 *c = &cpu_data(pr->id); | 79 | struct cpuinfo_x86 *c = &cpu_data(pr->id); |
80 | 80 | ||
81 | pr->pdc = NULL; | 81 | pr->pdc = NULL; |
82 | if (c->x86_vendor == X86_VENDOR_INTEL) | 82 | if (c->x86_vendor == X86_VENDOR_INTEL || |
83 | c->x86_vendor == X86_VENDOR_CENTAUR) | ||
83 | init_intel_pdc(pr, c); | 84 | init_intel_pdc(pr, c); |
84 | 85 | ||
85 | return; | 86 | return; |
diff --git a/arch/x86/kernel/acpi/realmode/wakeup.lds.S b/arch/x86/kernel/acpi/realmode/wakeup.lds.S index 7da00b799cda..060fff8f5c5b 100644 --- a/arch/x86/kernel/acpi/realmode/wakeup.lds.S +++ b/arch/x86/kernel/acpi/realmode/wakeup.lds.S | |||
@@ -57,5 +57,8 @@ SECTIONS | |||
57 | *(.note*) | 57 | *(.note*) |
58 | } | 58 | } |
59 | 59 | ||
60 | /* | ||
61 | * The ASSERT() sink to . is intentional, for binutils 2.14 compatibility: | ||
62 | */ | ||
60 | . = ASSERT(_end <= WAKEUP_SIZE, "Wakeup too big!"); | 63 | . = ASSERT(_end <= WAKEUP_SIZE, "Wakeup too big!"); |
61 | } | 64 | } |
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index ca93638ba430..82e508677b91 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c | |||
@@ -78,12 +78,9 @@ int acpi_save_state_mem(void) | |||
78 | #ifndef CONFIG_64BIT | 78 | #ifndef CONFIG_64BIT |
79 | store_gdt((struct desc_ptr *)&header->pmode_gdt); | 79 | store_gdt((struct desc_ptr *)&header->pmode_gdt); |
80 | 80 | ||
81 | header->pmode_efer_low = nx_enabled; | 81 | if (rdmsr_safe(MSR_EFER, &header->pmode_efer_low, |
82 | if (header->pmode_efer_low & 1) { | 82 | &header->pmode_efer_high)) |
83 | /* This is strange, why not save efer, always? */ | 83 | header->pmode_efer_low = header->pmode_efer_high = 0; |
84 | rdmsr(MSR_EFER, header->pmode_efer_low, | ||
85 | header->pmode_efer_high); | ||
86 | } | ||
87 | #endif /* !CONFIG_64BIT */ | 84 | #endif /* !CONFIG_64BIT */ |
88 | 85 | ||
89 | header->pmode_cr0 = read_cr0(); | 86 | header->pmode_cr0 = read_cr0(); |
@@ -119,29 +116,32 @@ void acpi_restore_state_mem(void) | |||
119 | 116 | ||
120 | 117 | ||
121 | /** | 118 | /** |
122 | * acpi_reserve_bootmem - do _very_ early ACPI initialisation | 119 | * acpi_reserve_wakeup_memory - do _very_ early ACPI initialisation |
123 | * | 120 | * |
124 | * We allocate a page from the first 1MB of memory for the wakeup | 121 | * We allocate a page from the first 1MB of memory for the wakeup |
125 | * routine for when we come back from a sleep state. The | 122 | * routine for when we come back from a sleep state. The |
126 | * runtime allocator allows specification of <16MB pages, but not | 123 | * runtime allocator allows specification of <16MB pages, but not |
127 | * <1MB pages. | 124 | * <1MB pages. |
128 | */ | 125 | */ |
129 | void __init acpi_reserve_bootmem(void) | 126 | void __init acpi_reserve_wakeup_memory(void) |
130 | { | 127 | { |
128 | unsigned long mem; | ||
129 | |||
131 | if ((&wakeup_code_end - &wakeup_code_start) > WAKEUP_SIZE) { | 130 | if ((&wakeup_code_end - &wakeup_code_start) > WAKEUP_SIZE) { |
132 | printk(KERN_ERR | 131 | printk(KERN_ERR |
133 | "ACPI: Wakeup code way too big, S3 disabled.\n"); | 132 | "ACPI: Wakeup code way too big, S3 disabled.\n"); |
134 | return; | 133 | return; |
135 | } | 134 | } |
136 | 135 | ||
137 | acpi_realmode = (unsigned long)alloc_bootmem_low(WAKEUP_SIZE); | 136 | mem = find_e820_area(0, 1<<20, WAKEUP_SIZE, PAGE_SIZE); |
138 | 137 | ||
139 | if (!acpi_realmode) { | 138 | if (mem == -1L) { |
140 | printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n"); | 139 | printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n"); |
141 | return; | 140 | return; |
142 | } | 141 | } |
143 | 142 | acpi_realmode = (unsigned long) phys_to_virt(mem); | |
144 | acpi_wakeup_address = virt_to_phys((void *)acpi_realmode); | 143 | acpi_wakeup_address = mem; |
144 | reserve_early(mem, mem + WAKEUP_SIZE, "ACPI WAKEUP"); | ||
145 | } | 145 | } |
146 | 146 | ||
147 | 147 | ||