Minor SMP fixes. Fix to linuxpci to catch buggy chipsets
This commit is contained in:
parent
350fa4e519
commit
ce6c4c7195
7 changed files with 70 additions and 19 deletions
|
|
@ -238,7 +238,8 @@ void smp_write_processor(struct mp_config_table *mc,
|
|||
unsigned char apicid, unsigned char apicver,
|
||||
unsigned char cpuflag, unsigned int cpufeature,
|
||||
unsigned int featureflag);
|
||||
void smp_write_processors(struct mp_config_table *mc);
|
||||
void smp_write_processors(struct mp_config_table *mc,
|
||||
unsigned long *processor_map);
|
||||
void smp_write_bus(struct mp_config_table *mc,
|
||||
unsigned char id, unsigned char *bustype);
|
||||
void smp_write_ioapic(struct mp_config_table *mc,
|
||||
|
|
@ -264,7 +265,7 @@ void smp_write_compatibility_address_space(struct mp_config_table *mc,
|
|||
unsigned int range_list);
|
||||
unsigned char smp_compute_checksum(void *v, int len);
|
||||
void smp_write_floating_table(void *v);
|
||||
void write_smp_table(void *v);
|
||||
void write_smp_table(void *v, unsigned long *processor_map);
|
||||
|
||||
|
||||
#else /* HAVE_MP_TABLE */
|
||||
|
|
|
|||
|
|
@ -109,10 +109,12 @@ void secondary_cpu_init(void)
|
|||
unsigned long totalram;
|
||||
int processor_id;
|
||||
|
||||
printk_spew(__FUNCTION__ "\n");
|
||||
atomic_inc(&active_cpus);
|
||||
totalram = get_ramsize();
|
||||
processor_id = cpu_initialize(totalram);
|
||||
atomic_dec(&active_cpus);
|
||||
printk_spew(__FUNCTION__ " id is %d\n", processor_id);
|
||||
stop_cpu(processor_id);
|
||||
}
|
||||
|
||||
|
|
@ -135,6 +137,18 @@ static void wait_for_other_cpus(void)
|
|||
|
||||
void hardwaremain(int boot_complete)
|
||||
{
|
||||
// The processor map.
|
||||
// Now that SMP is in linuxbios, and Linux counts on us
|
||||
// giving accurate information about processors, we need a map
|
||||
// of what processors are out there. This could be a bit mask,
|
||||
// but we will be optimistic and hope we someday run on
|
||||
// REALLY BIG SMPs. Also we may need more than one bit of
|
||||
// info per processor at some point. I hope we don't need
|
||||
// anything more complex than an int.
|
||||
unsigned long processor_map[MAX_CPUS];
|
||||
// Processor ID of the BOOT cpu (i.e. the one running this code
|
||||
int boot_cpu;
|
||||
|
||||
// Comment: the NEW_SUPERIO architecture is actually pretty good.
|
||||
// I think we need to move to the same sort of architecture for
|
||||
// everything: A config file generated sequence of calls
|
||||
|
|
@ -189,12 +203,14 @@ void hardwaremain(int boot_complete)
|
|||
printk_info("totalram: %ldM\n", totalram/1024);
|
||||
|
||||
/* Fully initialize the cpu before configuring the bus */
|
||||
cpu_initialize(totalram);
|
||||
boot_cpu = cpu_initialize(totalram);
|
||||
printk_spew("BOOT CPU is %d\n", boot_cpu);
|
||||
processor_map[boot_cpu] = CPU_BOOTPROCESSOR|CPU_ENABLED;
|
||||
|
||||
/* Now start the other cpus initializing
|
||||
* The sooner they start the sooner they stop.
|
||||
*/
|
||||
startup_other_cpus();
|
||||
startup_other_cpus(processor_map);
|
||||
|
||||
// Now do the real bus
|
||||
// we round the total ram up a lot for thing like the SISFB, which
|
||||
|
|
@ -233,7 +249,7 @@ void hardwaremain(int boot_complete)
|
|||
pci_zero_irq_settings();
|
||||
|
||||
/* copy the smp block to address 0 */
|
||||
write_smp_table((void *)16);
|
||||
write_smp_table((void *)16, processor_map);
|
||||
post_code(0x96);
|
||||
|
||||
check_pirq_routing_table();
|
||||
|
|
|
|||
|
|
@ -90,7 +90,8 @@ void smp_write_processor(struct mp_config_table *mc,
|
|||
* Having the proper apicid's in the table so the non-bootstrap
|
||||
* processors can be woken up should be enough.
|
||||
*/
|
||||
void smp_write_processors(struct mp_config_table *mc)
|
||||
void smp_write_processors(struct mp_config_table *mc,
|
||||
unsigned long *processor_map)
|
||||
{
|
||||
int i;
|
||||
int processor_id;
|
||||
|
|
@ -105,7 +106,7 @@ void smp_write_processors(struct mp_config_table *mc)
|
|||
cpu_feature_flags = edx;
|
||||
for(i = 0; i < MAX_CPUS; i++) {
|
||||
smp_write_processor(mc, i, apic_version,
|
||||
((processor_id == i)? CPU_BOOTPROCESSOR:0) | CPU_ENABLED,
|
||||
processor_map[i],
|
||||
cpu_features, cpu_feature_flags
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include <smp/start_stop.h>
|
||||
#include <arch/smp/mpspec.h>
|
||||
#include <cpu/p6/apic.h>
|
||||
#include <delay.h>
|
||||
|
||||
|
|
@ -57,7 +58,10 @@ void stop_cpu(int apicid)
|
|||
|
||||
}
|
||||
|
||||
void start_cpu(int apicid)
|
||||
// This is a lot more paranoid now, since Linux can NOT handle
|
||||
// being told there is a CPU when none exists. So any errors
|
||||
// will return 0, meaning no CPU.
|
||||
int start_cpu(int apicid)
|
||||
{
|
||||
int timeout;
|
||||
unsigned long send_status, accept_status, start_eip;
|
||||
|
|
@ -87,7 +91,10 @@ void start_cpu(int apicid)
|
|||
send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
|
||||
} while (send_status && (timeout++ < 1000));
|
||||
if (timeout >= 1000) {
|
||||
printk_spew("timed out\n");
|
||||
printk_err("CPU %d: First apic write timed out. Disabling\n",
|
||||
apicid);
|
||||
// too bad.
|
||||
return 0;
|
||||
}
|
||||
|
||||
mdelay(10);
|
||||
|
|
@ -108,7 +115,10 @@ void start_cpu(int apicid)
|
|||
send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
|
||||
} while (send_status && (timeout++ < 1000));
|
||||
if (timeout >= 1000) {
|
||||
printk_spew("timed out\n");
|
||||
printk_err("CPU %d: Second apic write timed out. Disabling\n",
|
||||
apicid);
|
||||
// too bad.
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME start_eip should be more flexible! */
|
||||
|
|
@ -178,9 +188,12 @@ void start_cpu(int apicid)
|
|||
printk_warning("APIC never delivered???\n");
|
||||
if (accept_status)
|
||||
printk_warning("APIC delivery error (%lx).\n", accept_status);
|
||||
if (send_status || accept_status)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void startup_other_cpus(void)
|
||||
void startup_other_cpus(unsigned long *processor_map)
|
||||
{
|
||||
int apicid = this_processors_id();
|
||||
int i;
|
||||
|
|
@ -189,6 +202,8 @@ void startup_other_cpus(void)
|
|||
if (i == apicid ) {
|
||||
continue;
|
||||
}
|
||||
start_cpu(i);
|
||||
if (start_cpu(i))
|
||||
processor_map[i] = CPU_ENABLED;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue