void mpinitcpu(long unit) { cpuinit(unit); /* TODO: initialise HPET; enable [rerouted] interrupts */ #if (HPET) hpetinit(); #endif apicinit(); #if (IOAPIC) ioapicinit(); #endif tssinit(unit); return; }
void mpstart(void) { // volatile static int first = 1; volatile struct m_cpu *cpu; volatile struct m_cpu *lim; uint32_t *mpentrystk = (uint32_t *)MPENTRYSTK; lim = &mpcputab[0] + mpncpu; #if 0 if (first) { kmemcpy((void *)MPENTRY, mpentry, (uint8_t *)&mpend - (uint8_t *)&mpentry); first = 0; } #endif for (cpu = &mpcputab[0] ; cpu < lim ; cpu++) { if (cpu == mpbootcpu) { /* started already */ continue; } kprintf("starting CPU %ld @ 0x%lx\n", cpu->id, MPENTRY); cpuinit((struct m_cpu *)cpu); #if 0 apicinit(cpu->id); ioapicinit(cpu->id); #endif *--mpentrystk = (uint32_t)cpu; *--mpentrystk = MPENTRYSTK - cpu->id * MPSTKSIZE; *--mpentrystk = (uint32_t)&kernpagedir; apicstart(cpu->id, MPENTRY); while (!cpu->started) { ; } } return; }
void mpinit(void) { struct mp *mp; struct mpconf *conf; struct mpcpu *cpu; struct mpioapic *ioapic; uint8_t *u8ptr; uint8_t *lim; // mpbootcpu = &mpcputab[0]; conf = mpconf(&mp); if (!conf) { return; } // cpuinit((struct m_cpu *)mpbootcpu); mpmultiproc = 1; mpapic = conf->apicadr; for (u8ptr = (uint8_t *)(conf + 1), lim = (uint8_t *)conf + conf->len ; u8ptr < lim ; ) { switch (*u8ptr) { case MPCPU: cpu = (struct mpcpu *)u8ptr; if (mpncpu != cpu->id) { mpmultiproc = 0; } if (cpu->flags & MPCPUBOOT) { mpbootcpu = &mpcputab[mpncpu]; cpuinit((struct m_cpu *)mpbootcpu); } mpcputab[mpncpu].id = mpncpu; mpncpu++; u8ptr += sizeof(struct mpcpu); continue; case MPIOAPIC: ioapic = (struct mpioapic *)u8ptr; mpioapicid = ioapic->apicnum; mpioapic = ioapic->adr; u8ptr += sizeof(struct mpioapic); continue; case MPBUS: case MPIOINTR: case MPLINTR: u8ptr += 8; continue; default: mpmultiproc = 0; break; } } if ((mpncpu == 1) || !mpmultiproc) { mpncpu = 1; // mptab = NULL; // mpioapicid = 0; return; } else if (mp->intmode) { outb(0x70, 0x22); // select IMCR outb(inb(0x23) | 0x01, 0x23); // mask external timer interrupts } #if 0 /* Boot CPU */ /* local APIC initialisation where present */ // apicinit(0); /* I/O APIC initialisation */ // ioapicinit(0); #endif return; }
void kinitlong(unsigned long pmemsz) { #if (NEWTMR) uint32_t tmrcnt = 0; #endif /* initialise interrupt management */ #if (VBE) trapinitprot(); #endif /* initialise virtual memory */ vminitlong((uint64_t *)kernpagemapl4tab); #if 0 /* FIXME: map possible device memory */ vmmapseg((uint32_t *)&_pagetab, DEVMEMBASE, DEVMEMBASE, 0xffffffffU, PAGEPRES | PAGEWRITE | PAGENOCACHE); #endif // schedinit(); /* zero kernel BSS segment */ kbzero(&_bssvirt, (uint32_t)&_ebssvirt - (uint32_t)&_bssvirt); /* set kernel I/O permission bitmap to all 1-bits */ kmemset(&kerniomap, 0xff, sizeof(kerniomap)); /* INITIALIZE CONSOLES AND SCREEN */ #if (VBE) vbeinitscr(); #endif #if (VBE) && (NEWFONT) consinit(768 / vbefontw, 1024 / vbefonth); #elif (VBE) consinit(768 >> 3, 1024 >> 3); #endif /* TODO: use memory map from GRUB? */ // vminitphys((uintptr_t)&_epagetab, pmemsz); vminitphys((uintptr_t)&_epagetab, pmemsz); meminit(pmemsz); tssinit(0); #if (VBE) && (NEWFONT) // consinit(768 / vbefontw, 1024 / vbefonth); #elif (VBE) consinit(768 >> 3, 1024 >> 3); #endif #if (SMBIOS) smbiosinit(); #endif #if (PS2DRV) ps2init(); #endif #if (VBE) && (PLASMA) plasmaloop(); #endif #if (VBE) vbeprintinfo(); #endif logoprint(); // vminitphys((uintptr_t)&_ebss, pmemsz - (unsigned long)&_ebss); /* HID devices */ #if (PCI) /* initialise PCI bus driver */ pciinit(); #endif #if (ATA) /* initialise ATA driver */ atainit(); #endif #if (SB16) /* initialise Soundblaster 16 driver */ sb16init(); #endif #if (ACPI) /* initialise ACPI subsystem */ acpiinit(); #endif /* initialise block I/O buffer cache */ if (!bufinit()) { kprintf("failed to allocate buffer cache\n"); while (1) { ; } } /* allocate unused device regions (in 3.5G..4G) */ // pageaddzone(DEVMEMBASE, &vmshmq, 0xffffffffU - DEVMEMBASE + 1); #if (SMP) || (APIC) //#if (SMP) /* multiprocessor initialisation */ // mpinit(); //#endif if (mpncpu == 1) { kprintf("found %ld processor\n", mpncpu); } else { kprintf("found %ld processors\n", mpncpu); } #if (HPET) /* initialise high precision event timers */ hpetinit(); #endif #if (NEWTMR) tmrcnt = apicinitcpu(0); #else apicinitcpu(0); #endif #if (IOAPIC) ioapicinit(0); #endif #endif /* SMP || APIC */ #if (SMP) if (mpmultiproc) { mpstart(); } #endif /* CPU interface */ taskinit(); // tssinit(0); // machinit(); /* execution environment */ procinit(PROCKERN); // k_curtask = &k_curproc->task; // sysinit(); kprintf("DMA buffers (%ul x %ul kilobytes) @ 0x%p\n", DMANCHAN, DMACHANBUFSIZE >> 10, DMABUFBASE); kprintf("VM page tables @ 0x%p\n", (unsigned long)&_pagetab); // kprintf("%ld kilobytes physical memory\n", pmemsz >> 10); kprintf("%ld kilobytes kernel memory\n", (uint32_t)&_ebss >> 10); kprintf("%ld kilobytes allocated physical memory (%ld wired, %ld total)\n", (vmpagestat.nwired + vmpagestat.nmapped + vmpagestat.nbuf) << (PAGESIZELOG2 - 10), vmpagestat.nwired << (PAGESIZELOG2 - 10), vmpagestat.nphys << (PAGESIZELOG2 - 10)); k_curcpu = &cputab[0]; cpuinit(k_curcpu); schedinit(); #if (APIC) apicstarttmr(tmrcnt); #else pitinit(); #endif schedloop(); /* NOTREACHED */ }