diff options
Diffstat (limited to 'src/arch/x86/utility.cc')
-rw-r--r-- | src/arch/x86/utility.cc | 151 |
1 files changed, 0 insertions, 151 deletions
diff --git a/src/arch/x86/utility.cc b/src/arch/x86/utility.cc index f45d9083b..f5e87b860 100644 --- a/src/arch/x86/utility.cc +++ b/src/arch/x86/utility.cc @@ -262,157 +262,6 @@ void initCPU(ThreadContext *tc, int cpuId) void startupCPU(ThreadContext *tc, int cpuId) { if (cpuId == 0) { - // This is the boot strap processor (BSP). Initialize it to look like - // the boot loader has just turned control over to the 64 bit OS. We - // won't actually set up real mode or legacy protected mode descriptor - // tables because we aren't executing any code that would require - // them. We do, however toggle the control bits in the correct order - // while allowing consistency checks and the underlying mechansims - // just to be safe. - - const int NumPDTs = 4; - - const Addr PageMapLevel4 = 0x70000; - const Addr PageDirPtrTable = 0x71000; - const Addr PageDirTable[NumPDTs] = - {0x72000, 0x73000, 0x74000, 0x75000}; - const Addr GDTBase = 0x76000; - - const int PML4Bits = 9; - const int PDPTBits = 9; - const int PDTBits = 9; - - // Get a port to write the page tables and descriptor tables. - FunctionalPort * physPort = tc->getPhysPort(); - - /* - * Set up the gdt. - */ - // Place holder at selector 0 - uint64_t nullDescriptor = 0; - physPort->writeBlob(GDTBase, (uint8_t *)(&nullDescriptor), 8); - - //64 bit code segment - SegDescriptor csDesc = 0; - csDesc.type.c = 0; // Not conforming - csDesc.dpl = 0; // Privelege level 0 - csDesc.p = 1; // Present - csDesc.l = 1; // 64 bit - csDesc.d = 0; // default operand size - //Because we're dealing with a pointer and I don't think it's - //guaranteed that there isn't anything in a nonvirtual class between - //it's beginning in memory and it's actual data, we'll use an - //intermediary. - uint64_t csDescVal = csDesc; - physPort->writeBlob(GDTBase, (uint8_t *)(&csDescVal), 8); - - tc->setMiscReg(MISCREG_TSG_BASE, GDTBase); - tc->setMiscReg(MISCREG_TSG_LIMIT, 0xF); - - /* - * Identity map the first 4GB of memory. In order to map this region - * of memory in long mode, there needs to be one actual page map level - * 4 entry which points to one page directory pointer table which - * points to 4 different page directory tables which are full of two - * megabyte pages. All of the other entries in valid tables are set - * to indicate that they don't pertain to anything valid and will - * cause a fault if used. - */ - - // Put valid values in all of the various table entries which indicate - // that those entries don't point to further tables or pages. Then - // set the values of those entries which are needed. - - // Page Map Level 4 - - // read/write, user, not present - uint64_t pml4e = X86ISA::htog(0x6); - for (int offset = 0; offset < (1 << PML4Bits) * 8; offset += 8) { - physPort->writeBlob(PageMapLevel4 + offset, (uint8_t *)(&pml4e), 8); - } - // Point to the only PDPT - pml4e = X86ISA::htog(0x7 | PageDirPtrTable); - physPort->writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8); - - // Page Directory Pointer Table - - // read/write, user, not present - uint64_t pdpe = X86ISA::htog(0x6); - for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) { - physPort->writeBlob(PageDirPtrTable + offset, - (uint8_t *)(&pdpe), 8); - } - // Point to the PDTs - for (int table = 0; table < NumPDTs; table++) { - pdpe = X86ISA::htog(0x7 | PageDirTable[table]); - physPort->writeBlob(PageDirPtrTable + table * 8, - (uint8_t *)(&pdpe), 8); - } - - // Page Directory Tables - - Addr base = 0; - const Addr pageSize = 2 << 20; - for (int table = 0; table < NumPDTs; table++) { - for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) { - // read/write, user, present, 4MB - uint64_t pdte = X86ISA::htog(0x87 | base); - physPort->writeBlob(PageDirTable[table] + offset, - (uint8_t *)(&pdte), 8); - base += pageSize; - } - } - - /* - * Transition from real mode all the way up to Long mode - */ - CR0 cr0 = tc->readMiscRegNoEffect(MISCREG_CR0); - //Turn off paging. - cr0.pg = 0; - tc->setMiscReg(MISCREG_CR0, cr0); - //Turn on protected mode. - cr0.pe = 1; - tc->setMiscReg(MISCREG_CR0, cr0); - - CR4 cr4 = tc->readMiscRegNoEffect(MISCREG_CR4); - //Turn on pae. - cr4.pae = 1; - tc->setMiscReg(MISCREG_CR4, cr4); - - //Point to the page tables. - tc->setMiscReg(MISCREG_CR3, PageMapLevel4); - - Efer efer = tc->readMiscRegNoEffect(MISCREG_EFER); - //Enable long mode. - efer.lme = 1; - tc->setMiscReg(MISCREG_EFER, efer); - - //Activate long mode. - cr0.pg = 1; - tc->setMiscReg(MISCREG_CR0, cr0); - - /* - * Far jump into 64 bit mode. - */ - // Set the selector - tc->setMiscReg(MISCREG_CS, 1); - // Manually set up the segment attributes. In the future when there's - // other existing functionality to do this, that could be used - // instead. - SegAttr csAttr = 0; - csAttr.writable = 0; - csAttr.readable = 1; - csAttr.expandDown = 0; - csAttr.dpl = 0; - csAttr.defaultSize = 0; - csAttr.longMode = 1; - tc->setMiscReg(MISCREG_CS_ATTR, csAttr); - - tc->setPC(tc->getSystemPtr()->kernelEntry); - tc->setNextPC(tc->readPC()); - - // We should now be in long mode. Yay! - tc->activate(0); } else { // This is an application processor (AP). It should be initialized to |