summaryrefslogtreecommitdiff
path: root/mp.c
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2019-06-05 11:42:03 -0400
committerRobert Morris <[email protected]>2019-06-05 11:42:03 -0400
commitf1a727b971a59bab6025b4c4111342c27356ca40 (patch)
treed22d52c613bfc003e6fb75b5d137aeff9d954201 /mp.c
parentec3d3a1fceee437c640f9c5c05fc517edfb1899e (diff)
downloadxv6-labs-f1a727b971a59bab6025b4c4111342c27356ca40.tar.gz
xv6-labs-f1a727b971a59bab6025b4c4111342c27356ca40.tar.bz2
xv6-labs-f1a727b971a59bab6025b4c4111342c27356ca40.zip
start at support for multiple CPUs
Diffstat (limited to 'mp.c')
-rw-r--r--mp.c139
1 files changed, 0 insertions, 139 deletions
diff --git a/mp.c b/mp.c
deleted file mode 100644
index e36e45c..0000000
--- a/mp.c
+++ /dev/null
@@ -1,139 +0,0 @@
-// Multiprocessor support
-// Search memory for MP description structures.
-// http://developer.intel.com/design/pentium/datashts/24201606.pdf
-
-#include "types.h"
-#include "defs.h"
-#include "param.h"
-#include "memlayout.h"
-#include "mp.h"
-#include "x86.h"
-#include "mmu.h"
-#include "proc.h"
-
-struct cpu cpus[NCPU];
-int ncpu;
-uchar ioapicid;
-
-static uchar
-sum(uchar *addr, int len)
-{
- int i, sum;
-
- sum = 0;
- for(i=0; i<len; i++)
- sum += addr[i];
- return sum;
-}
-
-// Look for an MP structure in the len bytes at addr.
-static struct mp*
-mpsearch1(uint64 a, int len)
-{
- uchar *e, *p, *addr;
-
- addr = P2V(a);
- e = addr+len;
- for(p = addr; p < e; p += sizeof(struct mp))
- if(memcmp(p, "_MP_", 4) == 0 && sum(p, sizeof(struct mp)) == 0)
- return (struct mp*)p;
- return 0;
-}
-
-// Search for the MP Floating Pointer Structure, which according to the
-// spec is in one of the following three locations:
-// 1) in the first KB of the EBDA;
-// 2) in the last KB of system base memory;
-// 3) in the BIOS ROM between 0xE0000 and 0xFFFFF.
-static struct mp*
-mpsearch(void)
-{
- uchar *bda;
- uint p;
- struct mp *mp;
-
- bda = (uchar *) P2V(0x400);
- if((p = ((bda[0x0F]<<8)| bda[0x0E]) << 4)){
- if((mp = mpsearch1(p, 1024)))
- return mp;
- } else {
- p = ((bda[0x14]<<8)|bda[0x13])*1024;
- if((mp = mpsearch1(p-1024, 1024)))
- return mp;
- }
- return mpsearch1(0xF0000, 0x10000);
-}
-
-// Search for an MP configuration table. For now,
-// don't accept the default configurations (physaddr == 0).
-// Check for correct signature, calculate the checksum and,
-// if correct, check the version.
-// To do: check extended table checksum.
-static struct mpconf*
-mpconfig(struct mp **pmp)
-{
- struct mpconf *conf;
- struct mp *mp;
-
- if((mp = mpsearch()) == 0 || mp->physaddr == 0)
- return 0;
- conf = (struct mpconf*) P2V((uint64) mp->physaddr);
- if(memcmp(conf, "PCMP", 4) != 0)
- return 0;
- if(conf->version != 1 && conf->version != 4)
- return 0;
- if(sum((uchar*)conf, conf->length) != 0)
- return 0;
- *pmp = mp;
- return conf;
-}
-
-void
-mpinit(void)
-{
- uchar *p, *e;
- int ismp;
- struct mp *mp;
- struct mpconf *conf;
- struct mpproc *proc;
- struct mpioapic *ioapic;
-
- if((conf = mpconfig(&mp)) == 0)
- panic("Expect to run on an SMP");
- ismp = 1;
- lapic = P2V((uint64)conf->lapicaddr_p);
- for(p=(uchar*)(conf+1), e=(uchar*)conf+conf->length; p<e; ){
- switch(*p){
- case MPPROC:
- proc = (struct mpproc*)p;
- if(ncpu < NCPU) {
- cpus[ncpu].apicid = proc->apicid; // apicid may differ from ncpu
- ncpu++;
- }
- p += sizeof(struct mpproc);
- continue;
- case MPIOAPIC:
- ioapic = (struct mpioapic*)p;
- ioapicid = ioapic->apicno;
- p += sizeof(struct mpioapic);
- continue;
- case MPBUS:
- case MPIOINTR:
- case MPLINTR:
- p += 8;
- continue;
- default:
- ismp = 0;
- break;
- }
- }
- if(!ismp)
- panic("Didn't find a suitable machine");
-
- if(mp->imcrp){
- // Bochs doesn't support IMCR, so this doesn't run on Bochs.
- // But it would on real hardware.
- outb(0x22, 0x70); // Select IMCR
- outb(0x23, inb(0x23) | 1); // Mask external interrupts.
- }
-}