diff options
author | Robert Morris <[email protected]> | 2019-06-05 11:42:03 -0400 |
---|---|---|
committer | Robert Morris <[email protected]> | 2019-06-05 11:42:03 -0400 |
commit | f1a727b971a59bab6025b4c4111342c27356ca40 (patch) | |
tree | d22d52c613bfc003e6fb75b5d137aeff9d954201 /mp.c | |
parent | ec3d3a1fceee437c640f9c5c05fc517edfb1899e (diff) | |
download | xv6-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.c | 139 |
1 files changed, 0 insertions, 139 deletions
@@ -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. - } -} |