X86: Move startup code to the system object to initialize a Linux system.
--HG-- extra : convert_revision : a4796c79f41aa8b8f38bf2f628bee8f1b3af64be
This commit is contained in:
parent
e7fc5c42f3
commit
42ae409746
9 changed files with 341 additions and 157 deletions
|
@ -155,8 +155,8 @@ def makeLinuxMipsSystem(mem_mode, mdesc = None):
|
|||
|
||||
return self
|
||||
|
||||
def makeX86System(mem_mode, mdesc = None):
|
||||
self = X86System()
|
||||
def makeLinuxX86System(mem_mode, mdesc = None):
|
||||
self = LinuxX86System()
|
||||
if not mdesc:
|
||||
# generic system
|
||||
mdesc = SysConfig()
|
||||
|
|
|
@ -102,7 +102,7 @@ elif m5.build_env['TARGET_ISA'] == "mips":
|
|||
elif m5.build_env['TARGET_ISA'] == "sparc":
|
||||
test_sys = makeSparcSystem(test_mem_mode, bm[0])
|
||||
elif m5.build_env['TARGET_ISA'] == "x86":
|
||||
test_sys = makeX86System(test_mem_mode, bm[0])
|
||||
test_sys = makeLinuxX86System(test_mem_mode, bm[0])
|
||||
else:
|
||||
m5.panic("incapable of building non-alpha or non-sparc full system!")
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@ if env['TARGET_ISA'] == 'x86':
|
|||
SimObject('X86System.py')
|
||||
|
||||
# Full-system sources
|
||||
Source('linux/system.cc')
|
||||
Source('pagetable_walker.cc')
|
||||
Source('system.cc')
|
||||
Source('stacktrace.cc')
|
||||
|
|
|
@ -58,3 +58,7 @@ from System import System
|
|||
|
||||
class X86System(System):
|
||||
type = 'X86System'
|
||||
|
||||
class LinuxX86System(X86System):
|
||||
type = 'LinuxX86System'
|
||||
command_line = Param.String("", "the kernel command line")
|
||||
|
|
88
src/arch/x86/linux/system.cc
Normal file
88
src/arch/x86/linux/system.cc
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 2007 The Hewlett-Packard Development Company
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use of this software in source and binary forms,
|
||||
* with or without modification, are permitted provided that the
|
||||
* following conditions are met:
|
||||
*
|
||||
* The software must be used only for Non-Commercial Use which means any
|
||||
* use which is NOT directed to receiving any direct monetary
|
||||
* compensation for, or commercial advantage from such use. Illustrative
|
||||
* examples of non-commercial use are academic research, personal study,
|
||||
* teaching, education and corporate research & development.
|
||||
* Illustrative examples of commercial use are distributing products for
|
||||
* commercial advantage and providing services using the software for
|
||||
* commercial advantage.
|
||||
*
|
||||
* If you wish to use this software or functionality therein that may be
|
||||
* covered by patents for commercial use, please contact:
|
||||
* Director of Intellectual Property Licensing
|
||||
* Office of Strategy and Technology
|
||||
* Hewlett-Packard Company
|
||||
* 1501 Page Mill Road
|
||||
* Palo Alto, California 94304
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. Redistributions
|
||||
* in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution. Neither the name of
|
||||
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission. No right of
|
||||
* sublicense is granted herewith. Derivatives of the software and
|
||||
* output created using the software may be prepared, but only for
|
||||
* Non-Commercial Uses. Derivatives of the software may be shared with
|
||||
* others provided: (i) the others agree to abide by the list of
|
||||
* conditions herein which includes the Non-Commercial Use restrictions;
|
||||
* and (ii) such Derivatives of the software include the above copyright
|
||||
* notice to acknowledge the contribution from this software where
|
||||
* applicable, this list of conditions and the disclaimer below.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#include "arch/x86/linux/system.hh"
|
||||
#include "arch/vtophys.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "mem/physical.hh"
|
||||
#include "params/LinuxX86System.hh"
|
||||
|
||||
|
||||
using namespace LittleEndianGuest;
|
||||
using namespace X86ISA;
|
||||
|
||||
LinuxX86System::LinuxX86System(Params *p)
|
||||
: X86System(p), commandLine(p->command_line)
|
||||
{
|
||||
}
|
||||
|
||||
LinuxX86System::~LinuxX86System()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
LinuxX86System::startup()
|
||||
{
|
||||
X86System::startup();
|
||||
//Build the real mode data structure.
|
||||
}
|
||||
|
||||
LinuxX86System *
|
||||
LinuxX86SystemParams::create()
|
||||
{
|
||||
return new LinuxX86System(this);
|
||||
}
|
81
src/arch/x86/linux/system.hh
Normal file
81
src/arch/x86/linux/system.hh
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2007 The Hewlett-Packard Development Company
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use of this software in source and binary forms,
|
||||
* with or without modification, are permitted provided that the
|
||||
* following conditions are met:
|
||||
*
|
||||
* The software must be used only for Non-Commercial Use which means any
|
||||
* use which is NOT directed to receiving any direct monetary
|
||||
* compensation for, or commercial advantage from such use. Illustrative
|
||||
* examples of non-commercial use are academic research, personal study,
|
||||
* teaching, education and corporate research & development.
|
||||
* Illustrative examples of commercial use are distributing products for
|
||||
* commercial advantage and providing services using the software for
|
||||
* commercial advantage.
|
||||
*
|
||||
* If you wish to use this software or functionality therein that may be
|
||||
* covered by patents for commercial use, please contact:
|
||||
* Director of Intellectual Property Licensing
|
||||
* Office of Strategy and Technology
|
||||
* Hewlett-Packard Company
|
||||
* 1501 Page Mill Road
|
||||
* Palo Alto, California 94304
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. Redistributions
|
||||
* in binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution. Neither the name of
|
||||
* the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission. No right of
|
||||
* sublicense is granted herewith. Derivatives of the software and
|
||||
* output created using the software may be prepared, but only for
|
||||
* Non-Commercial Uses. Derivatives of the software may be shared with
|
||||
* others provided: (i) the others agree to abide by the list of
|
||||
* conditions herein which includes the Non-Commercial Use restrictions;
|
||||
* and (ii) such Derivatives of the software include the above copyright
|
||||
* notice to acknowledge the contribution from this software where
|
||||
* applicable, this list of conditions and the disclaimer below.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_LINUX_X86_SYSTEM_HH__
|
||||
#define __ARCH_LINUX_X86_SYSTEM_HH__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "params/LinuxX86System.hh"
|
||||
#include "arch/x86/system.hh"
|
||||
|
||||
class LinuxX86System : public X86System
|
||||
{
|
||||
protected:
|
||||
std::string commandLine;
|
||||
|
||||
public:
|
||||
typedef LinuxX86SystemParams Params;
|
||||
LinuxX86System(Params *p);
|
||||
~LinuxX86System();
|
||||
|
||||
void startup();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -55,24 +55,183 @@
|
|||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#include "arch/x86/miscregs.hh"
|
||||
#include "arch/x86/system.hh"
|
||||
#include "arch/vtophys.hh"
|
||||
#include "base/remote_gdb.hh"
|
||||
#include "base/loader/object_file.hh"
|
||||
#include "base/loader/symtab.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "mem/physical.hh"
|
||||
#include "params/X86System.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
|
||||
|
||||
using namespace BigEndianGuest;
|
||||
using namespace LittleEndianGuest;
|
||||
using namespace X86ISA;
|
||||
|
||||
X86System::X86System(Params *p)
|
||||
: System(p)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
X86System::startup()
|
||||
{
|
||||
System::startup();
|
||||
// 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 = threadContexts[0]->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);
|
||||
|
||||
threadContexts[0]->setMiscReg(MISCREG_TSG_BASE, GDTBase);
|
||||
threadContexts[0]->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 = threadContexts[0]->readMiscRegNoEffect(MISCREG_CR0);
|
||||
//Turn off paging.
|
||||
cr0.pg = 0;
|
||||
threadContexts[0]->setMiscReg(MISCREG_CR0, cr0);
|
||||
//Turn on protected mode.
|
||||
cr0.pe = 1;
|
||||
threadContexts[0]->setMiscReg(MISCREG_CR0, cr0);
|
||||
|
||||
CR4 cr4 = threadContexts[0]->readMiscRegNoEffect(MISCREG_CR4);
|
||||
//Turn on pae.
|
||||
cr4.pae = 1;
|
||||
threadContexts[0]->setMiscReg(MISCREG_CR4, cr4);
|
||||
|
||||
//Point to the page tables.
|
||||
threadContexts[0]->setMiscReg(MISCREG_CR3, PageMapLevel4);
|
||||
|
||||
Efer efer = threadContexts[0]->readMiscRegNoEffect(MISCREG_EFER);
|
||||
//Enable long mode.
|
||||
efer.lme = 1;
|
||||
threadContexts[0]->setMiscReg(MISCREG_EFER, efer);
|
||||
|
||||
//Activate long mode.
|
||||
cr0.pg = 1;
|
||||
threadContexts[0]->setMiscReg(MISCREG_CR0, cr0);
|
||||
|
||||
/*
|
||||
* Far jump into 64 bit mode.
|
||||
*/
|
||||
// Set the selector
|
||||
threadContexts[0]->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;
|
||||
threadContexts[0]->setMiscReg(MISCREG_CS_ATTR, csAttr);
|
||||
|
||||
threadContexts[0]->setPC(threadContexts[0]->getSystemPtr()->kernelEntry);
|
||||
threadContexts[0]->setNextPC(threadContexts[0]->readPC());
|
||||
|
||||
// We should now be in long mode. Yay!
|
||||
}
|
||||
|
||||
X86System::~X86System()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -79,8 +79,10 @@ class X86System : public System
|
|||
* Serialization stuff
|
||||
*/
|
||||
public:
|
||||
virtual void serialize(std::ostream &os);
|
||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
void startup();
|
||||
|
||||
protected:
|
||||
const Params *params() const { return (const Params *)_params; }
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue