system.cc revision 6712
112854Sgabeblack@google.com/* 212854Sgabeblack@google.com * Copyright (c) 2007 The Hewlett-Packard Development Company 312854Sgabeblack@google.com * All rights reserved. 412854Sgabeblack@google.com * 512854Sgabeblack@google.com * Redistribution and use of this software in source and binary forms, 612854Sgabeblack@google.com * with or without modification, are permitted provided that the 712854Sgabeblack@google.com * following conditions are met: 812854Sgabeblack@google.com * 912854Sgabeblack@google.com * The software must be used only for Non-Commercial Use which means any 1012854Sgabeblack@google.com * use which is NOT directed to receiving any direct monetary 1112854Sgabeblack@google.com * compensation for, or commercial advantage from such use. Illustrative 1212854Sgabeblack@google.com * examples of non-commercial use are academic research, personal study, 1312854Sgabeblack@google.com * teaching, education and corporate research & development. 1412854Sgabeblack@google.com * Illustrative examples of commercial use are distributing products for 1512854Sgabeblack@google.com * commercial advantage and providing services using the software for 1612854Sgabeblack@google.com * commercial advantage. 1712854Sgabeblack@google.com * 1812854Sgabeblack@google.com * If you wish to use this software or functionality therein that may be 1912854Sgabeblack@google.com * covered by patents for commercial use, please contact: 2012854Sgabeblack@google.com * Director of Intellectual Property Licensing 2112854Sgabeblack@google.com * Office of Strategy and Technology 2212854Sgabeblack@google.com * Hewlett-Packard Company 2312854Sgabeblack@google.com * 1501 Page Mill Road 2412854Sgabeblack@google.com * Palo Alto, California 94304 2512854Sgabeblack@google.com * 2612854Sgabeblack@google.com * Redistributions of source code must retain the above copyright notice, 2712854Sgabeblack@google.com * this list of conditions and the following disclaimer. Redistributions 2812854Sgabeblack@google.com * in binary form must reproduce the above copyright notice, this list of 2912854Sgabeblack@google.com * conditions and the following disclaimer in the documentation and/or 3012854Sgabeblack@google.com * other materials provided with the distribution. Neither the name of 3112854Sgabeblack@google.com * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its 3212854Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 3312854Sgabeblack@google.com * this software without specific prior written permission. No right of 3412854Sgabeblack@google.com * sublicense is granted herewith. Derivatives of the software and 3512854Sgabeblack@google.com * output created using the software may be prepared, but only for 3612854Sgabeblack@google.com * Non-Commercial Uses. Derivatives of the software may be shared with 3712854Sgabeblack@google.com * others provided: (i) the others agree to abide by the list of 3812854Sgabeblack@google.com * conditions herein which includes the Non-Commercial Use restrictions; 3912854Sgabeblack@google.com * and (ii) such Derivatives of the software include the above copyright 4012854Sgabeblack@google.com * notice to acknowledge the contribution from this software where 4112854Sgabeblack@google.com * applicable, this list of conditions and the disclaimer below. 4212854Sgabeblack@google.com * 4312854Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 4412854Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 4512854Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 4612854Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 4712854Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4812854Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 4912854Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 5012854Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 5112854Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 5212854Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 5312854Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 5412854Sgabeblack@google.com * 5512854Sgabeblack@google.com * Authors: Gabe Black 5612854Sgabeblack@google.com */ 5712854Sgabeblack@google.com 5812854Sgabeblack@google.com#include "arch/x86/bios/smbios.hh" 5912854Sgabeblack@google.com#include "arch/x86/bios/intelmp.hh" 6012854Sgabeblack@google.com#include "arch/x86/miscregs.hh" 6112854Sgabeblack@google.com#include "arch/x86/system.hh" 6212854Sgabeblack@google.com#include "arch/vtophys.hh" 6312854Sgabeblack@google.com#include "base/intmath.hh" 6412854Sgabeblack@google.com#include "base/loader/object_file.hh" 6512854Sgabeblack@google.com#include "base/loader/symtab.hh" 6612854Sgabeblack@google.com#include "base/remote_gdb.hh" 6712854Sgabeblack@google.com#include "base/trace.hh" 6812854Sgabeblack@google.com#include "cpu/thread_context.hh" 6912854Sgabeblack@google.com#include "mem/physical.hh" 7012854Sgabeblack@google.com#include "params/X86System.hh" 7112854Sgabeblack@google.com#include "sim/byteswap.hh" 7212854Sgabeblack@google.com 7312854Sgabeblack@google.com 7412854Sgabeblack@google.comusing namespace LittleEndianGuest; 7512854Sgabeblack@google.comusing namespace X86ISA; 7612854Sgabeblack@google.com 7712854Sgabeblack@google.comX86System::X86System(Params *p) : 7812854Sgabeblack@google.com System(p), smbiosTable(p->smbios_table), 7912854Sgabeblack@google.com mpFloatingPointer(p->intel_mp_pointer), 8012854Sgabeblack@google.com mpConfigTable(p->intel_mp_table), 8112854Sgabeblack@google.com rsdp(p->acpi_description_table_pointer) 8212854Sgabeblack@google.com{} 8312854Sgabeblack@google.com 8412854Sgabeblack@google.comstatic void 8512854Sgabeblack@google.cominstallSegDesc(ThreadContext *tc, SegmentRegIndex seg, 8612854Sgabeblack@google.com SegDescriptor desc, bool longmode) 8712854Sgabeblack@google.com{ 8812854Sgabeblack@google.com uint64_t base = desc.baseLow + (desc.baseHigh << 24); 8912854Sgabeblack@google.com bool honorBase = !longmode || seg == SEGMENT_REG_FS || 9012854Sgabeblack@google.com seg == SEGMENT_REG_GS || 9112854Sgabeblack@google.com seg == SEGMENT_REG_TSL || 9212854Sgabeblack@google.com seg == SYS_SEGMENT_REG_TR; 9312854Sgabeblack@google.com uint64_t limit = desc.limitLow | (desc.limitHigh << 16); 9412854Sgabeblack@google.com 9512854Sgabeblack@google.com SegAttr attr = 0; 9612854Sgabeblack@google.com 9712854Sgabeblack@google.com attr.dpl = desc.dpl; 9812854Sgabeblack@google.com attr.unusable = 0; 9912854Sgabeblack@google.com attr.defaultSize = desc.d; 10012854Sgabeblack@google.com attr.longMode = desc.l; 10112854Sgabeblack@google.com attr.avl = desc.avl; 10212854Sgabeblack@google.com attr.granularity = desc.g; 10312854Sgabeblack@google.com attr.present = desc.p; 10412854Sgabeblack@google.com attr.system = desc.s; 10512854Sgabeblack@google.com attr.type = desc.type; 10612854Sgabeblack@google.com if (desc.s) { 10712854Sgabeblack@google.com if (desc.type.codeOrData) { 10812854Sgabeblack@google.com // Code segment 10912854Sgabeblack@google.com attr.expandDown = 0; 11012854Sgabeblack@google.com attr.readable = desc.type.r; 11112854Sgabeblack@google.com attr.writable = 0; 11212854Sgabeblack@google.com } else { 11312854Sgabeblack@google.com // Data segment 11412854Sgabeblack@google.com attr.expandDown = desc.type.e; 11512854Sgabeblack@google.com attr.readable = 1; 11612854Sgabeblack@google.com attr.writable = desc.type.w; 11712854Sgabeblack@google.com } 11812854Sgabeblack@google.com } else { 11912854Sgabeblack@google.com attr.readable = 1; 12012854Sgabeblack@google.com attr.writable = 1; 12112854Sgabeblack@google.com attr.expandDown = 0; 12212854Sgabeblack@google.com } 12312854Sgabeblack@google.com 12412854Sgabeblack@google.com tc->setMiscReg(MISCREG_SEG_BASE(seg), base); 12512854Sgabeblack@google.com tc->setMiscReg(MISCREG_SEG_EFF_BASE(seg), honorBase ? base : 0); 12612854Sgabeblack@google.com tc->setMiscReg(MISCREG_SEG_LIMIT(seg), limit); 12712854Sgabeblack@google.com tc->setMiscReg(MISCREG_SEG_ATTR(seg), (MiscReg)attr); 12812854Sgabeblack@google.com} 12912854Sgabeblack@google.com 13012854Sgabeblack@google.comvoid 13112854Sgabeblack@google.comX86System::startup() 13212854Sgabeblack@google.com{ 13312854Sgabeblack@google.com System::startup(); 13412854Sgabeblack@google.com ThreadContext *tc = threadContexts[0]; 13512854Sgabeblack@google.com // This is the boot strap processor (BSP). Initialize it to look like 13612854Sgabeblack@google.com // the boot loader has just turned control over to the 64 bit OS. We 13712854Sgabeblack@google.com // won't actually set up real mode or legacy protected mode descriptor 13812854Sgabeblack@google.com // tables because we aren't executing any code that would require 13912854Sgabeblack@google.com // them. We do, however toggle the control bits in the correct order 14012854Sgabeblack@google.com // while allowing consistency checks and the underlying mechansims 14112854Sgabeblack@google.com // just to be safe. 14212854Sgabeblack@google.com 14312854Sgabeblack@google.com const int NumPDTs = 4; 14412854Sgabeblack@google.com 14512854Sgabeblack@google.com const Addr PageMapLevel4 = 0x70000; 14612854Sgabeblack@google.com const Addr PageDirPtrTable = 0x71000; 14712854Sgabeblack@google.com const Addr PageDirTable[NumPDTs] = 14812854Sgabeblack@google.com {0x72000, 0x73000, 0x74000, 0x75000}; 14912854Sgabeblack@google.com const Addr GDTBase = 0x76000; 15012854Sgabeblack@google.com 15112854Sgabeblack@google.com const int PML4Bits = 9; 15212854Sgabeblack@google.com const int PDPTBits = 9; 15312854Sgabeblack@google.com const int PDTBits = 9; 15412854Sgabeblack@google.com 15512854Sgabeblack@google.com // Get a port to write the page tables and descriptor tables. 15612854Sgabeblack@google.com FunctionalPort * physPort = tc->getPhysPort(); 15712854Sgabeblack@google.com 15812854Sgabeblack@google.com /* 15912854Sgabeblack@google.com * Set up the gdt. 16012854Sgabeblack@google.com */ 16112854Sgabeblack@google.com uint8_t numGDTEntries = 0; 16212854Sgabeblack@google.com // Place holder at selector 0 16312854Sgabeblack@google.com uint64_t nullDescriptor = 0; 16412854Sgabeblack@google.com physPort->writeBlob(GDTBase + numGDTEntries * 8, 16512854Sgabeblack@google.com (uint8_t *)(&nullDescriptor), 8); 16612854Sgabeblack@google.com numGDTEntries++; 16712854Sgabeblack@google.com 16812854Sgabeblack@google.com //64 bit code segment 16912854Sgabeblack@google.com SegDescriptor csDesc = 0; 17012854Sgabeblack@google.com csDesc.type.codeOrData = 1; 17112854Sgabeblack@google.com csDesc.type.c = 0; // Not conforming 17212854Sgabeblack@google.com csDesc.type.r = 1; // Readable 17312854Sgabeblack@google.com csDesc.dpl = 0; // Privelege level 0 17412854Sgabeblack@google.com csDesc.p = 1; // Present 17512854Sgabeblack@google.com csDesc.l = 1; // 64 bit 17612854Sgabeblack@google.com csDesc.d = 0; // default operand size 17712854Sgabeblack@google.com csDesc.g = 1; // Page granularity 17812854Sgabeblack@google.com csDesc.s = 1; // Not a system segment 17912854Sgabeblack@google.com csDesc.limitHigh = 0xF; 18012854Sgabeblack@google.com csDesc.limitLow = 0xFF; 18112854Sgabeblack@google.com //Because we're dealing with a pointer and I don't think it's 18212854Sgabeblack@google.com //guaranteed that there isn't anything in a nonvirtual class between 18312854Sgabeblack@google.com //it's beginning in memory and it's actual data, we'll use an 18412854Sgabeblack@google.com //intermediary. 18512854Sgabeblack@google.com uint64_t csDescVal = csDesc; 18612854Sgabeblack@google.com physPort->writeBlob(GDTBase + numGDTEntries * 8, 18712854Sgabeblack@google.com (uint8_t *)(&csDescVal), 8); 18812854Sgabeblack@google.com 18912854Sgabeblack@google.com numGDTEntries++; 19012854Sgabeblack@google.com 19112854Sgabeblack@google.com SegSelector cs = 0; 19212854Sgabeblack@google.com cs.si = numGDTEntries - 1; 19312854Sgabeblack@google.com 19412854Sgabeblack@google.com tc->setMiscReg(MISCREG_CS, (MiscReg)cs); 19512854Sgabeblack@google.com 19612854Sgabeblack@google.com //32 bit data segment 19712854Sgabeblack@google.com SegDescriptor dsDesc = 0; 19812854Sgabeblack@google.com dsDesc.type.codeOrData = 0; 19912854Sgabeblack@google.com dsDesc.type.e = 0; // Not expand down 20012854Sgabeblack@google.com dsDesc.type.w = 1; // Writable 20112854Sgabeblack@google.com dsDesc.dpl = 0; // Privelege level 0 20212854Sgabeblack@google.com dsDesc.p = 1; // Present 20312854Sgabeblack@google.com dsDesc.d = 1; // default operand size 20412854Sgabeblack@google.com dsDesc.g = 1; // Page granularity 20512854Sgabeblack@google.com dsDesc.s = 1; // Not a system segment 20612854Sgabeblack@google.com dsDesc.limitHigh = 0xF; 20712854Sgabeblack@google.com dsDesc.limitLow = 0xFF; 20812854Sgabeblack@google.com uint64_t dsDescVal = dsDesc; 20912854Sgabeblack@google.com physPort->writeBlob(GDTBase + numGDTEntries * 8, 21012854Sgabeblack@google.com (uint8_t *)(&dsDescVal), 8); 21112854Sgabeblack@google.com 21212854Sgabeblack@google.com numGDTEntries++; 21312854Sgabeblack@google.com 21412854Sgabeblack@google.com SegSelector ds = 0; 21512854Sgabeblack@google.com ds.si = numGDTEntries - 1; 21612854Sgabeblack@google.com 21712854Sgabeblack@google.com tc->setMiscReg(MISCREG_DS, (MiscReg)ds); 21812854Sgabeblack@google.com tc->setMiscReg(MISCREG_ES, (MiscReg)ds); 21912854Sgabeblack@google.com tc->setMiscReg(MISCREG_FS, (MiscReg)ds); 22012854Sgabeblack@google.com tc->setMiscReg(MISCREG_GS, (MiscReg)ds); 22112854Sgabeblack@google.com tc->setMiscReg(MISCREG_SS, (MiscReg)ds); 22212854Sgabeblack@google.com 22312854Sgabeblack@google.com tc->setMiscReg(MISCREG_TSL, 0); 22412854Sgabeblack@google.com tc->setMiscReg(MISCREG_TSG_BASE, GDTBase); 22512854Sgabeblack@google.com tc->setMiscReg(MISCREG_TSG_LIMIT, 8 * numGDTEntries - 1); 22612854Sgabeblack@google.com 22712854Sgabeblack@google.com SegDescriptor tssDesc = 0; 22812854Sgabeblack@google.com tssDesc.type = 0xB; 22912854Sgabeblack@google.com tssDesc.dpl = 0; // Privelege level 0 23012854Sgabeblack@google.com tssDesc.p = 1; // Present 23112854Sgabeblack@google.com tssDesc.d = 1; // default operand size 23212854Sgabeblack@google.com tssDesc.g = 1; // Page granularity 23312854Sgabeblack@google.com tssDesc.s = 1; // Not a system segment 23412854Sgabeblack@google.com tssDesc.limitHigh = 0xF; 23512854Sgabeblack@google.com tssDesc.limitLow = 0xFF; 23612854Sgabeblack@google.com uint64_t tssDescVal = tssDesc; 23712854Sgabeblack@google.com physPort->writeBlob(GDTBase + numGDTEntries * 8, 23812854Sgabeblack@google.com (uint8_t *)(&tssDescVal), 8); 23912854Sgabeblack@google.com 24012854Sgabeblack@google.com numGDTEntries++; 24112854Sgabeblack@google.com 24212854Sgabeblack@google.com SegSelector tss = 0; 24312854Sgabeblack@google.com tss.si = numGDTEntries - 1; 24412854Sgabeblack@google.com 24512854Sgabeblack@google.com tc->setMiscReg(MISCREG_TR, (MiscReg)tss); 24612854Sgabeblack@google.com installSegDesc(tc, SYS_SEGMENT_REG_TR, tssDesc, true); 24712854Sgabeblack@google.com 24812854Sgabeblack@google.com /* 24912854Sgabeblack@google.com * Identity map the first 4GB of memory. In order to map this region 25012854Sgabeblack@google.com * of memory in long mode, there needs to be one actual page map level 25112854Sgabeblack@google.com * 4 entry which points to one page directory pointer table which 25212854Sgabeblack@google.com * points to 4 different page directory tables which are full of two 25312854Sgabeblack@google.com * megabyte pages. All of the other entries in valid tables are set 25412854Sgabeblack@google.com * to indicate that they don't pertain to anything valid and will 25512854Sgabeblack@google.com * cause a fault if used. 25612854Sgabeblack@google.com */ 25712854Sgabeblack@google.com 25812854Sgabeblack@google.com // Put valid values in all of the various table entries which indicate 25912854Sgabeblack@google.com // that those entries don't point to further tables or pages. Then 26012854Sgabeblack@google.com // set the values of those entries which are needed. 26112854Sgabeblack@google.com 26212854Sgabeblack@google.com // Page Map Level 4 26312854Sgabeblack@google.com 26412854Sgabeblack@google.com // read/write, user, not present 26512854Sgabeblack@google.com uint64_t pml4e = X86ISA::htog(0x6); 26612854Sgabeblack@google.com for (int offset = 0; offset < (1 << PML4Bits) * 8; offset += 8) { 26712854Sgabeblack@google.com physPort->writeBlob(PageMapLevel4 + offset, (uint8_t *)(&pml4e), 8); 26812854Sgabeblack@google.com } 26912854Sgabeblack@google.com // Point to the only PDPT 27012854Sgabeblack@google.com pml4e = X86ISA::htog(0x7 | PageDirPtrTable); 27112854Sgabeblack@google.com physPort->writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8); 27212854Sgabeblack@google.com 27312854Sgabeblack@google.com // Page Directory Pointer Table 27412854Sgabeblack@google.com 27512854Sgabeblack@google.com // read/write, user, not present 27612854Sgabeblack@google.com uint64_t pdpe = X86ISA::htog(0x6); 27712854Sgabeblack@google.com for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) { 27812854Sgabeblack@google.com physPort->writeBlob(PageDirPtrTable + offset, 27912854Sgabeblack@google.com (uint8_t *)(&pdpe), 8); 28012854Sgabeblack@google.com } 28112854Sgabeblack@google.com // Point to the PDTs 28212854Sgabeblack@google.com for (int table = 0; table < NumPDTs; table++) { 28312854Sgabeblack@google.com pdpe = X86ISA::htog(0x7 | PageDirTable[table]); 28412854Sgabeblack@google.com physPort->writeBlob(PageDirPtrTable + table * 8, 28512854Sgabeblack@google.com (uint8_t *)(&pdpe), 8); 28612854Sgabeblack@google.com } 28712854Sgabeblack@google.com 28812854Sgabeblack@google.com // Page Directory Tables 28912854Sgabeblack@google.com 29012854Sgabeblack@google.com Addr base = 0; 29112854Sgabeblack@google.com const Addr pageSize = 2 << 20; 29212854Sgabeblack@google.com for (int table = 0; table < NumPDTs; table++) { 29312854Sgabeblack@google.com for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) { 29412854Sgabeblack@google.com // read/write, user, present, 4MB 29512854Sgabeblack@google.com uint64_t pdte = X86ISA::htog(0x87 | base); 29612854Sgabeblack@google.com physPort->writeBlob(PageDirTable[table] + offset, 29712854Sgabeblack@google.com (uint8_t *)(&pdte), 8); 29812854Sgabeblack@google.com base += pageSize; 29912854Sgabeblack@google.com } 30012854Sgabeblack@google.com } 30112854Sgabeblack@google.com 30212854Sgabeblack@google.com /* 30312854Sgabeblack@google.com * Transition from real mode all the way up to Long mode 30412854Sgabeblack@google.com */ 30512854Sgabeblack@google.com CR0 cr0 = tc->readMiscRegNoEffect(MISCREG_CR0); 30612854Sgabeblack@google.com //Turn off paging. 30712854Sgabeblack@google.com cr0.pg = 0; 30812854Sgabeblack@google.com tc->setMiscReg(MISCREG_CR0, cr0); 30912854Sgabeblack@google.com //Turn on protected mode. 31012854Sgabeblack@google.com cr0.pe = 1; 31112854Sgabeblack@google.com tc->setMiscReg(MISCREG_CR0, cr0); 31212854Sgabeblack@google.com 31312854Sgabeblack@google.com CR4 cr4 = tc->readMiscRegNoEffect(MISCREG_CR4); 31412854Sgabeblack@google.com //Turn on pae. 31512854Sgabeblack@google.com cr4.pae = 1; 31612854Sgabeblack@google.com tc->setMiscReg(MISCREG_CR4, cr4); 31712854Sgabeblack@google.com 31812854Sgabeblack@google.com //Point to the page tables. 31912854Sgabeblack@google.com tc->setMiscReg(MISCREG_CR3, PageMapLevel4); 32012854Sgabeblack@google.com 32112854Sgabeblack@google.com Efer efer = tc->readMiscRegNoEffect(MISCREG_EFER); 32212854Sgabeblack@google.com //Enable long mode. 32312854Sgabeblack@google.com efer.lme = 1; 32412854Sgabeblack@google.com tc->setMiscReg(MISCREG_EFER, efer); 32512854Sgabeblack@google.com 32612854Sgabeblack@google.com //Start using longmode segments. 32712854Sgabeblack@google.com installSegDesc(tc, SEGMENT_REG_CS, csDesc, true); 32812854Sgabeblack@google.com installSegDesc(tc, SEGMENT_REG_DS, dsDesc, true); 32912854Sgabeblack@google.com installSegDesc(tc, SEGMENT_REG_ES, dsDesc, true); 33012854Sgabeblack@google.com installSegDesc(tc, SEGMENT_REG_FS, dsDesc, true); 33112854Sgabeblack@google.com installSegDesc(tc, SEGMENT_REG_GS, dsDesc, true); 33212854Sgabeblack@google.com installSegDesc(tc, SEGMENT_REG_SS, dsDesc, true); 33312854Sgabeblack@google.com 33412854Sgabeblack@google.com //Activate long mode. 33512854Sgabeblack@google.com cr0.pg = 1; 33612854Sgabeblack@google.com tc->setMiscReg(MISCREG_CR0, cr0); 33712854Sgabeblack@google.com 33812854Sgabeblack@google.com tc->setPC(tc->getSystemPtr()->kernelEntry); 33912854Sgabeblack@google.com tc->setNextPC(tc->readPC()); 34012854Sgabeblack@google.com 34112854Sgabeblack@google.com // We should now be in long mode. Yay! 34212854Sgabeblack@google.com 34312854Sgabeblack@google.com Addr ebdaPos = 0xF0000; 34412854Sgabeblack@google.com Addr fixed, table; 34512854Sgabeblack@google.com 34612854Sgabeblack@google.com //Write out the SMBios/DMI table 34712854Sgabeblack@google.com writeOutSMBiosTable(ebdaPos, fixed, table); 34812854Sgabeblack@google.com ebdaPos += (fixed + table); 34912854Sgabeblack@google.com ebdaPos = roundUp(ebdaPos, 16); 35012854Sgabeblack@google.com 35112854Sgabeblack@google.com //Write out the Intel MP Specification configuration table 35212854Sgabeblack@google.com writeOutMPTable(ebdaPos, fixed, table); 35312854Sgabeblack@google.com ebdaPos += (fixed + table); 35412854Sgabeblack@google.com} 35512854Sgabeblack@google.com 35612854Sgabeblack@google.comvoid 35712854Sgabeblack@google.comX86System::writeOutSMBiosTable(Addr header, 35812854Sgabeblack@google.com Addr &headerSize, Addr &structSize, Addr table) 35912854Sgabeblack@google.com{ 36012854Sgabeblack@google.com // Get a port to write the table and header to memory. 36112854Sgabeblack@google.com FunctionalPort * physPort = threadContexts[0]->getPhysPort(); 36212854Sgabeblack@google.com 36312854Sgabeblack@google.com // If the table location isn't specified, just put it after the header. 36412854Sgabeblack@google.com // The header size as of the 2.5 SMBios specification is 0x1F bytes 36512854Sgabeblack@google.com if (!table) 36612854Sgabeblack@google.com table = header + 0x1F; 36712854Sgabeblack@google.com smbiosTable->setTableAddr(table); 36812854Sgabeblack@google.com 36912854Sgabeblack@google.com smbiosTable->writeOut(physPort, header, headerSize, structSize); 37012854Sgabeblack@google.com 37112854Sgabeblack@google.com // Do some bounds checking to make sure we at least didn't step on 37212854Sgabeblack@google.com // ourselves. 37312854Sgabeblack@google.com assert(header > table || header + headerSize <= table); 37412854Sgabeblack@google.com assert(table > header || table + structSize <= header); 37512854Sgabeblack@google.com} 37612854Sgabeblack@google.com 37712854Sgabeblack@google.comvoid 37812854Sgabeblack@google.comX86System::writeOutMPTable(Addr fp, 37912854Sgabeblack@google.com Addr &fpSize, Addr &tableSize, Addr table) 38012854Sgabeblack@google.com{ 38112854Sgabeblack@google.com // Get a port to write the table and header to memory. 38212854Sgabeblack@google.com FunctionalPort * physPort = threadContexts[0]->getPhysPort(); 38312854Sgabeblack@google.com 38412854Sgabeblack@google.com // If the table location isn't specified and it exists, just put 38512854Sgabeblack@google.com // it after the floating pointer. The fp size as of the 1.4 Intel MP 38612854Sgabeblack@google.com // specification is 0x10 bytes. 38712854Sgabeblack@google.com if (mpConfigTable) { 38812854Sgabeblack@google.com if (!table) 38912854Sgabeblack@google.com table = fp + 0x10; 39012854Sgabeblack@google.com mpFloatingPointer->setTableAddr(table); 39112854Sgabeblack@google.com } 39212854Sgabeblack@google.com 39312854Sgabeblack@google.com fpSize = mpFloatingPointer->writeOut(physPort, fp); 39412854Sgabeblack@google.com if (mpConfigTable) 39512854Sgabeblack@google.com tableSize = mpConfigTable->writeOut(physPort, table); 39612854Sgabeblack@google.com else 39712854Sgabeblack@google.com tableSize = 0; 39812854Sgabeblack@google.com 39912854Sgabeblack@google.com // Do some bounds checking to make sure we at least didn't step on 40012854Sgabeblack@google.com // ourselves and the fp structure was the size we thought it was. 40112854Sgabeblack@google.com assert(fp > table || fp + fpSize <= table); 40212854Sgabeblack@google.com assert(table > fp || table + tableSize <= fp); 40312854Sgabeblack@google.com assert(fpSize == 0x10); 40412854Sgabeblack@google.com} 40512854Sgabeblack@google.com 40612854Sgabeblack@google.com 40712854Sgabeblack@google.comX86System::~X86System() 40812854Sgabeblack@google.com{ 40912854Sgabeblack@google.com delete smbiosTable; 41012854Sgabeblack@google.com} 41112854Sgabeblack@google.com 41212854Sgabeblack@google.comvoid 41312854Sgabeblack@google.comX86System::serialize(std::ostream &os) 41412854Sgabeblack@google.com{ 41512854Sgabeblack@google.com System::serialize(os); 41612854Sgabeblack@google.com} 41712854Sgabeblack@google.com 41812854Sgabeblack@google.com 41912854Sgabeblack@google.comvoid 42012854Sgabeblack@google.comX86System::unserialize(Checkpoint *cp, const std::string §ion) 42112854Sgabeblack@google.com{ 42212854Sgabeblack@google.com System::unserialize(cp,section); 42312854Sgabeblack@google.com} 42412854Sgabeblack@google.com 42512854Sgabeblack@google.comX86System * 42612854Sgabeblack@google.comX86SystemParams::create() 42712854Sgabeblack@google.com{ 42812854Sgabeblack@google.com return new X86System(this); 42912854Sgabeblack@google.com} 43012854Sgabeblack@google.com