aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/acpi')
-rw-r--r--arch/x86/kernel/acpi/boot.c105
-rw-r--r--arch/x86/kernel/acpi/cstate.c2
-rw-r--r--arch/x86/kernel/acpi/processor.c3
-rw-r--r--arch/x86/kernel/acpi/realmode/wakeup.lds.S3
-rw-r--r--arch/x86/kernel/acpi/sleep.c24
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)
834extern int es7000_plat; 834extern int es7000_plat;
835#endif 835#endif
836 836
837static struct {
838 int gsi_base;
839 int gsi_end;
840} mp_ioapic_routing[MAX_IO_APICS];
841
842int 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
857int 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
867static 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
889static 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
904void __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
937int __init acpi_probe_gsi(void) 837int __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}
54EXPORT_SYMBOL(acpi_processor_power_init_bm_check); 54EXPORT_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 */
129void __init acpi_reserve_bootmem(void) 126void __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