static Chan* acpiattach(char *spec) { int i; /* * This was written for the stock kernel. * This code must use 64 registers to be acpi ready in nix. */ if(1 || acpiinit() < 0) error("no acpi"); /* * should use fadt->xpm* and fadt->xgpe* registers for 64 bits. * We are not ready in this kernel for that. */ DBG("acpi io alloc\n"); acpiioalloc(fadt.smicmd, 1); acpiioalloc(fadt.pm1aevtblk, fadt.pm1evtlen); acpiioalloc(fadt.pm1bevtblk, fadt.pm1evtlen ); acpiioalloc(fadt.pm1acntblk, fadt.pm1cntlen); acpiioalloc(fadt.pm1bcntblk, fadt.pm1cntlen); acpiioalloc(fadt.pm2cntblk, fadt.pm2cntlen); acpiioalloc(fadt.pmtmrblk, fadt.pmtmrlen); acpiioalloc(fadt.gpe0blk, fadt.gpe0blklen); acpiioalloc(fadt.gpe1blk, fadt.gpe1blklen); DBG("acpi init gpes\n"); initgpes(); /* * This starts ACPI, which may require we handle * power mgmt events ourselves. Use with care. */ DBG("acpi starting\n"); outb(fadt.smicmd, fadt.acpienable); for(i = 0; i < 10; i++) if(getpm1ctl() & Pm1SciEn) break; if(i == 10) error("acpi: failed to enable\n"); if(fadt.sciint != 0) intrenable(fadt.sciint, acpiintr, 0, BUSUNKNOWN, "acpi"); return devattach(L'α', spec); }
void main(u32int ax, u32int bx) { vlong hz; memset(edata, 0, end - edata); /* * ilock via i8250enable via i8250console * needs m->machno, sys->machptr[] set, and * also 'up' set to nil. */ cgapost(sizeof(uintptr)*8); memset(m, 0, sizeof(Mach)); m->machno = 0; m->online = 1; m->nixtype = NIXTC; sys->machptr[m->machno] = &sys->mach; m->stack = PTR2UINT(sys->machstk); m->vsvm = sys->vsvmpage; up = nil; active.nonline = 1; active.exiting = 0; active.nbooting = 0; asminit(); multiboot(ax, bx, 0); options(oargc, oargv); crapoptions(); /* * Need something for initial delays * until a timebase is worked out. */ m->cpuhz = 2000000000ll; m->cpumhz = 2000; cgainit(); i8250console("0"); consputs = cgaconsputs; vsvminit(MACHSTKSZ, NIXTC); conf.nmach = 1; fmtinit(); print("\nNIX\n"); if(vflag){ print("&ax = %#p, ax = %#ux, bx = %#ux\n", &ax, ax, bx); multiboot(ax, bx, vflag); } m->perf.period = 1; if((hz = archhz()) != 0ll){ m->cpuhz = hz; m->cyclefreq = hz; m->cpumhz = hz/1000000ll; } /* * Mmuinit before meminit because it * flushes the TLB via m->pml4->pa. */ mmuinit(); ioinit(); kbdinit(); meminit(); confinit(); archinit(); mallocinit(); /* * Acpiinit will cause the first malloc * call to happen. * If the system dies here it's probably due * to malloc not being initialised * correctly, or the data segment is misaligned * (it's amazing how far you can get with * things like that completely broken). */ acpiinit(); umeminit(); trapinit(); printinit(); /* * This is necessary with GRUB and QEMU. * Without it an interrupt can occur at a weird vector, * because the vector base is likely different, causing * havoc. Do it before any APIC initialisation. */ i8259init(32); procinit0(); mpsinit(maxcores); apiconline(); sipi(); timersinit(); kbdenable(); fpuinit(); psinit(conf.nproc); initimage(); links(); devtabreset(); pageinit(); swapinit(); userinit(); nixsquids(); testiccs(); print("schedinit...\n"); schedinit(); }
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 */ }
void main(uint32_t mbmagic, uint32_t mbaddress) { Mach *m = entrym; /* when we get here, entrym is set to core0 mach. */ sys->machptr[m->machno] = m; // Very special case for BSP only. Too many things // assume this is set. wrmsr(GSbase, PTR2UINT(&sys->machptr[m->machno])); if (machp() != m) panic("m and machp() are different!!\n"); assert(sizeof(Mach) <= PGSZ); /* * Check that our data is on the right boundaries. * This works because the immediate value is in code. */ if (x != 0x123456) panic("Data is not set up correctly\n"); memset(edata, 0, end - edata); m = (void *) (KZERO + 1048576 + 11*4096); sys = (void *) (KZERO + 1048576); /* * ilock via i8250enable via i8250console * needs m->machno, sys->machptr[] set, and * also 'up' set to nil. */ cgapost(sizeof(uintptr_t)*8); memset(m, 0, sizeof(Mach)); m->machno = 0; m->online = 1; m->nixtype = NIXTC; sys->machptr[m->machno] = &sys->mach; m->stack = PTR2UINT(sys->machstk); *(uintptr_t*)m->stack = STACKGUARD; m->vsvm = sys->vsvmpage; m->externup = (void *)0; active.nonline = 1; active.exiting = 0; active.nbooting = 0; asminit(); multiboot(mbmagic, mbaddress, 0); options(oargc, oargv); /* * Need something for initial delays * until a timebase is worked out. */ m->cpuhz = 2000000000ll; m->cpumhz = 2000; cgainit(); i8250console("0"); consputs = cgaconsputs; /* It all ends here. */ vsvminit(MACHSTKSZ, NIXTC, m); if (machp() != m) panic("After vsvminit, m and machp() are different"); sys->nmach = 1; fmtinit(); print("\nHarvey\n"); if(vflag){ multiboot(mbmagic, mbaddress, vflag); } m->perf.period = 1; if((hz = archhz()) != 0ll){ m->cpuhz = hz; m->cyclefreq = hz; m->cpumhz = hz/1000000ll; } //iprint("archhz returns 0x%lld\n", hz); //iprint("NOTE: if cpuidhz runs too fast, we get die early with a NULL pointer\n"); //iprint("So, until that's fixed, we bring up AP cores slowly. Sorry!\n"); /* * Mmuinit before meminit because it * flushes the TLB via m->pml4->pa. */ mmuinit(); ioinit(); meminit(); confinit(); archinit(); mallocinit(); /* test malloc. It's easier to find out it's broken here, * not deep in some call chain. * See next note. * void *v = malloc(1234); hi("v "); put64((uint64_t)v); hi("\n"); free(v); hi("free ok\n"); */ /* * Acpiinit will cause the first malloc * call to happen. * If the system dies here it's probably due * to malloc not being initialised * correctly, or the data segment is misaligned * (it's amazing how far you can get with * things like that completely broken). */ if (0){ acpiinit(); hi(" acpiinit();\n");} umeminit(); trapinit(); /* * This is necessary with GRUB and QEMU. * Without it an interrupt can occur at a weird vector, * because the vector base is likely different, causing * havoc. Do it before any APIC initialisation. */ i8259init(32); procinit0(); mpsinit(maxcores); apiconline(); /* Forcing to single core if desired */ if(!nosmp) { sipi(); } teardownidmap(m); timersinit(); fpuinit(); psinit(conf.nproc); initimage(); links(); keybinit(); keybenable(); mouseenable(); devtabreset(); pageinit(); swapinit(); userinit(); /* Forcing to single core if desired */ if(!nosmp) { nixsquids(); testiccs(); } print("CPU Freq. %dMHz\n", m->cpumhz); print("schedinit...\n"); schedinit(); }
void kernel_init(multiboot_info_t *mboot_info) { extern char __start_bss[], __stop_bss[]; memset(__start_bss, 0, __stop_bss - __start_bss); /* mboot_info is a physical address. while some arches currently have the * lower memory mapped, everyone should have it mapped at kernbase by now. * also, it might be in 'free' memory, so once we start dynamically using * memory, we may clobber it. */ multiboot_kaddr = (struct multiboot_info*)((physaddr_t)mboot_info + KERNBASE); extract_multiboot_cmdline(multiboot_kaddr); cons_init(); print_cpuinfo(); printk("Boot Command Line: '%s'\n", boot_cmdline); exception_table_init(); cache_init(); // Determine systems's cache properties pmem_init(multiboot_kaddr); kmem_cache_init(); // Sets up slab allocator kmalloc_init(); hashtable_init(); radix_init(); cache_color_alloc_init(); // Inits data structs colored_page_alloc_init(); // Allocates colors for agnostic processes acpiinit(); topology_init(); kthread_init(); /* might need to tweak when this happens */ vmr_init(); file_init(); page_check(); idt_init(); kernel_msg_init(); timer_init(); vfs_init(); devfs_init(); train_timing(); kb_buf_init(&cons_buf); arch_init(); block_init(); enable_irq(); run_linker_funcs(); /* reset/init devtab after linker funcs 3 and 4. these run NIC and medium * pre-inits, which need to happen before devether. */ devtabreset(); devtabinit(); #ifdef CONFIG_EXT2FS mount_fs(&ext2_fs_type, "/dev/ramdisk", "/mnt", 0); #endif /* CONFIG_EXT2FS */ #ifdef CONFIG_ETH_AUDIO eth_audio_init(); #endif /* CONFIG_ETH_AUDIO */ get_coreboot_info(&sysinfo); booting = 0; #ifdef CONFIG_RUN_INIT_SCRIPT if (run_init_script()) { printk("Configured to run init script, but no script specified!\n"); manager(); } #else manager(); #endif }