diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /include/asm-i386/mach-default |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'include/asm-i386/mach-default')
21 files changed, 958 insertions, 0 deletions
diff --git a/include/asm-i386/mach-default/apm.h b/include/asm-i386/mach-default/apm.h new file mode 100644 index 000000000000..1f730b8bd1fd --- /dev/null +++ b/include/asm-i386/mach-default/apm.h | |||
@@ -0,0 +1,75 @@ | |||
1 | /* | ||
2 | * include/asm-i386/mach-default/apm.h | ||
3 | * | ||
4 | * Machine specific APM BIOS functions for generic. | ||
5 | * Split out from apm.c by Osamu Tomita <tomita@cinet.co.jp> | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_APM_H | ||
9 | #define _ASM_APM_H | ||
10 | |||
11 | #ifdef APM_ZERO_SEGS | ||
12 | # define APM_DO_ZERO_SEGS \ | ||
13 | "pushl %%ds\n\t" \ | ||
14 | "pushl %%es\n\t" \ | ||
15 | "xorl %%edx, %%edx\n\t" \ | ||
16 | "mov %%dx, %%ds\n\t" \ | ||
17 | "mov %%dx, %%es\n\t" \ | ||
18 | "mov %%dx, %%fs\n\t" \ | ||
19 | "mov %%dx, %%gs\n\t" | ||
20 | # define APM_DO_POP_SEGS \ | ||
21 | "popl %%es\n\t" \ | ||
22 | "popl %%ds\n\t" | ||
23 | #else | ||
24 | # define APM_DO_ZERO_SEGS | ||
25 | # define APM_DO_POP_SEGS | ||
26 | #endif | ||
27 | |||
28 | static inline void apm_bios_call_asm(u32 func, u32 ebx_in, u32 ecx_in, | ||
29 | u32 *eax, u32 *ebx, u32 *ecx, | ||
30 | u32 *edx, u32 *esi) | ||
31 | { | ||
32 | /* | ||
33 | * N.B. We do NOT need a cld after the BIOS call | ||
34 | * because we always save and restore the flags. | ||
35 | */ | ||
36 | __asm__ __volatile__(APM_DO_ZERO_SEGS | ||
37 | "pushl %%edi\n\t" | ||
38 | "pushl %%ebp\n\t" | ||
39 | "lcall *%%cs:apm_bios_entry\n\t" | ||
40 | "setc %%al\n\t" | ||
41 | "popl %%ebp\n\t" | ||
42 | "popl %%edi\n\t" | ||
43 | APM_DO_POP_SEGS | ||
44 | : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx), | ||
45 | "=S" (*esi) | ||
46 | : "a" (func), "b" (ebx_in), "c" (ecx_in) | ||
47 | : "memory", "cc"); | ||
48 | } | ||
49 | |||
50 | static inline u8 apm_bios_call_simple_asm(u32 func, u32 ebx_in, | ||
51 | u32 ecx_in, u32 *eax) | ||
52 | { | ||
53 | int cx, dx, si; | ||
54 | u8 error; | ||
55 | |||
56 | /* | ||
57 | * N.B. We do NOT need a cld after the BIOS call | ||
58 | * because we always save and restore the flags. | ||
59 | */ | ||
60 | __asm__ __volatile__(APM_DO_ZERO_SEGS | ||
61 | "pushl %%edi\n\t" | ||
62 | "pushl %%ebp\n\t" | ||
63 | "lcall *%%cs:apm_bios_entry\n\t" | ||
64 | "setc %%bl\n\t" | ||
65 | "popl %%ebp\n\t" | ||
66 | "popl %%edi\n\t" | ||
67 | APM_DO_POP_SEGS | ||
68 | : "=a" (*eax), "=b" (error), "=c" (cx), "=d" (dx), | ||
69 | "=S" (si) | ||
70 | : "a" (func), "b" (ebx_in), "c" (ecx_in) | ||
71 | : "memory", "cc"); | ||
72 | return error; | ||
73 | } | ||
74 | |||
75 | #endif /* _ASM_APM_H */ | ||
diff --git a/include/asm-i386/mach-default/bios_ebda.h b/include/asm-i386/mach-default/bios_ebda.h new file mode 100644 index 000000000000..9cbd9a668af8 --- /dev/null +++ b/include/asm-i386/mach-default/bios_ebda.h | |||
@@ -0,0 +1,15 @@ | |||
1 | #ifndef _MACH_BIOS_EBDA_H | ||
2 | #define _MACH_BIOS_EBDA_H | ||
3 | |||
4 | /* | ||
5 | * there is a real-mode segmented pointer pointing to the | ||
6 | * 4K EBDA area at 0x40E. | ||
7 | */ | ||
8 | static inline unsigned int get_bios_ebda(void) | ||
9 | { | ||
10 | unsigned int address = *(unsigned short *)phys_to_virt(0x40E); | ||
11 | address <<= 4; | ||
12 | return address; /* 0 means none */ | ||
13 | } | ||
14 | |||
15 | #endif /* _MACH_BIOS_EBDA_H */ | ||
diff --git a/include/asm-i386/mach-default/do_timer.h b/include/asm-i386/mach-default/do_timer.h new file mode 100644 index 000000000000..03dd13a48a8c --- /dev/null +++ b/include/asm-i386/mach-default/do_timer.h | |||
@@ -0,0 +1,85 @@ | |||
1 | /* defines for inline arch setup functions */ | ||
2 | |||
3 | #include <asm/apic.h> | ||
4 | |||
5 | /** | ||
6 | * do_timer_interrupt_hook - hook into timer tick | ||
7 | * @regs: standard registers from interrupt | ||
8 | * | ||
9 | * Description: | ||
10 | * This hook is called immediately after the timer interrupt is ack'd. | ||
11 | * It's primary purpose is to allow architectures that don't possess | ||
12 | * individual per CPU clocks (like the CPU APICs supply) to broadcast the | ||
13 | * timer interrupt as a means of triggering reschedules etc. | ||
14 | **/ | ||
15 | |||
16 | static inline void do_timer_interrupt_hook(struct pt_regs *regs) | ||
17 | { | ||
18 | do_timer(regs); | ||
19 | #ifndef CONFIG_SMP | ||
20 | update_process_times(user_mode(regs)); | ||
21 | #endif | ||
22 | /* | ||
23 | * In the SMP case we use the local APIC timer interrupt to do the | ||
24 | * profiling, except when we simulate SMP mode on a uniprocessor | ||
25 | * system, in that case we have to call the local interrupt handler. | ||
26 | */ | ||
27 | #ifndef CONFIG_X86_LOCAL_APIC | ||
28 | profile_tick(CPU_PROFILING, regs); | ||
29 | #else | ||
30 | if (!using_apic_timer) | ||
31 | smp_local_timer_interrupt(regs); | ||
32 | #endif | ||
33 | } | ||
34 | |||
35 | |||
36 | /* you can safely undefine this if you don't have the Neptune chipset */ | ||
37 | |||
38 | #define BUGGY_NEPTUN_TIMER | ||
39 | |||
40 | /** | ||
41 | * do_timer_overflow - process a detected timer overflow condition | ||
42 | * @count: hardware timer interrupt count on overflow | ||
43 | * | ||
44 | * Description: | ||
45 | * This call is invoked when the jiffies count has not incremented but | ||
46 | * the hardware timer interrupt has. It means that a timer tick interrupt | ||
47 | * came along while the previous one was pending, thus a tick was missed | ||
48 | **/ | ||
49 | static inline int do_timer_overflow(int count) | ||
50 | { | ||
51 | int i; | ||
52 | |||
53 | spin_lock(&i8259A_lock); | ||
54 | /* | ||
55 | * This is tricky when I/O APICs are used; | ||
56 | * see do_timer_interrupt(). | ||
57 | */ | ||
58 | i = inb(0x20); | ||
59 | spin_unlock(&i8259A_lock); | ||
60 | |||
61 | /* assumption about timer being IRQ0 */ | ||
62 | if (i & 0x01) { | ||
63 | /* | ||
64 | * We cannot detect lost timer interrupts ... | ||
65 | * well, that's why we call them lost, don't we? :) | ||
66 | * [hmm, on the Pentium and Alpha we can ... sort of] | ||
67 | */ | ||
68 | count -= LATCH; | ||
69 | } else { | ||
70 | #ifdef BUGGY_NEPTUN_TIMER | ||
71 | /* | ||
72 | * for the Neptun bug we know that the 'latch' | ||
73 | * command doesn't latch the high and low value | ||
74 | * of the counter atomically. Thus we have to | ||
75 | * substract 256 from the counter | ||
76 | * ... funny, isnt it? :) | ||
77 | */ | ||
78 | |||
79 | count -= 256; | ||
80 | #else | ||
81 | printk("do_slow_gettimeoffset(): hardware timer problem?\n"); | ||
82 | #endif | ||
83 | } | ||
84 | return count; | ||
85 | } | ||
diff --git a/include/asm-i386/mach-default/entry_arch.h b/include/asm-i386/mach-default/entry_arch.h new file mode 100644 index 000000000000..bc861469bdba --- /dev/null +++ b/include/asm-i386/mach-default/entry_arch.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * This file is designed to contain the BUILD_INTERRUPT specifications for | ||
3 | * all of the extra named interrupt vectors used by the architecture. | ||
4 | * Usually this is the Inter Process Interrupts (IPIs) | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * The following vectors are part of the Linux architecture, there | ||
9 | * is no hardware IRQ pin equivalent for them, they are triggered | ||
10 | * through the ICC by us (IPIs) | ||
11 | */ | ||
12 | #ifdef CONFIG_X86_SMP | ||
13 | BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) | ||
14 | BUILD_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR) | ||
15 | BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) | ||
16 | #endif | ||
17 | |||
18 | /* | ||
19 | * every pentium local APIC has two 'local interrupts', with a | ||
20 | * soft-definable vector attached to both interrupts, one of | ||
21 | * which is a timer interrupt, the other one is error counter | ||
22 | * overflow. Linux uses the local APIC timer interrupt to get | ||
23 | * a much simpler SMP time architecture: | ||
24 | */ | ||
25 | #ifdef CONFIG_X86_LOCAL_APIC | ||
26 | BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR) | ||
27 | BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR) | ||
28 | BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR) | ||
29 | |||
30 | #ifdef CONFIG_X86_MCE_P4THERMAL | ||
31 | BUILD_INTERRUPT(thermal_interrupt,THERMAL_APIC_VECTOR) | ||
32 | #endif | ||
33 | |||
34 | #endif | ||
diff --git a/include/asm-i386/mach-default/io_ports.h b/include/asm-i386/mach-default/io_ports.h new file mode 100644 index 000000000000..a96d9f6604ee --- /dev/null +++ b/include/asm-i386/mach-default/io_ports.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * arch/i386/mach-generic/io_ports.h | ||
3 | * | ||
4 | * Machine specific IO port address definition for generic. | ||
5 | * Written by Osamu Tomita <tomita@cinet.co.jp> | ||
6 | */ | ||
7 | #ifndef _MACH_IO_PORTS_H | ||
8 | #define _MACH_IO_PORTS_H | ||
9 | |||
10 | /* i8253A PIT registers */ | ||
11 | #define PIT_MODE 0x43 | ||
12 | #define PIT_CH0 0x40 | ||
13 | #define PIT_CH2 0x42 | ||
14 | |||
15 | /* i8259A PIC registers */ | ||
16 | #define PIC_MASTER_CMD 0x20 | ||
17 | #define PIC_MASTER_IMR 0x21 | ||
18 | #define PIC_MASTER_ISR PIC_MASTER_CMD | ||
19 | #define PIC_MASTER_POLL PIC_MASTER_ISR | ||
20 | #define PIC_MASTER_OCW3 PIC_MASTER_ISR | ||
21 | #define PIC_SLAVE_CMD 0xa0 | ||
22 | #define PIC_SLAVE_IMR 0xa1 | ||
23 | |||
24 | /* i8259A PIC related value */ | ||
25 | #define PIC_CASCADE_IR 2 | ||
26 | #define MASTER_ICW4_DEFAULT 0x01 | ||
27 | #define SLAVE_ICW4_DEFAULT 0x01 | ||
28 | #define PIC_ICW4_AEOI 2 | ||
29 | |||
30 | #endif /* !_MACH_IO_PORTS_H */ | ||
diff --git a/include/asm-i386/mach-default/irq_vectors.h b/include/asm-i386/mach-default/irq_vectors.h new file mode 100644 index 000000000000..881c63ca61ad --- /dev/null +++ b/include/asm-i386/mach-default/irq_vectors.h | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * This file should contain #defines for all of the interrupt vector | ||
3 | * numbers used by this architecture. | ||
4 | * | ||
5 | * In addition, there are some standard defines: | ||
6 | * | ||
7 | * FIRST_EXTERNAL_VECTOR: | ||
8 | * The first free place for external interrupts | ||
9 | * | ||
10 | * SYSCALL_VECTOR: | ||
11 | * The IRQ vector a syscall makes the user to kernel transition | ||
12 | * under. | ||
13 | * | ||
14 | * TIMER_IRQ: | ||
15 | * The IRQ number the timer interrupt comes in at. | ||
16 | * | ||
17 | * NR_IRQS: | ||
18 | * The total number of interrupt vectors (including all the | ||
19 | * architecture specific interrupts) needed. | ||
20 | * | ||
21 | */ | ||
22 | #ifndef _ASM_IRQ_VECTORS_H | ||
23 | #define _ASM_IRQ_VECTORS_H | ||
24 | |||
25 | /* | ||
26 | * IDT vectors usable for external interrupt sources start | ||
27 | * at 0x20: | ||
28 | */ | ||
29 | #define FIRST_EXTERNAL_VECTOR 0x20 | ||
30 | |||
31 | #define SYSCALL_VECTOR 0x80 | ||
32 | |||
33 | /* | ||
34 | * Vectors 0x20-0x2f are used for ISA interrupts. | ||
35 | */ | ||
36 | |||
37 | /* | ||
38 | * Special IRQ vectors used by the SMP architecture, 0xf0-0xff | ||
39 | * | ||
40 | * some of the following vectors are 'rare', they are merged | ||
41 | * into a single vector (CALL_FUNCTION_VECTOR) to save vector space. | ||
42 | * TLB, reschedule and local APIC vectors are performance-critical. | ||
43 | * | ||
44 | * Vectors 0xf0-0xfa are free (reserved for future Linux use). | ||
45 | */ | ||
46 | #define SPURIOUS_APIC_VECTOR 0xff | ||
47 | #define ERROR_APIC_VECTOR 0xfe | ||
48 | #define INVALIDATE_TLB_VECTOR 0xfd | ||
49 | #define RESCHEDULE_VECTOR 0xfc | ||
50 | #define CALL_FUNCTION_VECTOR 0xfb | ||
51 | |||
52 | #define THERMAL_APIC_VECTOR 0xf0 | ||
53 | /* | ||
54 | * Local APIC timer IRQ vector is on a different priority level, | ||
55 | * to work around the 'lost local interrupt if more than 2 IRQ | ||
56 | * sources per level' errata. | ||
57 | */ | ||
58 | #define LOCAL_TIMER_VECTOR 0xef | ||
59 | |||
60 | /* | ||
61 | * First APIC vector available to drivers: (vectors 0x30-0xee) | ||
62 | * we start at 0x31 to spread out vectors evenly between priority | ||
63 | * levels. (0x80 is the syscall vector) | ||
64 | */ | ||
65 | #define FIRST_DEVICE_VECTOR 0x31 | ||
66 | #define FIRST_SYSTEM_VECTOR 0xef | ||
67 | |||
68 | #define TIMER_IRQ 0 | ||
69 | |||
70 | /* | ||
71 | * 16 8259A IRQ's, 208 potential APIC interrupt sources. | ||
72 | * Right now the APIC is mostly only used for SMP. | ||
73 | * 256 vectors is an architectural limit. (we can have | ||
74 | * more than 256 devices theoretically, but they will | ||
75 | * have to use shared interrupts) | ||
76 | * Since vectors 0x00-0x1f are used/reserved for the CPU, | ||
77 | * the usable vector space is 0x20-0xff (224 vectors) | ||
78 | */ | ||
79 | |||
80 | /* | ||
81 | * The maximum number of vectors supported by i386 processors | ||
82 | * is limited to 256. For processors other than i386, NR_VECTORS | ||
83 | * should be changed accordingly. | ||
84 | */ | ||
85 | #define NR_VECTORS 256 | ||
86 | |||
87 | #include "irq_vectors_limits.h" | ||
88 | |||
89 | #define FPU_IRQ 13 | ||
90 | |||
91 | #define FIRST_VM86_IRQ 3 | ||
92 | #define LAST_VM86_IRQ 15 | ||
93 | #define invalid_vm86_irq(irq) ((irq) < 3 || (irq) > 15) | ||
94 | |||
95 | |||
96 | #endif /* _ASM_IRQ_VECTORS_H */ | ||
diff --git a/include/asm-i386/mach-default/irq_vectors_limits.h b/include/asm-i386/mach-default/irq_vectors_limits.h new file mode 100644 index 000000000000..b330026e6f7f --- /dev/null +++ b/include/asm-i386/mach-default/irq_vectors_limits.h | |||
@@ -0,0 +1,21 @@ | |||
1 | #ifndef _ASM_IRQ_VECTORS_LIMITS_H | ||
2 | #define _ASM_IRQ_VECTORS_LIMITS_H | ||
3 | |||
4 | #ifdef CONFIG_PCI_MSI | ||
5 | #define NR_IRQS FIRST_SYSTEM_VECTOR | ||
6 | #define NR_IRQ_VECTORS NR_IRQS | ||
7 | #else | ||
8 | #ifdef CONFIG_X86_IO_APIC | ||
9 | #define NR_IRQS 224 | ||
10 | # if (224 >= 32 * NR_CPUS) | ||
11 | # define NR_IRQ_VECTORS NR_IRQS | ||
12 | # else | ||
13 | # define NR_IRQ_VECTORS (32 * NR_CPUS) | ||
14 | # endif | ||
15 | #else | ||
16 | #define NR_IRQS 16 | ||
17 | #define NR_IRQ_VECTORS NR_IRQS | ||
18 | #endif | ||
19 | #endif | ||
20 | |||
21 | #endif /* _ASM_IRQ_VECTORS_LIMITS_H */ | ||
diff --git a/include/asm-i386/mach-default/mach_apic.h b/include/asm-i386/mach-default/mach_apic.h new file mode 100644 index 000000000000..627f1cd084ba --- /dev/null +++ b/include/asm-i386/mach-default/mach_apic.h | |||
@@ -0,0 +1,133 @@ | |||
1 | #ifndef __ASM_MACH_APIC_H | ||
2 | #define __ASM_MACH_APIC_H | ||
3 | |||
4 | #include <mach_apicdef.h> | ||
5 | #include <asm/smp.h> | ||
6 | |||
7 | #define APIC_DFR_VALUE (APIC_DFR_FLAT) | ||
8 | |||
9 | static inline cpumask_t target_cpus(void) | ||
10 | { | ||
11 | #ifdef CONFIG_SMP | ||
12 | return cpu_online_map; | ||
13 | #else | ||
14 | return cpumask_of_cpu(0); | ||
15 | #endif | ||
16 | } | ||
17 | #define TARGET_CPUS (target_cpus()) | ||
18 | |||
19 | #define NO_BALANCE_IRQ (0) | ||
20 | #define esr_disable (0) | ||
21 | |||
22 | #define NO_IOAPIC_CHECK (0) | ||
23 | |||
24 | #define INT_DELIVERY_MODE dest_LowestPrio | ||
25 | #define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */ | ||
26 | |||
27 | static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid) | ||
28 | { | ||
29 | return physid_isset(apicid, bitmap); | ||
30 | } | ||
31 | |||
32 | static inline unsigned long check_apicid_present(int bit) | ||
33 | { | ||
34 | return physid_isset(bit, phys_cpu_present_map); | ||
35 | } | ||
36 | |||
37 | /* | ||
38 | * Set up the logical destination ID. | ||
39 | * | ||
40 | * Intel recommends to set DFR, LDR and TPR before enabling | ||
41 | * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel | ||
42 | * document number 292116). So here it goes... | ||
43 | */ | ||
44 | static inline void init_apic_ldr(void) | ||
45 | { | ||
46 | unsigned long val; | ||
47 | |||
48 | apic_write_around(APIC_DFR, APIC_DFR_VALUE); | ||
49 | val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; | ||
50 | val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id()); | ||
51 | apic_write_around(APIC_LDR, val); | ||
52 | } | ||
53 | |||
54 | static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map) | ||
55 | { | ||
56 | return phys_map; | ||
57 | } | ||
58 | |||
59 | static inline void clustered_apic_check(void) | ||
60 | { | ||
61 | printk("Enabling APIC mode: %s. Using %d I/O APICs\n", | ||
62 | "Flat", nr_ioapics); | ||
63 | } | ||
64 | |||
65 | static inline int multi_timer_check(int apic, int irq) | ||
66 | { | ||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static inline int apicid_to_node(int logical_apicid) | ||
71 | { | ||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | /* Mapping from cpu number to logical apicid */ | ||
76 | static inline int cpu_to_logical_apicid(int cpu) | ||
77 | { | ||
78 | return 1 << cpu; | ||
79 | } | ||
80 | |||
81 | static inline int cpu_present_to_apicid(int mps_cpu) | ||
82 | { | ||
83 | if (mps_cpu < get_physical_broadcast()) | ||
84 | return mps_cpu; | ||
85 | else | ||
86 | return BAD_APICID; | ||
87 | } | ||
88 | |||
89 | static inline physid_mask_t apicid_to_cpu_present(int phys_apicid) | ||
90 | { | ||
91 | return physid_mask_of_physid(phys_apicid); | ||
92 | } | ||
93 | |||
94 | static inline int mpc_apic_id(struct mpc_config_processor *m, | ||
95 | struct mpc_config_translation *translation_record) | ||
96 | { | ||
97 | printk("Processor #%d %ld:%ld APIC version %d\n", | ||
98 | m->mpc_apicid, | ||
99 | (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, | ||
100 | (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, | ||
101 | m->mpc_apicver); | ||
102 | return (m->mpc_apicid); | ||
103 | } | ||
104 | |||
105 | static inline void setup_portio_remap(void) | ||
106 | { | ||
107 | } | ||
108 | |||
109 | static inline int check_phys_apicid_present(int boot_cpu_physical_apicid) | ||
110 | { | ||
111 | return physid_isset(boot_cpu_physical_apicid, phys_cpu_present_map); | ||
112 | } | ||
113 | |||
114 | static inline int apic_id_registered(void) | ||
115 | { | ||
116 | return physid_isset(GET_APIC_ID(apic_read(APIC_ID)), phys_cpu_present_map); | ||
117 | } | ||
118 | |||
119 | static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) | ||
120 | { | ||
121 | return cpus_addr(cpumask)[0]; | ||
122 | } | ||
123 | |||
124 | static inline void enable_apic_mode(void) | ||
125 | { | ||
126 | } | ||
127 | |||
128 | static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb) | ||
129 | { | ||
130 | return cpuid_apic >> index_msb; | ||
131 | } | ||
132 | |||
133 | #endif /* __ASM_MACH_APIC_H */ | ||
diff --git a/include/asm-i386/mach-default/mach_apicdef.h b/include/asm-i386/mach-default/mach_apicdef.h new file mode 100644 index 000000000000..7bcb350c3ee8 --- /dev/null +++ b/include/asm-i386/mach-default/mach_apicdef.h | |||
@@ -0,0 +1,13 @@ | |||
1 | #ifndef __ASM_MACH_APICDEF_H | ||
2 | #define __ASM_MACH_APICDEF_H | ||
3 | |||
4 | #define APIC_ID_MASK (0xF<<24) | ||
5 | |||
6 | static inline unsigned get_apic_id(unsigned long x) | ||
7 | { | ||
8 | return (((x)>>24)&0xF); | ||
9 | } | ||
10 | |||
11 | #define GET_APIC_ID(x) get_apic_id(x) | ||
12 | |||
13 | #endif | ||
diff --git a/include/asm-i386/mach-default/mach_ipi.h b/include/asm-i386/mach-default/mach_ipi.h new file mode 100644 index 000000000000..6f2b17a20089 --- /dev/null +++ b/include/asm-i386/mach-default/mach_ipi.h | |||
@@ -0,0 +1,30 @@ | |||
1 | #ifndef __ASM_MACH_IPI_H | ||
2 | #define __ASM_MACH_IPI_H | ||
3 | |||
4 | void send_IPI_mask_bitmask(cpumask_t mask, int vector); | ||
5 | void __send_IPI_shortcut(unsigned int shortcut, int vector); | ||
6 | |||
7 | static inline void send_IPI_mask(cpumask_t mask, int vector) | ||
8 | { | ||
9 | send_IPI_mask_bitmask(mask, vector); | ||
10 | } | ||
11 | |||
12 | static inline void send_IPI_allbutself(int vector) | ||
13 | { | ||
14 | /* | ||
15 | * if there are no other CPUs in the system then we get an APIC send | ||
16 | * error if we try to broadcast, thus avoid sending IPIs in this case. | ||
17 | */ | ||
18 | if (!(num_online_cpus() > 1)) | ||
19 | return; | ||
20 | |||
21 | __send_IPI_shortcut(APIC_DEST_ALLBUT, vector); | ||
22 | return; | ||
23 | } | ||
24 | |||
25 | static inline void send_IPI_all(int vector) | ||
26 | { | ||
27 | __send_IPI_shortcut(APIC_DEST_ALLINC, vector); | ||
28 | } | ||
29 | |||
30 | #endif /* __ASM_MACH_IPI_H */ | ||
diff --git a/include/asm-i386/mach-default/mach_mpparse.h b/include/asm-i386/mach-default/mach_mpparse.h new file mode 100644 index 000000000000..1d3832482580 --- /dev/null +++ b/include/asm-i386/mach-default/mach_mpparse.h | |||
@@ -0,0 +1,28 @@ | |||
1 | #ifndef __ASM_MACH_MPPARSE_H | ||
2 | #define __ASM_MACH_MPPARSE_H | ||
3 | |||
4 | static inline void mpc_oem_bus_info(struct mpc_config_bus *m, char *name, | ||
5 | struct mpc_config_translation *translation) | ||
6 | { | ||
7 | // Dprintk("Bus #%d is %s\n", m->mpc_busid, name); | ||
8 | } | ||
9 | |||
10 | static inline void mpc_oem_pci_bus(struct mpc_config_bus *m, | ||
11 | struct mpc_config_translation *translation) | ||
12 | { | ||
13 | } | ||
14 | |||
15 | static inline int mps_oem_check(struct mp_config_table *mpc, char *oem, | ||
16 | char *productid) | ||
17 | { | ||
18 | return 0; | ||
19 | } | ||
20 | |||
21 | /* Hook from generic ACPI tables.c */ | ||
22 | static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) | ||
23 | { | ||
24 | return 0; | ||
25 | } | ||
26 | |||
27 | |||
28 | #endif /* __ASM_MACH_MPPARSE_H */ | ||
diff --git a/include/asm-i386/mach-default/mach_mpspec.h b/include/asm-i386/mach-default/mach_mpspec.h new file mode 100644 index 000000000000..6b5dadcf1d0e --- /dev/null +++ b/include/asm-i386/mach-default/mach_mpspec.h | |||
@@ -0,0 +1,8 @@ | |||
1 | #ifndef __ASM_MACH_MPSPEC_H | ||
2 | #define __ASM_MACH_MPSPEC_H | ||
3 | |||
4 | #define MAX_IRQ_SOURCES 256 | ||
5 | |||
6 | #define MAX_MP_BUSSES 32 | ||
7 | |||
8 | #endif /* __ASM_MACH_MPSPEC_H */ | ||
diff --git a/include/asm-i386/mach-default/mach_reboot.h b/include/asm-i386/mach-default/mach_reboot.h new file mode 100644 index 000000000000..521e227db679 --- /dev/null +++ b/include/asm-i386/mach-default/mach_reboot.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * arch/i386/mach-generic/mach_reboot.h | ||
3 | * | ||
4 | * Machine specific reboot functions for generic. | ||
5 | * Split out from reboot.c by Osamu Tomita <tomita@cinet.co.jp> | ||
6 | */ | ||
7 | #ifndef _MACH_REBOOT_H | ||
8 | #define _MACH_REBOOT_H | ||
9 | |||
10 | static inline void kb_wait(void) | ||
11 | { | ||
12 | int i; | ||
13 | |||
14 | for (i = 0; i < 0x10000; i++) | ||
15 | if ((inb_p(0x64) & 0x02) == 0) | ||
16 | break; | ||
17 | } | ||
18 | |||
19 | static inline void mach_reboot(void) | ||
20 | { | ||
21 | int i; | ||
22 | for (i = 0; i < 100; i++) { | ||
23 | kb_wait(); | ||
24 | udelay(50); | ||
25 | outb(0xfe, 0x64); /* pulse reset low */ | ||
26 | udelay(50); | ||
27 | } | ||
28 | } | ||
29 | |||
30 | #endif /* !_MACH_REBOOT_H */ | ||
diff --git a/include/asm-i386/mach-default/mach_time.h b/include/asm-i386/mach-default/mach_time.h new file mode 100644 index 000000000000..b749aa44a86f --- /dev/null +++ b/include/asm-i386/mach-default/mach_time.h | |||
@@ -0,0 +1,122 @@ | |||
1 | /* | ||
2 | * include/asm-i386/mach-default/mach_time.h | ||
3 | * | ||
4 | * Machine specific set RTC function for generic. | ||
5 | * Split out from time.c by Osamu Tomita <tomita@cinet.co.jp> | ||
6 | */ | ||
7 | #ifndef _MACH_TIME_H | ||
8 | #define _MACH_TIME_H | ||
9 | |||
10 | #include <linux/mc146818rtc.h> | ||
11 | |||
12 | /* for check timing call set_rtc_mmss() 500ms */ | ||
13 | /* used in arch/i386/time.c::do_timer_interrupt() */ | ||
14 | #define USEC_AFTER 500000 | ||
15 | #define USEC_BEFORE 500000 | ||
16 | |||
17 | /* | ||
18 | * In order to set the CMOS clock precisely, set_rtc_mmss has to be | ||
19 | * called 500 ms after the second nowtime has started, because when | ||
20 | * nowtime is written into the registers of the CMOS clock, it will | ||
21 | * jump to the next second precisely 500 ms later. Check the Motorola | ||
22 | * MC146818A or Dallas DS12887 data sheet for details. | ||
23 | * | ||
24 | * BUG: This routine does not handle hour overflow properly; it just | ||
25 | * sets the minutes. Usually you'll only notice that after reboot! | ||
26 | */ | ||
27 | static inline int mach_set_rtc_mmss(unsigned long nowtime) | ||
28 | { | ||
29 | int retval = 0; | ||
30 | int real_seconds, real_minutes, cmos_minutes; | ||
31 | unsigned char save_control, save_freq_select; | ||
32 | |||
33 | save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ | ||
34 | CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); | ||
35 | |||
36 | save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ | ||
37 | CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); | ||
38 | |||
39 | cmos_minutes = CMOS_READ(RTC_MINUTES); | ||
40 | if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | ||
41 | BCD_TO_BIN(cmos_minutes); | ||
42 | |||
43 | /* | ||
44 | * since we're only adjusting minutes and seconds, | ||
45 | * don't interfere with hour overflow. This avoids | ||
46 | * messing with unknown time zones but requires your | ||
47 | * RTC not to be off by more than 15 minutes | ||
48 | */ | ||
49 | real_seconds = nowtime % 60; | ||
50 | real_minutes = nowtime / 60; | ||
51 | if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) | ||
52 | real_minutes += 30; /* correct for half hour time zone */ | ||
53 | real_minutes %= 60; | ||
54 | |||
55 | if (abs(real_minutes - cmos_minutes) < 30) { | ||
56 | if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { | ||
57 | BIN_TO_BCD(real_seconds); | ||
58 | BIN_TO_BCD(real_minutes); | ||
59 | } | ||
60 | CMOS_WRITE(real_seconds,RTC_SECONDS); | ||
61 | CMOS_WRITE(real_minutes,RTC_MINUTES); | ||
62 | } else { | ||
63 | printk(KERN_WARNING | ||
64 | "set_rtc_mmss: can't update from %d to %d\n", | ||
65 | cmos_minutes, real_minutes); | ||
66 | retval = -1; | ||
67 | } | ||
68 | |||
69 | /* The following flags have to be released exactly in this order, | ||
70 | * otherwise the DS12887 (popular MC146818A clone with integrated | ||
71 | * battery and quartz) will not reset the oscillator and will not | ||
72 | * update precisely 500 ms later. You won't find this mentioned in | ||
73 | * the Dallas Semiconductor data sheets, but who believes data | ||
74 | * sheets anyway ... -- Markus Kuhn | ||
75 | */ | ||
76 | CMOS_WRITE(save_control, RTC_CONTROL); | ||
77 | CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); | ||
78 | |||
79 | return retval; | ||
80 | } | ||
81 | |||
82 | static inline unsigned long mach_get_cmos_time(void) | ||
83 | { | ||
84 | unsigned int year, mon, day, hour, min, sec; | ||
85 | int i; | ||
86 | |||
87 | /* The Linux interpretation of the CMOS clock register contents: | ||
88 | * When the Update-In-Progress (UIP) flag goes from 1 to 0, the | ||
89 | * RTC registers show the second which has precisely just started. | ||
90 | * Let's hope other operating systems interpret the RTC the same way. | ||
91 | */ | ||
92 | /* read RTC exactly on falling edge of update flag */ | ||
93 | for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ | ||
94 | if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) | ||
95 | break; | ||
96 | for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */ | ||
97 | if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) | ||
98 | break; | ||
99 | do { /* Isn't this overkill ? UIP above should guarantee consistency */ | ||
100 | sec = CMOS_READ(RTC_SECONDS); | ||
101 | min = CMOS_READ(RTC_MINUTES); | ||
102 | hour = CMOS_READ(RTC_HOURS); | ||
103 | day = CMOS_READ(RTC_DAY_OF_MONTH); | ||
104 | mon = CMOS_READ(RTC_MONTH); | ||
105 | year = CMOS_READ(RTC_YEAR); | ||
106 | } while (sec != CMOS_READ(RTC_SECONDS)); | ||
107 | if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | ||
108 | { | ||
109 | BCD_TO_BIN(sec); | ||
110 | BCD_TO_BIN(min); | ||
111 | BCD_TO_BIN(hour); | ||
112 | BCD_TO_BIN(day); | ||
113 | BCD_TO_BIN(mon); | ||
114 | BCD_TO_BIN(year); | ||
115 | } | ||
116 | if ((year += 1900) < 1970) | ||
117 | year += 100; | ||
118 | |||
119 | return mktime(year, mon, day, hour, min, sec); | ||
120 | } | ||
121 | |||
122 | #endif /* !_MACH_TIME_H */ | ||
diff --git a/include/asm-i386/mach-default/mach_timer.h b/include/asm-i386/mach-default/mach_timer.h new file mode 100644 index 000000000000..4b9703bb0288 --- /dev/null +++ b/include/asm-i386/mach-default/mach_timer.h | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * include/asm-i386/mach-default/mach_timer.h | ||
3 | * | ||
4 | * Machine specific calibrate_tsc() for generic. | ||
5 | * Split out from timer_tsc.c by Osamu Tomita <tomita@cinet.co.jp> | ||
6 | */ | ||
7 | /* ------ Calibrate the TSC ------- | ||
8 | * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset(). | ||
9 | * Too much 64-bit arithmetic here to do this cleanly in C, and for | ||
10 | * accuracy's sake we want to keep the overhead on the CTC speaker (channel 2) | ||
11 | * output busy loop as low as possible. We avoid reading the CTC registers | ||
12 | * directly because of the awkward 8-bit access mechanism of the 82C54 | ||
13 | * device. | ||
14 | */ | ||
15 | #ifndef _MACH_TIMER_H | ||
16 | #define _MACH_TIMER_H | ||
17 | |||
18 | #define CALIBRATE_LATCH (5 * LATCH) | ||
19 | |||
20 | static inline void mach_prepare_counter(void) | ||
21 | { | ||
22 | /* Set the Gate high, disable speaker */ | ||
23 | outb((inb(0x61) & ~0x02) | 0x01, 0x61); | ||
24 | |||
25 | /* | ||
26 | * Now let's take care of CTC channel 2 | ||
27 | * | ||
28 | * Set the Gate high, program CTC channel 2 for mode 0, | ||
29 | * (interrupt on terminal count mode), binary count, | ||
30 | * load 5 * LATCH count, (LSB and MSB) to begin countdown. | ||
31 | * | ||
32 | * Some devices need a delay here. | ||
33 | */ | ||
34 | outb(0xb0, 0x43); /* binary, mode 0, LSB/MSB, Ch 2 */ | ||
35 | outb_p(CALIBRATE_LATCH & 0xff, 0x42); /* LSB of count */ | ||
36 | outb_p(CALIBRATE_LATCH >> 8, 0x42); /* MSB of count */ | ||
37 | } | ||
38 | |||
39 | static inline void mach_countup(unsigned long *count_p) | ||
40 | { | ||
41 | unsigned long count = 0; | ||
42 | do { | ||
43 | count++; | ||
44 | } while ((inb_p(0x61) & 0x20) == 0); | ||
45 | *count_p = count; | ||
46 | } | ||
47 | |||
48 | #endif /* !_MACH_TIMER_H */ | ||
diff --git a/include/asm-i386/mach-default/mach_traps.h b/include/asm-i386/mach-default/mach_traps.h new file mode 100644 index 000000000000..625438b8a6eb --- /dev/null +++ b/include/asm-i386/mach-default/mach_traps.h | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * include/asm-i386/mach-default/mach_traps.h | ||
3 | * | ||
4 | * Machine specific NMI handling for generic. | ||
5 | * Split out from traps.c by Osamu Tomita <tomita@cinet.co.jp> | ||
6 | */ | ||
7 | #ifndef _MACH_TRAPS_H | ||
8 | #define _MACH_TRAPS_H | ||
9 | |||
10 | #include <asm/mc146818rtc.h> | ||
11 | |||
12 | static inline void clear_mem_error(unsigned char reason) | ||
13 | { | ||
14 | reason = (reason & 0xf) | 4; | ||
15 | outb(reason, 0x61); | ||
16 | } | ||
17 | |||
18 | static inline unsigned char get_nmi_reason(void) | ||
19 | { | ||
20 | return inb(0x61); | ||
21 | } | ||
22 | |||
23 | static inline void reassert_nmi(void) | ||
24 | { | ||
25 | int old_reg = -1; | ||
26 | |||
27 | if (do_i_have_lock_cmos()) | ||
28 | old_reg = current_lock_cmos_reg(); | ||
29 | else | ||
30 | lock_cmos(0); /* register doesn't matter here */ | ||
31 | outb(0x8f, 0x70); | ||
32 | inb(0x71); /* dummy */ | ||
33 | outb(0x0f, 0x70); | ||
34 | inb(0x71); /* dummy */ | ||
35 | if (old_reg >= 0) | ||
36 | outb(old_reg, 0x70); | ||
37 | else | ||
38 | unlock_cmos(); | ||
39 | } | ||
40 | |||
41 | #endif /* !_MACH_TRAPS_H */ | ||
diff --git a/include/asm-i386/mach-default/mach_wakecpu.h b/include/asm-i386/mach-default/mach_wakecpu.h new file mode 100644 index 000000000000..673b85c9b273 --- /dev/null +++ b/include/asm-i386/mach-default/mach_wakecpu.h | |||
@@ -0,0 +1,41 @@ | |||
1 | #ifndef __ASM_MACH_WAKECPU_H | ||
2 | #define __ASM_MACH_WAKECPU_H | ||
3 | |||
4 | /* | ||
5 | * This file copes with machines that wakeup secondary CPUs by the | ||
6 | * INIT, INIT, STARTUP sequence. | ||
7 | */ | ||
8 | |||
9 | #define WAKE_SECONDARY_VIA_INIT | ||
10 | |||
11 | #define TRAMPOLINE_LOW phys_to_virt(0x467) | ||
12 | #define TRAMPOLINE_HIGH phys_to_virt(0x469) | ||
13 | |||
14 | #define boot_cpu_apicid boot_cpu_physical_apicid | ||
15 | |||
16 | static inline void wait_for_init_deassert(atomic_t *deassert) | ||
17 | { | ||
18 | while (!atomic_read(deassert)); | ||
19 | return; | ||
20 | } | ||
21 | |||
22 | /* Nothing to do for most platforms, since cleared by the INIT cycle */ | ||
23 | static inline void smp_callin_clear_local_apic(void) | ||
24 | { | ||
25 | } | ||
26 | |||
27 | static inline void store_NMI_vector(unsigned short *high, unsigned short *low) | ||
28 | { | ||
29 | } | ||
30 | |||
31 | static inline void restore_NMI_vector(unsigned short *high, unsigned short *low) | ||
32 | { | ||
33 | } | ||
34 | |||
35 | #if APIC_DEBUG | ||
36 | #define inquire_remote_apic(apicid) __inquire_remote_apic(apicid) | ||
37 | #else | ||
38 | #define inquire_remote_apic(apicid) {} | ||
39 | #endif | ||
40 | |||
41 | #endif /* __ASM_MACH_WAKECPU_H */ | ||
diff --git a/include/asm-i386/mach-default/pci-functions.h b/include/asm-i386/mach-default/pci-functions.h new file mode 100644 index 000000000000..ed0bab427354 --- /dev/null +++ b/include/asm-i386/mach-default/pci-functions.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * PCI BIOS function numbering for conventional PCI BIOS | ||
3 | * systems | ||
4 | */ | ||
5 | |||
6 | #define PCIBIOS_PCI_FUNCTION_ID 0xb1XX | ||
7 | #define PCIBIOS_PCI_BIOS_PRESENT 0xb101 | ||
8 | #define PCIBIOS_FIND_PCI_DEVICE 0xb102 | ||
9 | #define PCIBIOS_FIND_PCI_CLASS_CODE 0xb103 | ||
10 | #define PCIBIOS_GENERATE_SPECIAL_CYCLE 0xb106 | ||
11 | #define PCIBIOS_READ_CONFIG_BYTE 0xb108 | ||
12 | #define PCIBIOS_READ_CONFIG_WORD 0xb109 | ||
13 | #define PCIBIOS_READ_CONFIG_DWORD 0xb10a | ||
14 | #define PCIBIOS_WRITE_CONFIG_BYTE 0xb10b | ||
15 | #define PCIBIOS_WRITE_CONFIG_WORD 0xb10c | ||
16 | #define PCIBIOS_WRITE_CONFIG_DWORD 0xb10d | ||
17 | #define PCIBIOS_GET_ROUTING_OPTIONS 0xb10e | ||
18 | #define PCIBIOS_SET_PCI_HW_INT 0xb10f | ||
19 | |||
diff --git a/include/asm-i386/mach-default/setup_arch_post.h b/include/asm-i386/mach-default/setup_arch_post.h new file mode 100644 index 000000000000..2fc4888721f6 --- /dev/null +++ b/include/asm-i386/mach-default/setup_arch_post.h | |||
@@ -0,0 +1,40 @@ | |||
1 | /** | ||
2 | * machine_specific_memory_setup - Hook for machine specific memory setup. | ||
3 | * | ||
4 | * Description: | ||
5 | * This is included late in kernel/setup.c so that it can make | ||
6 | * use of all of the static functions. | ||
7 | **/ | ||
8 | |||
9 | static char * __init machine_specific_memory_setup(void) | ||
10 | { | ||
11 | char *who; | ||
12 | |||
13 | |||
14 | who = "BIOS-e820"; | ||
15 | |||
16 | /* | ||
17 | * Try to copy the BIOS-supplied E820-map. | ||
18 | * | ||
19 | * Otherwise fake a memory map; one section from 0k->640k, | ||
20 | * the next section from 1mb->appropriate_mem_k | ||
21 | */ | ||
22 | sanitize_e820_map(E820_MAP, &E820_MAP_NR); | ||
23 | if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) { | ||
24 | unsigned long mem_size; | ||
25 | |||
26 | /* compare results from other methods and take the greater */ | ||
27 | if (ALT_MEM_K < EXT_MEM_K) { | ||
28 | mem_size = EXT_MEM_K; | ||
29 | who = "BIOS-88"; | ||
30 | } else { | ||
31 | mem_size = ALT_MEM_K; | ||
32 | who = "BIOS-e801"; | ||
33 | } | ||
34 | |||
35 | e820.nr_map = 0; | ||
36 | add_memory_region(0, LOWMEMSIZE(), E820_RAM); | ||
37 | add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM); | ||
38 | } | ||
39 | return who; | ||
40 | } | ||
diff --git a/include/asm-i386/mach-default/setup_arch_pre.h b/include/asm-i386/mach-default/setup_arch_pre.h new file mode 100644 index 000000000000..fb42099e7bd4 --- /dev/null +++ b/include/asm-i386/mach-default/setup_arch_pre.h | |||
@@ -0,0 +1,5 @@ | |||
1 | /* Hook to call BIOS initialisation function */ | ||
2 | |||
3 | /* no action for generic */ | ||
4 | |||
5 | #define ARCH_SETUP | ||
diff --git a/include/asm-i386/mach-default/smpboot_hooks.h b/include/asm-i386/mach-default/smpboot_hooks.h new file mode 100644 index 000000000000..7f45f6311059 --- /dev/null +++ b/include/asm-i386/mach-default/smpboot_hooks.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* two abstractions specific to kernel/smpboot.c, mainly to cater to visws | ||
2 | * which needs to alter them. */ | ||
3 | |||
4 | static inline void smpboot_clear_io_apic_irqs(void) | ||
5 | { | ||
6 | io_apic_irqs = 0; | ||
7 | } | ||
8 | |||
9 | static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) | ||
10 | { | ||
11 | CMOS_WRITE(0xa, 0xf); | ||
12 | local_flush_tlb(); | ||
13 | Dprintk("1.\n"); | ||
14 | *((volatile unsigned short *) TRAMPOLINE_HIGH) = start_eip >> 4; | ||
15 | Dprintk("2.\n"); | ||
16 | *((volatile unsigned short *) TRAMPOLINE_LOW) = start_eip & 0xf; | ||
17 | Dprintk("3.\n"); | ||
18 | } | ||
19 | |||
20 | static inline void smpboot_restore_warm_reset_vector(void) | ||
21 | { | ||
22 | /* | ||
23 | * Install writable page 0 entry to set BIOS data area. | ||
24 | */ | ||
25 | local_flush_tlb(); | ||
26 | |||
27 | /* | ||
28 | * Paranoid: Set warm reset code and vector here back | ||
29 | * to default values. | ||
30 | */ | ||
31 | CMOS_WRITE(0, 0xf); | ||
32 | |||
33 | *((volatile long *) phys_to_virt(0x467)) = 0; | ||
34 | } | ||
35 | |||
36 | static inline void smpboot_setup_io_apic(void) | ||
37 | { | ||
38 | /* | ||
39 | * Here we can be sure that there is an IO-APIC in the system. Let's | ||
40 | * go and set it up: | ||
41 | */ | ||
42 | if (!skip_ioapic_setup && nr_ioapics) | ||
43 | setup_IO_APIC(); | ||
44 | } | ||