@@ -91,6 +91,43 @@
smp_add_mpc_entry(mc, sizeof(*mpc));
}
+void smp_scan_for_apics(struct mp_config_table *mc, struct device *parent, int boot_apic_id, unsigned apic_version, unsigned cpu_features, unsigned cpu_feature_flags)
+{
+ int p_it;
+ int c_it;
+ struct device *child;
+
+ // Scan the root node for APIC clusters and APICs
+ for(p_it=0;p_it<(parent->links);p_it++) {
+ for(c_it=0;c_it<(parent->links);c_it++) {
+ for (child=parent->link[c_it].children; child; child=child->sibling) {
+ // Is this an APIC?
+ if (child->path.type == DEVICE_PATH_APIC) {
+ // Found an APIC, add it to the MP table
+ if (child->enabled) {
+ unsigned long cpu_flag;
+ cpu_flag = MPC_CPU_ENABLED;
+ if (boot_apic_id == child->path.apic.apic_id) {
+ cpu_flag = MPC_CPU_ENABLED | MPC_CPU_BOOTPROCESSOR;
+ }
+ smp_write_processor(mc,
+ child->path.apic.apic_id, apic_version,
+ cpu_flag, cpu_features, cpu_feature_flags
+ );
+ }
+ }
+
+ // Or an APIC cluster?
+ if (child->path.type == DEVICE_PATH_APIC_CLUSTER) {
+ // Found an APIC cluster, scan it for APICs
+ smp_scan_for_apics(mc, child, boot_apic_id, apic_version,
+ cpu_features, cpu_feature_flags);
+ }
+ }
+ }
+ }
+}
+
/* If we assume a symmetric processor configuration we can
* get all of the information we need to write the processor
* entry from the bootstrap processor.
@@ -105,32 +142,16 @@
unsigned cpu_features;
unsigned cpu_feature_flags;
struct cpuid_result result;
- device_t cpu;
+ //device_t cpu;
boot_apic_id = lapicid();
apic_version = lapic_read(LAPIC_LVR) & 0xff;
result = cpuid(1);
cpu_features = result.eax;
cpu_feature_flags = result.edx;
- for(cpu = all_devices; cpu; cpu = cpu->next) {
- unsigned long cpu_flag;
- if ((cpu->path.type != DEVICE_PATH_APIC) ||
- (cpu->bus->dev->path.type != DEVICE_PATH_APIC_CLUSTER))
- {
- continue;
- }
- if (!cpu->enabled) {
- continue;
- }
- cpu_flag = MPC_CPU_ENABLED;
- if (boot_apic_id == cpu->path.apic.apic_id) {
- cpu_flag = MPC_CPU_ENABLED | MPC_CPU_BOOTPROCESSOR;
- }
- smp_write_processor(mc,
- cpu->path.apic.apic_id, apic_version,
- cpu_flag, cpu_features, cpu_feature_flags
- );
- }
+
+ // Scan the root node for APIC clusters and APICs
+ smp_scan_for_apics(mc, all_devices, boot_apic_id, apic_version, cpu_features, cpu_feature_flags);
}
void smp_write_bus(struct mp_config_table *mc,
@@ -179,7 +200,7 @@
#ifdef DEBUG_MPTABLE
printk_debug("add intsrc srcbus 0x%x srcbusirq 0x%x, dstapic 0x%x, dstirq 0x%x\n",
srcbus, srcbusirq, dstapic, dstirq);
- hexdump(__func__, mpc, sizeof(*mpc));
+// hexdump(__func__, mpc, sizeof(*mpc));
#endif
}
Here is a cleaned up and tested version of the SMP APIC autodetect patch. Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> --- It would of course be helpful to attach the patch. My Webmail client keeps eating it... Timothy Pearson Raptor Engineering