📄 mp.c
字号:
// Multiprocessor bootstrap.// 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 "mp.h"#include "x86.h"#include "mmu.h"#include "proc.h"struct cpu cpus[NCPU];static struct cpu *bcpu;int ismp;int ncpu;uchar ioapic_id;intmp_bcpu(void){ return bcpu-cpus;}static ucharsum(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*mp_search1(uchar *addr, int len){ uchar *e, *p; 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*mp_search(void){ uchar *bda; uint p; struct mp *mp; bda = (uchar*)0x400; if((p = ((bda[0x0F]<<8)|bda[0x0E]) << 4)){ if((mp = mp_search1((uchar*)p, 1024))) return mp; } else { p = ((bda[0x14]<<8)|bda[0x13])*1024; if((mp = mp_search1((uchar*)p-1024, 1024))) return mp; } return mp_search1((uchar*)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*mp_config(struct mp **pmp){ struct mpconf *conf; struct mp *mp; if((mp = mp_search()) == 0 || mp->physaddr == 0) return 0; conf = (struct mpconf*)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;}voidmp_init(void){ uchar *p, *e; struct mp *mp; struct mpconf *conf; struct mpproc *proc; struct mpioapic *ioapic; bcpu = &cpus[ncpu]; if((conf = mp_config(&mp)) == 0) return; ismp = 1; lapic = (uint*)conf->lapicaddr; for(p=(uchar*)(conf+1), e=(uchar*)conf+conf->length; p<e; ){ switch(*p){ case MPPROC: proc = (struct mpproc*)p; cpus[ncpu].apicid = proc->apicid; if(proc->flags & MPBOOT) bcpu = &cpus[ncpu]; ncpu++; p += sizeof(struct mpproc); continue; case MPIOAPIC: ioapic = (struct mpioapic*)p; ioapic_id = ioapic->apicno; p += sizeof(struct mpioapic); continue; case MPBUS: case MPIOINTR: case MPLINTR: p += 8; continue; default: cprintf("mp_init: unknown config type %x\n", *p); panic("mp_init"); } } 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. }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -