diff options
Diffstat (limited to 'arch/x86/kernel/mpparse.c')
-rw-r--r-- | arch/x86/kernel/mpparse.c | 73 |
1 files changed, 70 insertions, 3 deletions
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 7591325e616d..1cc7a4b8643f 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c | |||
@@ -49,15 +49,73 @@ static int __init mpf_checksum(unsigned char *mp, int len) | |||
49 | } | 49 | } |
50 | 50 | ||
51 | #ifdef CONFIG_X86_NUMAQ | 51 | #ifdef CONFIG_X86_NUMAQ |
52 | int found_numaq; | ||
52 | /* | 53 | /* |
53 | * Have to match translation table entries to main table entries by counter | 54 | * Have to match translation table entries to main table entries by counter |
54 | * hence the mpc_record variable .... can't see a less disgusting way of | 55 | * hence the mpc_record variable .... can't see a less disgusting way of |
55 | * doing this .... | 56 | * doing this .... |
56 | */ | 57 | */ |
58 | struct mpc_config_translation { | ||
59 | unsigned char mpc_type; | ||
60 | unsigned char trans_len; | ||
61 | unsigned char trans_type; | ||
62 | unsigned char trans_quad; | ||
63 | unsigned char trans_global; | ||
64 | unsigned char trans_local; | ||
65 | unsigned short trans_reserved; | ||
66 | }; | ||
67 | |||
57 | 68 | ||
58 | static int mpc_record; | 69 | static int mpc_record; |
59 | static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] | 70 | static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] |
60 | __cpuinitdata; | 71 | __cpuinitdata; |
72 | |||
73 | static inline int generate_logical_apicid(int quad, int phys_apicid) | ||
74 | { | ||
75 | return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1); | ||
76 | } | ||
77 | |||
78 | |||
79 | static inline int mpc_apic_id(struct mpc_config_processor *m, | ||
80 | struct mpc_config_translation *translation_record) | ||
81 | { | ||
82 | int quad = translation_record->trans_quad; | ||
83 | int logical_apicid = generate_logical_apicid(quad, m->mpc_apicid); | ||
84 | |||
85 | printk(KERN_DEBUG "Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n", | ||
86 | m->mpc_apicid, | ||
87 | (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, | ||
88 | (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, | ||
89 | m->mpc_apicver, quad, logical_apicid); | ||
90 | return logical_apicid; | ||
91 | } | ||
92 | |||
93 | int mp_bus_id_to_node[MAX_MP_BUSSES]; | ||
94 | |||
95 | int mp_bus_id_to_local[MAX_MP_BUSSES]; | ||
96 | |||
97 | static void mpc_oem_bus_info(struct mpc_config_bus *m, char *name, | ||
98 | struct mpc_config_translation *translation) | ||
99 | { | ||
100 | int quad = translation->trans_quad; | ||
101 | int local = translation->trans_local; | ||
102 | |||
103 | mp_bus_id_to_node[m->mpc_busid] = quad; | ||
104 | mp_bus_id_to_local[m->mpc_busid] = local; | ||
105 | printk(KERN_INFO "Bus #%d is %s (node %d)\n", | ||
106 | m->mpc_busid, name, quad); | ||
107 | } | ||
108 | |||
109 | int quad_local_to_mp_bus_id [NR_CPUS/4][4]; | ||
110 | static void mpc_oem_pci_bus(struct mpc_config_bus *m, | ||
111 | struct mpc_config_translation *translation) | ||
112 | { | ||
113 | int quad = translation->trans_quad; | ||
114 | int local = translation->trans_local; | ||
115 | |||
116 | quad_local_to_mp_bus_id[quad][local] = m->mpc_busid; | ||
117 | } | ||
118 | |||
61 | #endif | 119 | #endif |
62 | 120 | ||
63 | static void __cpuinit MP_processor_info(struct mpc_config_processor *m) | 121 | static void __cpuinit MP_processor_info(struct mpc_config_processor *m) |
@@ -321,11 +379,11 @@ static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable, | |||
321 | } | 379 | } |
322 | } | 380 | } |
323 | 381 | ||
324 | static inline void mps_oem_check(struct mp_config_table *mpc, char *oem, | 382 | void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem, |
325 | char *productid) | 383 | char *productid) |
326 | { | 384 | { |
327 | if (strncmp(oem, "IBM NUMA", 8)) | 385 | if (strncmp(oem, "IBM NUMA", 8)) |
328 | printk("Warning! May not be a NUMA-Q system!\n"); | 386 | printk("Warning! Not a NUMA-Q system!\n"); |
329 | else | 387 | else |
330 | found_numaq = 1; | 388 | found_numaq = 1; |
331 | 389 | ||
@@ -388,7 +446,16 @@ static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early) | |||
388 | return 0; | 446 | return 0; |
389 | 447 | ||
390 | #ifdef CONFIG_X86_32 | 448 | #ifdef CONFIG_X86_32 |
391 | mps_oem_check(mpc, oem, str); | 449 | /* |
450 | * need to make sure summit and es7000's mps_oem_check is safe to be | ||
451 | * called early via genericarch 's mps_oem_check | ||
452 | */ | ||
453 | if (early) { | ||
454 | #ifdef CONFIG_X86_NUMAQ | ||
455 | numaq_mps_oem_check(mpc, oem, str); | ||
456 | #endif | ||
457 | } else | ||
458 | mps_oem_check(mpc, oem, str); | ||
392 | #endif | 459 | #endif |
393 | 460 | ||
394 | /* save the local APIC address, it might be non-default */ | 461 | /* save the local APIC address, it might be non-default */ |