aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/mpparse.c
diff options
context:
space:
mode:
authorYinghai Lu <yhlu.kernel@gmail.com>2008-07-19 21:01:16 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-20 03:25:52 -0400
commit64898a8bad8c94ad7a4bd5cc86b66edfbb081f4a (patch)
tree013c56a97a533c0843d28d838bc94e6de3da9e2c /arch/x86/kernel/mpparse.c
parent3c9cb6de1e5ad37d1558fdb0d9d2bed5a7bac0d9 (diff)
x86: extend and use x86_quirks to clean up NUMAQ code
add these new x86_quirks methods: int *mpc_record; int (*mpc_apic_id)(struct mpc_config_processor *m); void (*mpc_oem_bus_info)(struct mpc_config_bus *m, char *name); void (*mpc_oem_pci_bus)(struct mpc_config_bus *m); void (*smp_read_mpc_oem)(struct mp_config_oemtable *oemtable, unsigned short oemsize); ... and move NUMAQ related mps table handling to numaq_32.c. also move the call to smp_read_mpc_oem() to smp_read_mpc() directly. Should not change functionality, albeit it would be nice to get it tested on real NUMAQ as well ... Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/mpparse.c')
-rw-r--r--arch/x86/kernel/mpparse.c191
1 files changed, 21 insertions, 170 deletions
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index 3cbd2df3abe4..6ae005ccaed8 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -49,76 +49,6 @@ static int __init mpf_checksum(unsigned char *mp, int len)
49 return sum & 0xFF; 49 return sum & 0xFF;
50} 50}
51 51
52#ifdef CONFIG_X86_NUMAQ
53int found_numaq;
54/*
55 * Have to match translation table entries to main table entries by counter
56 * hence the mpc_record variable .... can't see a less disgusting way of
57 * doing this ....
58 */
59struct mpc_config_translation {
60 unsigned char mpc_type;
61 unsigned char trans_len;
62 unsigned char trans_type;
63 unsigned char trans_quad;
64 unsigned char trans_global;
65 unsigned char trans_local;
66 unsigned short trans_reserved;
67};
68
69
70static int mpc_record;
71static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY]
72 __cpuinitdata;
73
74static inline int generate_logical_apicid(int quad, int phys_apicid)
75{
76 return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1);
77}
78
79
80static inline int mpc_apic_id(struct mpc_config_processor *m,
81 struct mpc_config_translation *translation_record)
82{
83 int quad = translation_record->trans_quad;
84 int logical_apicid = generate_logical_apicid(quad, m->mpc_apicid);
85
86 printk(KERN_DEBUG "Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n",
87 m->mpc_apicid,
88 (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8,
89 (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
90 m->mpc_apicver, quad, logical_apicid);
91 return logical_apicid;
92}
93
94int mp_bus_id_to_node[MAX_MP_BUSSES];
95
96int mp_bus_id_to_local[MAX_MP_BUSSES];
97
98static void mpc_oem_bus_info(struct mpc_config_bus *m, char *name,
99 struct mpc_config_translation *translation)
100{
101 int quad = translation->trans_quad;
102 int local = translation->trans_local;
103
104 mp_bus_id_to_node[m->mpc_busid] = quad;
105 mp_bus_id_to_local[m->mpc_busid] = local;
106 printk(KERN_INFO "Bus #%d is %s (node %d)\n",
107 m->mpc_busid, name, quad);
108}
109
110int quad_local_to_mp_bus_id [NR_CPUS/4][4];
111static void mpc_oem_pci_bus(struct mpc_config_bus *m,
112 struct mpc_config_translation *translation)
113{
114 int quad = translation->trans_quad;
115 int local = translation->trans_local;
116
117 quad_local_to_mp_bus_id[quad][local] = m->mpc_busid;
118}
119
120#endif
121
122static void __cpuinit MP_processor_info(struct mpc_config_processor *m) 52static void __cpuinit MP_processor_info(struct mpc_config_processor *m)
123{ 53{
124 int apicid; 54 int apicid;
@@ -128,14 +58,12 @@ static void __cpuinit MP_processor_info(struct mpc_config_processor *m)
128 disabled_cpus++; 58 disabled_cpus++;
129 return; 59 return;
130 } 60 }
131#ifdef CONFIG_X86_NUMAQ 61
132 if (found_numaq) 62 if (x86_quirks->mpc_apic_id)
133 apicid = mpc_apic_id(m, translation_table[mpc_record]); 63 apicid = x86_quirks->mpc_apic_id(m);
134 else 64 else
135 apicid = m->mpc_apicid; 65 apicid = m->mpc_apicid;
136#else 66
137 apicid = m->mpc_apicid;
138#endif
139 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { 67 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
140 bootup_cpu = " (Bootup-CPU)"; 68 bootup_cpu = " (Bootup-CPU)";
141 boot_cpu_physical_apicid = m->mpc_apicid; 69 boot_cpu_physical_apicid = m->mpc_apicid;
@@ -152,12 +80,10 @@ static void __init MP_bus_info(struct mpc_config_bus *m)
152 memcpy(str, m->mpc_bustype, 6); 80 memcpy(str, m->mpc_bustype, 6);
153 str[6] = 0; 81 str[6] = 0;
154 82
155#ifdef CONFIG_X86_NUMAQ 83 if (x86_quirks->mpc_oem_bus_info)
156 if (found_numaq) 84 x86_quirks->mpc_oem_bus_info(m, str);
157 mpc_oem_bus_info(m, str, translation_table[mpc_record]); 85 else
158#else 86 printk(KERN_INFO "Bus #%d is %s\n", m->mpc_busid, str);
159 printk(KERN_INFO "Bus #%d is %s\n", m->mpc_busid, str);
160#endif
161 87
162#if MAX_MP_BUSSES < 256 88#if MAX_MP_BUSSES < 256
163 if (m->mpc_busid >= MAX_MP_BUSSES) { 89 if (m->mpc_busid >= MAX_MP_BUSSES) {
@@ -174,10 +100,9 @@ static void __init MP_bus_info(struct mpc_config_bus *m)
174 mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; 100 mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
175#endif 101#endif
176 } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI) - 1) == 0) { 102 } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI) - 1) == 0) {
177#ifdef CONFIG_X86_NUMAQ 103 if (x86_quirks->mpc_oem_pci_bus)
178 if (found_numaq) 104 x86_quirks->mpc_oem_pci_bus(m);
179 mpc_oem_pci_bus(m, translation_table[mpc_record]); 105
180#endif
181 clear_bit(m->mpc_busid, mp_bus_not_pci); 106 clear_bit(m->mpc_busid, mp_bus_not_pci);
182#if defined(CONFIG_EISA) || defined (CONFIG_MCA) 107#if defined(CONFIG_EISA) || defined (CONFIG_MCA)
183 mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI; 108 mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI;
@@ -317,83 +242,6 @@ static void __init MP_lintsrc_info(struct mpc_config_lintsrc *m)
317 m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint); 242 m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint);
318} 243}
319 244
320#ifdef CONFIG_X86_NUMAQ
321static void __init MP_translation_info(struct mpc_config_translation *m)
322{
323 printk(KERN_INFO
324 "Translation: record %d, type %d, quad %d, global %d, local %d\n",
325 mpc_record, m->trans_type, m->trans_quad, m->trans_global,
326 m->trans_local);
327
328 if (mpc_record >= MAX_MPC_ENTRY)
329 printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n");
330 else
331 translation_table[mpc_record] = m; /* stash this for later */
332 if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad))
333 node_set_online(m->trans_quad);
334}
335
336/*
337 * Read/parse the MPC oem tables
338 */
339
340static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable,
341 unsigned short oemsize)
342{
343 int count = sizeof(*oemtable); /* the header size */
344 unsigned char *oemptr = ((unsigned char *)oemtable) + count;
345
346 mpc_record = 0;
347 printk(KERN_INFO "Found an OEM MPC table at %8p - parsing it ... \n",
348 oemtable);
349 if (memcmp(oemtable->oem_signature, MPC_OEM_SIGNATURE, 4)) {
350 printk(KERN_WARNING
351 "SMP mpc oemtable: bad signature [%c%c%c%c]!\n",
352 oemtable->oem_signature[0], oemtable->oem_signature[1],
353 oemtable->oem_signature[2], oemtable->oem_signature[3]);
354 return;
355 }
356 if (mpf_checksum((unsigned char *)oemtable, oemtable->oem_length)) {
357 printk(KERN_WARNING "SMP oem mptable: checksum error!\n");
358 return;
359 }
360 while (count < oemtable->oem_length) {
361 switch (*oemptr) {
362 case MP_TRANSLATION:
363 {
364 struct mpc_config_translation *m =
365 (struct mpc_config_translation *)oemptr;
366 MP_translation_info(m);
367 oemptr += sizeof(*m);
368 count += sizeof(*m);
369 ++mpc_record;
370 break;
371 }
372 default:
373 {
374 printk(KERN_WARNING
375 "Unrecognised OEM table entry type! - %d\n",
376 (int)*oemptr);
377 return;
378 }
379 }
380 }
381}
382
383void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem,
384 char *productid)
385{
386 if (strncmp(oem, "IBM NUMA", 8))
387 printk("Warning! Not a NUMA-Q system!\n");
388 else
389 found_numaq = 1;
390
391 if (mpc->mpc_oemptr)
392 smp_read_mpc_oem((struct mp_config_oemtable *)mpc->mpc_oemptr,
393 mpc->mpc_oemsize);
394}
395#endif /* CONFIG_X86_NUMAQ */
396
397/* 245/*
398 * Read/parse the MPC 246 * Read/parse the MPC
399 */ 247 */
@@ -458,7 +306,6 @@ static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early)
458 } else 306 } else
459 mps_oem_check(mpc, oem, str); 307 mps_oem_check(mpc, oem, str);
460#endif 308#endif
461
462 /* save the local APIC address, it might be non-default */ 309 /* save the local APIC address, it might be non-default */
463 if (!acpi_lapic) 310 if (!acpi_lapic)
464 mp_lapic_addr = mpc->mpc_lapic; 311 mp_lapic_addr = mpc->mpc_lapic;
@@ -466,12 +313,17 @@ static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early)
466 if (early) 313 if (early)
467 return 1; 314 return 1;
468 315
316 if (mpc->mpc_oemptr && x86_quirks->smp_read_mpc_oem) {
317 struct mp_config_oemtable *oem_table = (struct mp_config_oemtable *)(unsigned long)mpc->mpc_oemptr;
318 x86_quirks->smp_read_mpc_oem(oem_table, mpc->mpc_oemsize);
319 }
320
469 /* 321 /*
470 * Now process the configuration blocks. 322 * Now process the configuration blocks.
471 */ 323 */
472#ifdef CONFIG_X86_NUMAQ 324 if (x86_quirks->mpc_record)
473 mpc_record = 0; 325 *x86_quirks->mpc_record = 0;
474#endif 326
475 while (count < mpc->mpc_length) { 327 while (count < mpc->mpc_length) {
476 switch (*mpt) { 328 switch (*mpt) {
477 case MP_PROCESSOR: 329 case MP_PROCESSOR:
@@ -537,9 +389,8 @@ static int __init smp_read_mpc(struct mp_config_table *mpc, unsigned early)
537 count = mpc->mpc_length; 389 count = mpc->mpc_length;
538 break; 390 break;
539 } 391 }
540#ifdef CONFIG_X86_NUMAQ 392 if (x86_quirks->mpc_record)
541 ++mpc_record; 393 (*x86_quirks->mpc_record)++;
542#endif
543 } 394 }
544 395
545#ifdef CONFIG_X86_GENERICARCH 396#ifdef CONFIG_X86_GENERICARCH