patch-1.3.78 linux/arch/i386/kernel/smp.c
Next file: linux/arch/i386/mm/init.c
Previous file: linux/arch/i386/kernel/entry.S
Back to the patch index
Back to the overall index
- Lines: 264
- Date:
Mon Mar 25 08:58:20 1996
- Orig file:
v1.3.77/linux/arch/i386/kernel/smp.c
- Orig date:
Wed Mar 20 10:59:54 1996
diff -u --recursive --new-file v1.3.77/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
@@ -51,14 +51,14 @@
int smp_found_config=0; /* Have we found an SMP box */
unsigned long cpu_present_map = 0; /* Bitmask of existing CPU's */
-int smp_num_cpus; /* Total count of live CPU's */
+int smp_num_cpus = 1; /* Total count of live CPU's */
int smp_threads_ready=0; /* Set when the idlers are all forked */
volatile int cpu_number_map[NR_CPUS]; /* which CPU maps to which logical number */
+volatile int cpu_logical_map[NR_CPUS]; /* which logical number maps to which CPU */
volatile unsigned long cpu_callin_map[NR_CPUS] = {0,}; /* We always use 0 the rest is ready for parallel delivery */
volatile unsigned long smp_invalidate_needed; /* Used for the invalidate map thats also checked in the spinlock */
struct cpuinfo_x86 cpu_data[NR_CPUS]; /* Per cpu bogomips and other parameters */
static unsigned int num_processors = 1; /* Internal processor count */
-int smp_top_cpu = 0; /* Highest used APIC id */
static unsigned long io_apic_addr = 0xFEC00000; /* Address of the I/O apic (not yet used) */
unsigned char boot_cpu_id = 0; /* Processor that is doing the boot up */
static unsigned char *kstack_base,*kstack_end; /* Kernel stack list pointers */
@@ -220,7 +220,6 @@
{
SMP_PRINTK((" Bootup CPU\n"));
boot_cpu_id=m->mpc_apicid;
- nlong = boot_cpu_id<<24; /* Dummy 'self' for bootup */
}
else /* Boot CPU already counted */
num_processors++;
@@ -294,7 +293,7 @@
* Scan the memory blocks for an SMP configuration block.
*/
-void smp_scan_config(unsigned long base, unsigned long length)
+int smp_scan_config(unsigned long base, unsigned long length)
{
unsigned long *bp=(unsigned long *)base;
struct intel_mp_floating *mpf;
@@ -325,54 +324,18 @@
*/
if(mpf->mpf_feature1!=0)
{
- num_processors=2;
- printk("I/O APIC at 0xFEC00000.\n");
- printk("Bus#0 is ");
- }
- switch(mpf->mpf_feature1)
- {
- case 1:
- case 5:
- printk("ISA\n");
- break;
- case 2:
- printk("EISA with no IRQ8 chaining\n");
- break;
- case 6:
- case 3:
- printk("EISA\n");
- break;
- case 4:
- case 7:
- printk("MCA\n");
- break;
- case 0:
- break;
- default:
- printk("???\nUnknown standard configuration %d\n",
- mpf->mpf_feature1);
- return;
- }
- if(mpf->mpf_feature1>4)
- printk("Bus #1 is PCI\n");
- /*
- * Read the physical hardware table.
- */
- if(mpf->mpf_physptr)
- smp_read_mpc((void *)mpf->mpf_physptr);
- else
- {
unsigned long cfg;
/*
- * If no table present, determine
- * what the CPU mapping is.
+ * We need to know what the local
+ * APIC id of the boot CPU is!
*/
/*
*
* HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK
*
+ * It's not just a crazy hack... ;-)
*/
/*
* Standard page mapping
@@ -386,7 +349,6 @@
local_invalidate();
boot_cpu_id = GET_APIC_ID(*((volatile unsigned long *) APIC_ID));
- nlong = boot_cpu_id<<24; /* Dummy 'self' for bootup */
/*
* Give it back
@@ -400,26 +362,79 @@
* END OF HACK END OF HACK END OF HACK END OF HACK END OF HACK
*
*/
+ /*
+ * 2 CPUs, numbered 0 & 1.
+ */
+ cpu_present_map=3;
+ num_processors=2;
+ printk("I/O APIC at 0xFEC00000.\n");
+ printk("Bus#0 is ");
+ }
+ switch(mpf->mpf_feature1)
+ {
+ case 1:
+ case 5:
+ printk("ISA\n");
+ break;
+ case 2:
+ printk("EISA with no IRQ8 chaining\n");
+ break;
+ case 6:
+ case 3:
+ printk("EISA\n");
+ break;
+ case 4:
+ case 7:
+ printk("MCA\n");
+ break;
+ case 0:
+ break;
+ default:
+ printk("???\nUnknown standard configuration %d\n",
+ mpf->mpf_feature1);
+ return 1;
+ }
+ if(mpf->mpf_feature1>4)
+ {
+ printk("Bus #1 is PCI\n");
/*
- * If boot CPU != 0, other CPU
- * is 0, else other CPU is 1.
+ * Set local APIC version to
+ * the integrated form.
+ * It's initialized to zero
+ * otherwise, representing
+ * a discrete 82489DX.
*/
- if (boot_cpu_id)
- cpu_present_map=1 | (1 << boot_cpu_id);
- else
- cpu_present_map=3;
+ apic_version[0] = 0x10;
+ apic_version[1] = 0x10;
}
+ /*
+ * Read the physical hardware table.
+ * Anything here will override the
+ * defaults.
+ */
+ if(mpf->mpf_physptr)
+ smp_read_mpc((void *)mpf->mpf_physptr);
+
+ /*
+ * Now that the boot CPU id is known,
+ * set some other information about it.
+ */
+ nlong = boot_cpu_id<<24; /* Dummy 'self' for bootup */
+ cpu_logical_map[0] = boot_cpu_id;
+
printk("Processors: %d\n", num_processors);
/*
- * Only use the first one found.
+ * Only use the first configuration found.
*/
- return;
+ return 1;
}
}
bp+=4;
length-=16;
}
+
+ return 0;
}
/*
@@ -565,7 +580,7 @@
void smp_boot_cpus(void)
{
- int i,j;
+ int i;
int cpucount=0;
unsigned long cfg;
void *stack;
@@ -667,15 +682,12 @@
* Don't even attempt to start the boot CPU!
*/
if (i == boot_cpu_id)
- {
- smp_top_cpu=max(smp_top_cpu,i);
continue;
- }
if (cpu_present_map & (1 << i))
{
unsigned long send_status, accept_status;
- int timeout, num_starts;
+ int timeout, num_starts, j;
/*
* We need a kernel stack for each processor.
@@ -719,8 +731,11 @@
* Be paranoid about clearing APIC errors.
*/
- apic_write(APIC_ESR, 0);
- accept_status = (apic_read(APIC_ESR) & 0xEF);
+ if ( apic_version[i] & 0xF0 )
+ {
+ apic_write(APIC_ESR, 0);
+ accept_status = (apic_read(APIC_ESR) & 0xEF);
+ }
/*
* Status is now clean
@@ -777,8 +792,8 @@
* Run STARTUP IPI loop.
*/
- for (j = 0; !(send_status || accept_status)
- && (j < num_starts) ; j++)
+ for (j = 1; !(send_status || accept_status)
+ && (j <= num_starts) ; j++)
{
SMP_PRINTK(("Sending STARTUP #%d.\n",j));
@@ -826,8 +841,7 @@
cpucount++;
/* number CPUs logically, starting from 1 (BSP is 0) */
cpu_number_map[i] = cpucount;
- smp_top_cpu=max(smp_top_cpu,i);
-
+ cpu_logical_map[cpucount] = i;
}
else
{
@@ -951,10 +965,12 @@
/*
* Sanity check we don't re-enter this across CPU's. Only the kernel
* lock holder may send messages. For a STOP_CPU we are bringing the
- * entire box to the fastest halt we can..
+ * entire box to the fastest halt we can.. A reschedule carries
+ * no data and can occur during an invalidate.. guess what panic
+ * I got to notice this bug...
*/
- if(message_cpu!=NO_PROC_ID && msg!=MSG_STOP_CPU)
+ if(message_cpu!=NO_PROC_ID && msg!=MSG_STOP_CPU && msg!=MSG_RESCHEDULE)
{
panic("CPU #%d: Message pass %d but pass in progress by %d of %d\n",
smp_processor_id(),msg,message_cpu, smp_msg_id);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this