Esempio n. 1
0
File: mp.c Progetto: tim48134/xylos
void
mpinit(void)
{
	uchar *p, *e;
	struct mp *mp;
	struct mpconf *conf;
	struct mpproc *proc;
	struct mpioapic *ioapic;

	bcpu = &cpus[0];
	if((conf = mpconfig(&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;
				if(ncpu != proc->apicid) {
					cprintf("mpinit: ncpu=%d apicid=%d\n", ncpu, proc->apicid);
					ismp = 0;
				}
				if(proc->flags & MPBOOT) {
					bcpu = &cpus[ncpu];
				}
				cpus[ncpu].id = 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:
				cprintf("mpinit: unknown config type %x\n", *p);
				ismp = 0;
		}
	}
	if(!ismp) {
		// Didn't like what we found; fall back to no MP.
		ncpu = 1;
		lapic = 0;
		ioapicid = 0;
		return;
	}

	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.
	}
}
Esempio n. 2
0
void
mp_init(void)
{
	uint8_t          *p, *e;
	struct mp      *mp;
	struct mpconf  *conf;
	struct mpproc  *proc;
	struct mpioapic *mpio;

	if (!cpu_onboot())	// only do once, on the boot CPU
		return;

	if ((conf = mpconfig(&mp)) == 0)
		return; // Not a multiprocessor machine - just use boot CPU.

	ismp = 1;
	lapic = (uint32_t *) conf->lapicaddr;
	for (p = (uint8_t *) (conf + 1), e = (uint8_t *) conf + conf->length;
			p < e;) {
		switch (*p) {
		case MPPROC:
			proc = (struct mpproc *) p;
			p += sizeof(struct mpproc);
			if (!(proc->flags & MPENAB))
				continue;	// processor disabled

			// Get a cpu struct and kernel stack for this CPU.
			cpu *c = (proc->flags & MPBOOT)
					? &cpu_boot : cpu_alloc();
			c->id = proc->apicid;
#if LAB >= 9
			c->num = ncpu;	// also assign sequential CPU numbers
#endif
			ncpu++;
			continue;
		case MPIOAPIC:
			mpio = (struct mpioapic *) p;
			p += sizeof(struct mpioapic);
			ioapicid = mpio->apicno;
			ioapic = (struct ioapic *) mpio->addr;
			continue;
		case MPBUS:
		case MPIOINTR:
		case MPLINTR:
			p += 8;
			continue;
		default:
			panic("mpinit: unknown config type %x\n", *p);
		}
	}
	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.
	}
}
Esempio n. 3
0
void
mp_init(void)
{
	struct mp *mp;
	struct mpconf *conf;
	struct mpproc *proc;
	uint8_t *p;
	unsigned int i;

	bootcpu = &cpus[0];
	if ((conf = mpconfig(&mp)) == 0)
		return;
	ismp = 1;
	lapic = (uint32_t *)conf->lapicaddr;

	for (p = conf->entries, i = 0; i < conf->entry; i++) {
		//cprintf("mpinit: *p = %u i = %u\n", *p, i);
		switch (*p) {
		case MPPROC:
			proc = (struct mpproc *)p;
			if (proc->flags & MPPROC_BOOT)
				bootcpu = &cpus[ncpu];
			if (ncpu < NCPU) {
				cpus[ncpu].cpu_id = ncpu;
				ncpu++;
			} else {
				cprintf("SMP: too many CPUs, CPU %d disabled\n",
					proc->apicid);
			}
			p += sizeof(struct mpproc);
			continue;
		case MPBUS:
		case MPIOAPIC:
		case MPIOINTR:
		case MPLINTR:
			p += 8;
			continue;
		default:
			cprintf("mpinit: unknown config type %x\n", *p);
			ismp = 0;
			i = conf->entry;
		}
	}

	bootcpu->cpu_status = CPU_STARTED;
	if (!ismp) {
		// Didn't like what we found; fall back to no MP.
		ncpu = 1;
		lapic = NULL;
		cprintf("SMP: configuration not found, SMP disabled\n");
		return;
	}
	cprintf("SMP: CPU %d found %d CPU(s)\n", bootcpu->cpu_id,  ncpu);

	if (mp->imcrp) {
		// [MP 3.2.6.1] If the hardware implements PIC mode,
		// switch to getting interrupts from the LAPIC.
		cprintf("SMP: Setting IMCR to switch from PIC mode to symmetric I/O mode\n");
		outb(0x22, 0x70);   // Select IMCR
		outb(0x23, inb(0x23) | 1);  // Mask external interrupts.
	}
}
Esempio n. 4
0
int init_mp()
{
	uchar_t *p;
	uint_t ncpu = 0, ismp = 1;
	mpconf_t *conf;
	mpproc_t *proc;
	mpfp_t *mp;
	mpioapic_t *ioapic;

	if ((conf = mpconfig(&mp)) == NULL) {
		printk("could not find MP configuration\n");
		return 0;
	}

	lapic_regp = (uint_t *) conf->lapicaddr;
	for (p = (uchar_t *) (conf + 1); p < (uchar_t *) conf + conf->length;) {
		switch (*p) {
		case MPPROC:
			proc = (mpproc_t *) p;
			if (ncpu != proc->apicid) {
				printk(LOG_MP
				       "mpinit: ncpu=%d apicid=%d\n",
				       ncpu, proc->apicid);
				ismp = 0;
			}

			cpu_reset_state(&cpuset[ncpu]);
			if (proc->flags & MPBOOT) {
				cpu_set_val(&cpuset[ncpu], flag_bsp, 1);
				printk
				    ("found bootstrap processor #%d\n",
				     proc->apicid);
			} else
				printk
				    ("found application processor #%d\n",
				     proc->apicid);
			cpu_set_val(&cpuset[ncpu], proc_id, proc->apicid);

			// find next processor
			ncpu++;
			p += sizeof(mpproc_t);
			continue;
		case MPIOAPIC:
			ioapic = (mpioapic_t *) p;
			ioapic_id = ioapic->apicno;
			p += sizeof(mpioapic_t);
			continue;
		case MPBUS:
		case MPIOINTR:
		case MPLINTR:
			p += 8;
			continue;
		default:
			printk(LOG_MP "mpinit: unknown config type %x\n", *p);
			ismp = 0;
		}
	}

	if (!ismp) {
		// Didn't like what we found; fall back to no MP.
		mpinfo.ncpu = 1;
		mpinfo.ismp = 0;
		lapic_regp = NULL;
		ioapic_id = 0;
		return 0;
	}
	// Select IMCR,  Mask external interrupts
	if (mp->imcrp) {
		outb(0x22, 0x70);
		outb(0x23, inb(0x23) | 1);
	}

	if (ncpu > 1)
		mpinfo.ismp = 1;
	else
		mpinfo.ismp = 0;
	mpinfo.ncpu = ncpu;

	// only return AP num
	return ncpu - 1;
}