diff options
author | Jack Steiner <steiner@sgi.com> | 2008-03-28 14:12:16 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-04-17 17:41:33 +0200 |
commit | ac23d4ee3f84de33c16ed7e68f9adee2386e74fb (patch) | |
tree | 296346293480fb5d67a15d7552bf41bd0cadd4cf /include/asm-x86 | |
parent | 570da318cf0e3053e62030253494c410a18d4be7 (diff) | |
download | blackbird-op-linux-ac23d4ee3f84de33c16ed7e68f9adee2386e74fb.tar.gz blackbird-op-linux-ac23d4ee3f84de33c16ed7e68f9adee2386e74fb.zip |
x86: support for new UV apic
UV supports really big systems. So big, in fact, that the APICID register
does not contain enough bits to contain an APICID that is unique across all
cpus.
The UV BIOS supports 3 APICID modes:
- legacy mode. This mode uses the old APIC mode where
APICID is in bits [31:24] of the APICID register.
- x2apic mode. This mode is whitebox-compatible. APICIDs
are unique across all cpus. Standard x2apic APIC operations
(Intel-defined) can be used for IPIs. The node identifier
fits within the Intel-defined portion of the APICID register.
- x2apic-uv mode. In this mode, the APICIDs on each node have
unique IDs, but IDs on different node are not unique. For example,
if each mode has 32 cpus, the APICIDs on each node might be
0 - 31. Every node has the same set of IDs.
The UV hub is used to route IPIs/interrupts to the correct node.
Traditional APIC operations WILL NOT WORK.
In x2apic-uv mode, the ACPI tables all contain a full unique ID (note:
exact bit layout still changing but the following is close):
nnnnnnnnnnlc0cch
n = unique node number
l = socket number on board
c = core
h = hyperthread
Only the "lc0cch" bits are written to the APICID register. The remaining bits are
supplied by having the get_apic_id() function "OR" the extra bits into the value
read from the APICID register. (Hmmm.. why not keep the ENTIRE APICID register
in per-cpu data....)
The x2apic-uv mode is recognized by the MADT table containing:
oem_id = "SGI"
oem_table_id = "UV-X"
Signed-off-by: Jack Steiner <steiner@sgi.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include/asm-x86')
-rw-r--r-- | include/asm-x86/genapic_64.h | 5 | ||||
-rw-r--r-- | include/asm-x86/smp.h | 5 |
2 files changed, 10 insertions, 0 deletions
diff --git a/include/asm-x86/genapic_64.h b/include/asm-x86/genapic_64.h index 914815c28ae5..1de931b263ce 100644 --- a/include/asm-x86/genapic_64.h +++ b/include/asm-x86/genapic_64.h @@ -39,4 +39,9 @@ enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC}; extern enum uv_system_type get_uv_system_type(void); extern int is_uv_system(void); +extern struct genapic apic_x2apic_uv_x; +DECLARE_PER_CPU(int, x2apic_extra_bits); +extern void uv_cpu_init(void); +extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip); + #endif diff --git a/include/asm-x86/smp.h b/include/asm-x86/smp.h index c0d693ca4357..b35566264879 100644 --- a/include/asm-x86/smp.h +++ b/include/asm-x86/smp.h @@ -174,10 +174,15 @@ static inline int logical_smp_processor_id(void) return GET_APIC_LOGICAL_ID(*(u32 *)(APIC_BASE + APIC_LDR)); } +#ifdef CONFIG_X86_32_SMP static inline unsigned int read_apic_id(void) { return *(u32 *)(APIC_BASE + APIC_ID); } +#else +extern unsigned int read_apic_id(void); +#endif + # ifdef APIC_DEFINITION extern int hard_smp_processor_id(void); |