Xv6 with picoc & Linkage editor  v1.0
The project delineate mutual cohesion between c library, linkage editor ( linker), interpreter and operating system by porting the same on xv6 kernel
mp.c
00001 // Multiprocessor support
00002 // Search memory for MP description structures.
00003 // http://developer.intel.com/design/pentium/datashts/24201606.pdf
00004 
00005 #include "types.h"
00006 #include "defs.h"
00007 #include "param.h"
00008 #include "memlayout.h"
00009 #include "mp.h"
00010 #include "x86.h"
00011 #include "mmu.h"
00012 #include "proc.h"
00013 
00014 struct cpu cpus[NCPU];
00015 static struct cpu *bcpu;
00016 int ismp;
00017 int ncpu;
00018 uchar ioapicid;
00019 
00020 int
00021 mpbcpu(void)
00022 {
00023   return bcpu-cpus;
00024 }
00025 
00026 static uchar
00027 sum(uchar *addr, int len)
00028 {
00029   int i, sum;
00030   
00031   sum = 0;
00032   for(i=0; i<len; i++)
00033     sum += addr[i];
00034   return sum;
00035 }
00036 
00037 // Look for an MP structure in the len bytes at addr.
00038 static struct mp*
00039 mpsearch1(uint a, int len)
00040 {
00041   uchar *e, *p, *addr;
00042 
00043   addr = p2v(a);
00044   e = addr+len;
00045   for(p = addr; p < e; p += sizeof(struct mp))
00046     if(memcmp(p, "_MP_", 4) == 0 && sum(p, sizeof(struct mp)) == 0)
00047       return (struct mp*)p;
00048   return 0;
00049 }
00050 
00051 // Search for the MP Floating Pointer Structure, which according to the
00052 // spec is in one of the following three locations:
00053 // 1) in the first KB of the EBDA;
00054 // 2) in the last KB of system base memory;
00055 // 3) in the BIOS ROM between 0xE0000 and 0xFFFFF.
00056 static struct mp*
00057 mpsearch(void)
00058 {
00059   uchar *bda;
00060   uint p;
00061   struct mp *mp;
00062 
00063   bda = (uchar *) P2V(0x400);
00064   if((p = ((bda[0x0F]<<8)| bda[0x0E]) << 4)){
00065     if((mp = mpsearch1(p, 1024)))
00066       return mp;
00067   } else {
00068     p = ((bda[0x14]<<8)|bda[0x13])*1024;
00069     if((mp = mpsearch1(p-1024, 1024)))
00070       return mp;
00071   }
00072   return mpsearch1(0xF0000, 0x10000);
00073 }
00074 
00075 // Search for an MP configuration table.  For now,
00076 // don't accept the default configurations (physaddr == 0).
00077 // Check for correct signature, calculate the checksum and,
00078 // if correct, check the version.
00079 // To do: check extended table checksum.
00080 static struct mpconf*
00081 mpconfig(struct mp **pmp)
00082 {
00083   struct mpconf *conf;
00084   struct mp *mp;
00085 
00086   if((mp = mpsearch()) == 0 || mp->physaddr == 0)
00087     return 0;
00088   conf = (struct mpconf*) p2v((uint) mp->physaddr);
00089   if(memcmp(conf, "PCMP", 4) != 0)
00090     return 0;
00091   if(conf->version != 1 && conf->version != 4)
00092     return 0;
00093   if(sum((uchar*)conf, conf->length) != 0)
00094     return 0;
00095   *pmp = mp;
00096   return conf;
00097 }
00098 
00099 void
00100 mpinit(void)
00101 {
00102   uchar *p, *e;
00103   struct mp *mp;
00104   struct mpconf *conf;
00105   struct mpproc *proc;
00106   struct mpioapic *ioapic;
00107 
00108   bcpu = &cpus[0];
00109   if((conf = mpconfig(&mp)) == 0)
00110     return;
00111   ismp = 1;
00112   lapic = (uint*)conf->lapicaddr;
00113   for(p=(uchar*)(conf+1), e=(uchar*)conf+conf->length; p<e; ){
00114     switch(*p){
00115     case MPPROC:
00116       proc = (struct mpproc*)p;
00117       if(ncpu != proc->apicid){
00118         cprintf("mpinit: ncpu=%d apicid=%d\n", ncpu, proc->apicid);
00119         ismp = 0;
00120       }
00121       if(proc->flags & MPBOOT)
00122         bcpu = &cpus[ncpu];
00123       cpus[ncpu].id = ncpu;
00124       ncpu++;
00125       p += sizeof(struct mpproc);
00126       continue;
00127     case MPIOAPIC:
00128       ioapic = (struct mpioapic*)p;
00129       ioapicid = ioapic->apicno;
00130       p += sizeof(struct mpioapic);
00131       continue;
00132     case MPBUS:
00133     case MPIOINTR:
00134     case MPLINTR:
00135       p += 8;
00136       continue;
00137     default:
00138       cprintf("mpinit: unknown config type %x\n", *p);
00139       ismp = 0;
00140     }
00141   }
00142   if(!ismp){
00143     // Didn't like what we found; fall back to no MP.
00144     ncpu = 1;
00145     lapic = 0;
00146     ioapicid = 0;
00147     return;
00148   }
00149 
00150   if(mp->imcrp){
00151     // Bochs doesn't support IMCR, so this doesn't run on Bochs.
00152     // But it would on real hardware.
00153     outb(0x22, 0x70);   // Select IMCR
00154     outb(0x23, inb(0x23) | 1);  // Mask external interrupts.
00155   }
00156 }
 All Data Structures