⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp.c

📁 美国mit操作系统课程所用的一个教学操作系统xv6
💻 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 + -