system.cc revision 7087
110515SAli.Saidi@ARM.com/* 210515SAli.Saidi@ARM.com * Copyright (c) 2007 The Hewlett-Packard Development Company 311201Sandreas.hansson@arm.com * All rights reserved. 411201Sandreas.hansson@arm.com * 511201Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 610515SAli.Saidi@ARM.com * not be construed as granting a license to any other intellectual 711201Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 811201Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 911201Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 1011201Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 1111201Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 1211201Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 1311201Sandreas.hansson@arm.com * 1410515SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without 1510515SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are 1611201Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 1711201Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 1811201Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 1911201Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 2011201Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 2111201Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 2211201Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 2311201Sandreas.hansson@arm.com * this software without specific prior written permission. 2411201Sandreas.hansson@arm.com * 2510585Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2611201Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2711201Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2811201Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2911201Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3011201Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3111201Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3211201Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3311201Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410585Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3511201Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3611201Sandreas.hansson@arm.com * 3711201Sandreas.hansson@arm.com * Authors: Gabe Black 3811201Sandreas.hansson@arm.com */ 3911201Sandreas.hansson@arm.com 4011201Sandreas.hansson@arm.com#include "arch/x86/bios/smbios.hh" 4111201Sandreas.hansson@arm.com#include "arch/x86/bios/intelmp.hh" 4211201Sandreas.hansson@arm.com#include "arch/x86/miscregs.hh" 4311201Sandreas.hansson@arm.com#include "arch/x86/system.hh" 4411201Sandreas.hansson@arm.com#include "arch/vtophys.hh" 4511138Sandreas.hansson@arm.com#include "base/intmath.hh" 4611201Sandreas.hansson@arm.com#include "base/loader/object_file.hh" 4711201Sandreas.hansson@arm.com#include "base/loader/symtab.hh" 4811201Sandreas.hansson@arm.com#include "base/remote_gdb.hh" 4911201Sandreas.hansson@arm.com#include "base/trace.hh" 5011201Sandreas.hansson@arm.com#include "cpu/thread_context.hh" 5111201Sandreas.hansson@arm.com#include "mem/physical.hh" 5211201Sandreas.hansson@arm.com#include "params/X86System.hh" 5311201Sandreas.hansson@arm.com#include "sim/byteswap.hh" 5411201Sandreas.hansson@arm.com 5511201Sandreas.hansson@arm.com 5611201Sandreas.hansson@arm.comusing namespace LittleEndianGuest; 5711201Sandreas.hansson@arm.comusing namespace X86ISA; 5811201Sandreas.hansson@arm.com 5911201Sandreas.hansson@arm.comX86System::X86System(Params *p) : 6011201Sandreas.hansson@arm.com System(p), smbiosTable(p->smbios_table), 6111201Sandreas.hansson@arm.com mpFloatingPointer(p->intel_mp_pointer), 6211201Sandreas.hansson@arm.com mpConfigTable(p->intel_mp_table), 6311201Sandreas.hansson@arm.com rsdp(p->acpi_description_table_pointer) 6411167Sjthestness@gmail.com{} 6511201Sandreas.hansson@arm.com 6611201Sandreas.hansson@arm.comstatic void 6711201Sandreas.hansson@arm.cominstallSegDesc(ThreadContext *tc, SegmentRegIndex seg, 6811201Sandreas.hansson@arm.com SegDescriptor desc, bool longmode) 6911201Sandreas.hansson@arm.com{ 7011201Sandreas.hansson@arm.com uint64_t base = desc.baseLow + (desc.baseHigh << 24); 7111201Sandreas.hansson@arm.com bool honorBase = !longmode || seg == SEGMENT_REG_FS || 7211201Sandreas.hansson@arm.com seg == SEGMENT_REG_GS || 7311201Sandreas.hansson@arm.com seg == SEGMENT_REG_TSL || 7411201Sandreas.hansson@arm.com seg == SYS_SEGMENT_REG_TR; 7511201Sandreas.hansson@arm.com uint64_t limit = desc.limitLow | (desc.limitHigh << 16); 7611201Sandreas.hansson@arm.com 7711201Sandreas.hansson@arm.com SegAttr attr = 0; 7811201Sandreas.hansson@arm.com 7911201Sandreas.hansson@arm.com attr.dpl = desc.dpl; 8011201Sandreas.hansson@arm.com attr.unusable = 0; 8111201Sandreas.hansson@arm.com attr.defaultSize = desc.d; 8211201Sandreas.hansson@arm.com attr.longMode = desc.l; 8311201Sandreas.hansson@arm.com attr.avl = desc.avl; 8411201Sandreas.hansson@arm.com attr.granularity = desc.g; 8511201Sandreas.hansson@arm.com attr.present = desc.p; 8611201Sandreas.hansson@arm.com attr.system = desc.s; 8711201Sandreas.hansson@arm.com attr.type = desc.type; 8811201Sandreas.hansson@arm.com if (desc.s) { 8911201Sandreas.hansson@arm.com if (desc.type.codeOrData) { 9011201Sandreas.hansson@arm.com // Code segment 9111201Sandreas.hansson@arm.com attr.expandDown = 0; 9211201Sandreas.hansson@arm.com attr.readable = desc.type.r; 9311201Sandreas.hansson@arm.com attr.writable = 0; 9411201Sandreas.hansson@arm.com } else { 9511201Sandreas.hansson@arm.com // Data segment 9611201Sandreas.hansson@arm.com attr.expandDown = desc.type.e; 9711201Sandreas.hansson@arm.com attr.readable = 1; 9810515SAli.Saidi@ARM.com attr.writable = desc.type.w; 9911201Sandreas.hansson@arm.com } 10011201Sandreas.hansson@arm.com } else { 10110515SAli.Saidi@ARM.com attr.readable = 1; 10210515SAli.Saidi@ARM.com attr.writable = 1; 10310515SAli.Saidi@ARM.com attr.expandDown = 0; 10410515SAli.Saidi@ARM.com } 10510515SAli.Saidi@ARM.com 10610515SAli.Saidi@ARM.com tc->setMiscReg(MISCREG_SEG_BASE(seg), base); 10711201Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_SEG_EFF_BASE(seg), honorBase ? base : 0); 10810515SAli.Saidi@ARM.com tc->setMiscReg(MISCREG_SEG_LIMIT(seg), limit); 10910515SAli.Saidi@ARM.com tc->setMiscReg(MISCREG_SEG_ATTR(seg), (MiscReg)attr); 11010515SAli.Saidi@ARM.com} 11110515SAli.Saidi@ARM.com 11210515SAli.Saidi@ARM.comvoid 11310515SAli.Saidi@ARM.comX86System::startup() 11411201Sandreas.hansson@arm.com{ 11511201Sandreas.hansson@arm.com System::startup(); 11611201Sandreas.hansson@arm.com ThreadContext *tc = threadContexts[0]; 11711201Sandreas.hansson@arm.com // This is the boot strap processor (BSP). Initialize it to look like 11811201Sandreas.hansson@arm.com // the boot loader has just turned control over to the 64 bit OS. We 11911201Sandreas.hansson@arm.com // won't actually set up real mode or legacy protected mode descriptor 12011201Sandreas.hansson@arm.com // tables because we aren't executing any code that would require 12111201Sandreas.hansson@arm.com // them. We do, however toggle the control bits in the correct order 12211201Sandreas.hansson@arm.com // while allowing consistency checks and the underlying mechansims 12311201Sandreas.hansson@arm.com // just to be safe. 12411201Sandreas.hansson@arm.com 12511201Sandreas.hansson@arm.com const int NumPDTs = 4; 12611201Sandreas.hansson@arm.com 12711201Sandreas.hansson@arm.com const Addr PageMapLevel4 = 0x70000; 12811201Sandreas.hansson@arm.com const Addr PageDirPtrTable = 0x71000; 12911201Sandreas.hansson@arm.com const Addr PageDirTable[NumPDTs] = 13011201Sandreas.hansson@arm.com {0x72000, 0x73000, 0x74000, 0x75000}; 13111201Sandreas.hansson@arm.com const Addr GDTBase = 0x76000; 13211201Sandreas.hansson@arm.com 13311201Sandreas.hansson@arm.com const int PML4Bits = 9; 13411201Sandreas.hansson@arm.com const int PDPTBits = 9; 13511201Sandreas.hansson@arm.com const int PDTBits = 9; 13611138Sandreas.hansson@arm.com 13711201Sandreas.hansson@arm.com // Get a port to write the page tables and descriptor tables. 13811201Sandreas.hansson@arm.com FunctionalPort * physPort = tc->getPhysPort(); 13910515SAli.Saidi@ARM.com 14010515SAli.Saidi@ARM.com /* 14110515SAli.Saidi@ARM.com * Set up the gdt. 14210515SAli.Saidi@ARM.com */ 14310515SAli.Saidi@ARM.com uint8_t numGDTEntries = 0; 14410515SAli.Saidi@ARM.com // Place holder at selector 0 14510515SAli.Saidi@ARM.com uint64_t nullDescriptor = 0; 14610515SAli.Saidi@ARM.com physPort->writeBlob(GDTBase + numGDTEntries * 8, 14710515SAli.Saidi@ARM.com (uint8_t *)(&nullDescriptor), 8); 14810515SAli.Saidi@ARM.com numGDTEntries++; 14910515SAli.Saidi@ARM.com 15010515SAli.Saidi@ARM.com //64 bit code segment 15110515SAli.Saidi@ARM.com SegDescriptor csDesc = 0; 15210515SAli.Saidi@ARM.com csDesc.type.codeOrData = 1; 15310515SAli.Saidi@ARM.com csDesc.type.c = 0; // Not conforming 15410515SAli.Saidi@ARM.com csDesc.type.r = 1; // Readable 15510515SAli.Saidi@ARM.com csDesc.dpl = 0; // Privelege level 0 15610515SAli.Saidi@ARM.com csDesc.p = 1; // Present 15710515SAli.Saidi@ARM.com csDesc.l = 1; // 64 bit 15810515SAli.Saidi@ARM.com csDesc.d = 0; // default operand size 15910515SAli.Saidi@ARM.com csDesc.g = 1; // Page granularity 16010515SAli.Saidi@ARM.com csDesc.s = 1; // Not a system segment 16110515SAli.Saidi@ARM.com csDesc.limitHigh = 0xF; 16211201Sandreas.hansson@arm.com csDesc.limitLow = 0xFF; 16311201Sandreas.hansson@arm.com //Because we're dealing with a pointer and I don't think it's 16411201Sandreas.hansson@arm.com //guaranteed that there isn't anything in a nonvirtual class between 16511201Sandreas.hansson@arm.com //it's beginning in memory and it's actual data, we'll use an 16611201Sandreas.hansson@arm.com //intermediary. 16711201Sandreas.hansson@arm.com uint64_t csDescVal = csDesc; 16811201Sandreas.hansson@arm.com physPort->writeBlob(GDTBase + numGDTEntries * 8, 16911201Sandreas.hansson@arm.com (uint8_t *)(&csDescVal), 8); 17011201Sandreas.hansson@arm.com 17111201Sandreas.hansson@arm.com numGDTEntries++; 17211201Sandreas.hansson@arm.com 17311201Sandreas.hansson@arm.com SegSelector cs = 0; 17411201Sandreas.hansson@arm.com cs.si = numGDTEntries - 1; 17511201Sandreas.hansson@arm.com 17611201Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_CS, (MiscReg)cs); 17711201Sandreas.hansson@arm.com 17811201Sandreas.hansson@arm.com //32 bit data segment 17911201Sandreas.hansson@arm.com SegDescriptor dsDesc = 0; 18011201Sandreas.hansson@arm.com dsDesc.type.codeOrData = 0; 18111201Sandreas.hansson@arm.com dsDesc.type.e = 0; // Not expand down 18211201Sandreas.hansson@arm.com dsDesc.type.w = 1; // Writable 18311201Sandreas.hansson@arm.com dsDesc.dpl = 0; // Privelege level 0 18411201Sandreas.hansson@arm.com dsDesc.p = 1; // Present 18511201Sandreas.hansson@arm.com dsDesc.d = 1; // default operand size 18611201Sandreas.hansson@arm.com dsDesc.g = 1; // Page granularity 18711201Sandreas.hansson@arm.com dsDesc.s = 1; // Not a system segment 18811201Sandreas.hansson@arm.com dsDesc.limitHigh = 0xF; 18911201Sandreas.hansson@arm.com dsDesc.limitLow = 0xFF; 19011201Sandreas.hansson@arm.com uint64_t dsDescVal = dsDesc; 19111201Sandreas.hansson@arm.com physPort->writeBlob(GDTBase + numGDTEntries * 8, 19211201Sandreas.hansson@arm.com (uint8_t *)(&dsDescVal), 8); 19311201Sandreas.hansson@arm.com 19411201Sandreas.hansson@arm.com numGDTEntries++; 19511201Sandreas.hansson@arm.com 19611201Sandreas.hansson@arm.com SegSelector ds = 0; 19711201Sandreas.hansson@arm.com ds.si = numGDTEntries - 1; 19811201Sandreas.hansson@arm.com 19911201Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_DS, (MiscReg)ds); 20011201Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_ES, (MiscReg)ds); 20111201Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_FS, (MiscReg)ds); 20211201Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_GS, (MiscReg)ds); 20311201Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_SS, (MiscReg)ds); 20411201Sandreas.hansson@arm.com 20511201Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_TSL, 0); 20611201Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_TSG_BASE, GDTBase); 20711201Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_TSG_LIMIT, 8 * numGDTEntries - 1); 20811201Sandreas.hansson@arm.com 20911201Sandreas.hansson@arm.com SegDescriptor tssDesc = 0; 21011201Sandreas.hansson@arm.com tssDesc.type = 0xB; 21111201Sandreas.hansson@arm.com tssDesc.dpl = 0; // Privelege level 0 21211201Sandreas.hansson@arm.com tssDesc.p = 1; // Present 21311201Sandreas.hansson@arm.com tssDesc.d = 1; // default operand size 21411201Sandreas.hansson@arm.com tssDesc.g = 1; // Page granularity 21511201Sandreas.hansson@arm.com tssDesc.s = 1; // Not a system segment 21611201Sandreas.hansson@arm.com tssDesc.limitHigh = 0xF; 21711201Sandreas.hansson@arm.com tssDesc.limitLow = 0xFF; 21811201Sandreas.hansson@arm.com uint64_t tssDescVal = tssDesc; 21911201Sandreas.hansson@arm.com physPort->writeBlob(GDTBase + numGDTEntries * 8, 22011201Sandreas.hansson@arm.com (uint8_t *)(&tssDescVal), 8); 22111201Sandreas.hansson@arm.com 22211201Sandreas.hansson@arm.com numGDTEntries++; 22311201Sandreas.hansson@arm.com 22411201Sandreas.hansson@arm.com SegSelector tss = 0; 22511201Sandreas.hansson@arm.com tss.si = numGDTEntries - 1; 22611201Sandreas.hansson@arm.com 22711201Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_TR, (MiscReg)tss); 22811201Sandreas.hansson@arm.com installSegDesc(tc, SYS_SEGMENT_REG_TR, tssDesc, true); 22910892Sandreas.hansson@arm.com 23010892Sandreas.hansson@arm.com /* 23110892Sandreas.hansson@arm.com * Identity map the first 4GB of memory. In order to map this region 23211201Sandreas.hansson@arm.com * of memory in long mode, there needs to be one actual page map level 23311201Sandreas.hansson@arm.com * 4 entry which points to one page directory pointer table which 23411201Sandreas.hansson@arm.com * points to 4 different page directory tables which are full of two 23511201Sandreas.hansson@arm.com * megabyte pages. All of the other entries in valid tables are set 23611201Sandreas.hansson@arm.com * to indicate that they don't pertain to anything valid and will 23711201Sandreas.hansson@arm.com * cause a fault if used. 23811201Sandreas.hansson@arm.com */ 23911201Sandreas.hansson@arm.com 24011201Sandreas.hansson@arm.com // Put valid values in all of the various table entries which indicate 24111201Sandreas.hansson@arm.com // that those entries don't point to further tables or pages. Then 24211201Sandreas.hansson@arm.com // set the values of those entries which are needed. 24311201Sandreas.hansson@arm.com 24411201Sandreas.hansson@arm.com // Page Map Level 4 24511201Sandreas.hansson@arm.com 24611201Sandreas.hansson@arm.com // read/write, user, not present 24711201Sandreas.hansson@arm.com uint64_t pml4e = X86ISA::htog(0x6); 24811201Sandreas.hansson@arm.com for (int offset = 0; offset < (1 << PML4Bits) * 8; offset += 8) { 24911201Sandreas.hansson@arm.com physPort->writeBlob(PageMapLevel4 + offset, (uint8_t *)(&pml4e), 8); 25011201Sandreas.hansson@arm.com } 25111201Sandreas.hansson@arm.com // Point to the only PDPT 25211201Sandreas.hansson@arm.com pml4e = X86ISA::htog(0x7 | PageDirPtrTable); 25311201Sandreas.hansson@arm.com physPort->writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8); 25411201Sandreas.hansson@arm.com 25511201Sandreas.hansson@arm.com // Page Directory Pointer Table 25611201Sandreas.hansson@arm.com 25711201Sandreas.hansson@arm.com // read/write, user, not present 25811201Sandreas.hansson@arm.com uint64_t pdpe = X86ISA::htog(0x6); 25911167Sjthestness@gmail.com for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) { 26011167Sjthestness@gmail.com physPort->writeBlob(PageDirPtrTable + offset, 26111201Sandreas.hansson@arm.com (uint8_t *)(&pdpe), 8); 26211201Sandreas.hansson@arm.com } 26311201Sandreas.hansson@arm.com // Point to the PDTs 26411201Sandreas.hansson@arm.com for (int table = 0; table < NumPDTs; table++) { 26511201Sandreas.hansson@arm.com pdpe = X86ISA::htog(0x7 | PageDirTable[table]); 26611201Sandreas.hansson@arm.com physPort->writeBlob(PageDirPtrTable + table * 8, 26711201Sandreas.hansson@arm.com (uint8_t *)(&pdpe), 8); 26811201Sandreas.hansson@arm.com } 26911201Sandreas.hansson@arm.com 27011201Sandreas.hansson@arm.com // Page Directory Tables 27111201Sandreas.hansson@arm.com 27211201Sandreas.hansson@arm.com Addr base = 0; 27311201Sandreas.hansson@arm.com const Addr pageSize = 2 << 20; 27410515SAli.Saidi@ARM.com for (int table = 0; table < NumPDTs; table++) { 27511201Sandreas.hansson@arm.com for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) { 27611167Sjthestness@gmail.com // read/write, user, present, 4MB 27711167Sjthestness@gmail.com uint64_t pdte = X86ISA::htog(0x87 | base); 27811167Sjthestness@gmail.com physPort->writeBlob(PageDirTable[table] + offset, 27911167Sjthestness@gmail.com (uint8_t *)(&pdte), 8); 28010515SAli.Saidi@ARM.com base += pageSize; 28111138Sandreas.hansson@arm.com } 28211138Sandreas.hansson@arm.com } 28311138Sandreas.hansson@arm.com 28411201Sandreas.hansson@arm.com /* 28511201Sandreas.hansson@arm.com * Transition from real mode all the way up to Long mode 28611201Sandreas.hansson@arm.com */ 28711201Sandreas.hansson@arm.com CR0 cr0 = tc->readMiscRegNoEffect(MISCREG_CR0); 28811167Sjthestness@gmail.com //Turn off paging. 28911201Sandreas.hansson@arm.com cr0.pg = 0; 29011201Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_CR0, cr0); 29111201Sandreas.hansson@arm.com //Turn on protected mode. 29211201Sandreas.hansson@arm.com cr0.pe = 1; 29311201Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_CR0, cr0); 29411201Sandreas.hansson@arm.com 29511201Sandreas.hansson@arm.com CR4 cr4 = tc->readMiscRegNoEffect(MISCREG_CR4); 29611201Sandreas.hansson@arm.com //Turn on pae. 29711201Sandreas.hansson@arm.com cr4.pae = 1; 29811201Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_CR4, cr4); 29911201Sandreas.hansson@arm.com 30011201Sandreas.hansson@arm.com //Point to the page tables. 30111201Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_CR3, PageMapLevel4); 30211201Sandreas.hansson@arm.com 30310628Sandreas.hansson@arm.com Efer efer = tc->readMiscRegNoEffect(MISCREG_EFER); 30411201Sandreas.hansson@arm.com //Enable long mode. 30510628Sandreas.hansson@arm.com efer.lme = 1; 30611201Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_EFER, efer); 30711201Sandreas.hansson@arm.com 30811201Sandreas.hansson@arm.com //Start using longmode segments. 30911201Sandreas.hansson@arm.com installSegDesc(tc, SEGMENT_REG_CS, csDesc, true); 31011201Sandreas.hansson@arm.com installSegDesc(tc, SEGMENT_REG_DS, dsDesc, true); 31111201Sandreas.hansson@arm.com installSegDesc(tc, SEGMENT_REG_ES, dsDesc, true); 31211201Sandreas.hansson@arm.com installSegDesc(tc, SEGMENT_REG_FS, dsDesc, true); 31311201Sandreas.hansson@arm.com installSegDesc(tc, SEGMENT_REG_GS, dsDesc, true); 31411201Sandreas.hansson@arm.com installSegDesc(tc, SEGMENT_REG_SS, dsDesc, true); 31511201Sandreas.hansson@arm.com 31611201Sandreas.hansson@arm.com //Activate long mode. 31710628Sandreas.hansson@arm.com cr0.pg = 1; 31811201Sandreas.hansson@arm.com tc->setMiscReg(MISCREG_CR0, cr0); 31910628Sandreas.hansson@arm.com 32011201Sandreas.hansson@arm.com tc->setPC(tc->getSystemPtr()->kernelEntry); 32110585Sandreas.hansson@arm.com tc->setNextPC(tc->readPC()); 32211201Sandreas.hansson@arm.com 32311201Sandreas.hansson@arm.com // We should now be in long mode. Yay! 32411201Sandreas.hansson@arm.com 32511201Sandreas.hansson@arm.com Addr ebdaPos = 0xF0000; 32610585Sandreas.hansson@arm.com Addr fixed, table; 32711201Sandreas.hansson@arm.com 32811201Sandreas.hansson@arm.com //Write out the SMBios/DMI table 32910585Sandreas.hansson@arm.com writeOutSMBiosTable(ebdaPos, fixed, table); 33011167Sjthestness@gmail.com ebdaPos += (fixed + table); 33111201Sandreas.hansson@arm.com ebdaPos = roundUp(ebdaPos, 16); 33211201Sandreas.hansson@arm.com 33311201Sandreas.hansson@arm.com //Write out the Intel MP Specification configuration table 33410585Sandreas.hansson@arm.com writeOutMPTable(ebdaPos, fixed, table); 33511167Sjthestness@gmail.com ebdaPos += (fixed + table); 33610585Sandreas.hansson@arm.com} 33710585Sandreas.hansson@arm.com 33810585Sandreas.hansson@arm.comvoid 33910585Sandreas.hansson@arm.comX86System::writeOutSMBiosTable(Addr header, 34010585Sandreas.hansson@arm.com Addr &headerSize, Addr &structSize, Addr table) 34110585Sandreas.hansson@arm.com{ 34211201Sandreas.hansson@arm.com // Get a port to write the table and header to memory. 34311201Sandreas.hansson@arm.com FunctionalPort * physPort = threadContexts[0]->getPhysPort(); 34411201Sandreas.hansson@arm.com 34511201Sandreas.hansson@arm.com // If the table location isn't specified, just put it after the header. 34611201Sandreas.hansson@arm.com // The header size as of the 2.5 SMBios specification is 0x1F bytes 34710585Sandreas.hansson@arm.com if (!table) 34811201Sandreas.hansson@arm.com table = header + 0x1F; 34911201Sandreas.hansson@arm.com smbiosTable->setTableAddr(table); 35011201Sandreas.hansson@arm.com 35110585Sandreas.hansson@arm.com smbiosTable->writeOut(physPort, header, headerSize, structSize); 35210628Sandreas.hansson@arm.com 35310628Sandreas.hansson@arm.com // Do some bounds checking to make sure we at least didn't step on 35410628Sandreas.hansson@arm.com // ourselves. 35510628Sandreas.hansson@arm.com assert(header > table || header + headerSize <= table); 35610628Sandreas.hansson@arm.com assert(table > header || table + structSize <= header); 35710628Sandreas.hansson@arm.com} 35810628Sandreas.hansson@arm.com 35910628Sandreas.hansson@arm.comvoid 36010585Sandreas.hansson@arm.comX86System::writeOutMPTable(Addr fp, 36110585Sandreas.hansson@arm.com Addr &fpSize, Addr &tableSize, Addr table) 36210585Sandreas.hansson@arm.com{ 36310585Sandreas.hansson@arm.com // Get a port to write the table and header to memory. 36410585Sandreas.hansson@arm.com FunctionalPort * physPort = threadContexts[0]->getPhysPort(); 36510585Sandreas.hansson@arm.com 36610585Sandreas.hansson@arm.com // If the table location isn't specified and it exists, just put 36710585Sandreas.hansson@arm.com // it after the floating pointer. The fp size as of the 1.4 Intel MP 36810585Sandreas.hansson@arm.com // specification is 0x10 bytes. 36910585Sandreas.hansson@arm.com if (mpConfigTable) { 37010585Sandreas.hansson@arm.com if (!table) 37110585Sandreas.hansson@arm.com table = fp + 0x10; 37210585Sandreas.hansson@arm.com mpFloatingPointer->setTableAddr(table); 37310585Sandreas.hansson@arm.com } 37410585Sandreas.hansson@arm.com 37510585Sandreas.hansson@arm.com fpSize = mpFloatingPointer->writeOut(physPort, fp); 37610585Sandreas.hansson@arm.com if (mpConfigTable) 37710585Sandreas.hansson@arm.com tableSize = mpConfigTable->writeOut(physPort, table); 37810585Sandreas.hansson@arm.com else 37910585Sandreas.hansson@arm.com tableSize = 0; 38010585Sandreas.hansson@arm.com 38111201Sandreas.hansson@arm.com // Do some bounds checking to make sure we at least didn't step on 38211201Sandreas.hansson@arm.com // ourselves and the fp structure was the size we thought it was. 38311201Sandreas.hansson@arm.com assert(fp > table || fp + fpSize <= table); 38411201Sandreas.hansson@arm.com assert(table > fp || table + tableSize <= fp); 38511201Sandreas.hansson@arm.com assert(fpSize == 0x10); 38611201Sandreas.hansson@arm.com} 38711201Sandreas.hansson@arm.com 38811201Sandreas.hansson@arm.com 38911201Sandreas.hansson@arm.comX86System::~X86System() 39011201Sandreas.hansson@arm.com{ 39111201Sandreas.hansson@arm.com delete smbiosTable; 39211201Sandreas.hansson@arm.com} 39311201Sandreas.hansson@arm.com 39411201Sandreas.hansson@arm.comvoid 39511201Sandreas.hansson@arm.comX86System::serialize(std::ostream &os) 39611201Sandreas.hansson@arm.com{ 39711201Sandreas.hansson@arm.com System::serialize(os); 39811201Sandreas.hansson@arm.com} 39911201Sandreas.hansson@arm.com 40011201Sandreas.hansson@arm.com 40111201Sandreas.hansson@arm.comvoid 40211201Sandreas.hansson@arm.comX86System::unserialize(Checkpoint *cp, const std::string §ion) 40311201Sandreas.hansson@arm.com{ 40411201Sandreas.hansson@arm.com System::unserialize(cp,section); 40511201Sandreas.hansson@arm.com} 40611201Sandreas.hansson@arm.com 40711201Sandreas.hansson@arm.comX86System * 40811201Sandreas.hansson@arm.comX86SystemParams::create() 40911201Sandreas.hansson@arm.com{ 41011201Sandreas.hansson@arm.com return new X86System(this); 41111201Sandreas.hansson@arm.com} 41211201Sandreas.hansson@arm.com