system.cc revision 12483:fd8c7ada2fb9
14997Sgblack@eecs.umich.edu/* 25417Sgblack@eecs.umich.edu * Copyright (c) 2007 The Hewlett-Packard Development Company 34997Sgblack@eecs.umich.edu * Copyright (c) 2018 TU Dresden 44997Sgblack@eecs.umich.edu * All rights reserved. 57087Snate@binkert.org * 67087Snate@binkert.org * The license below extends only to copyright in the software and shall 77087Snate@binkert.org * not be construed as granting a license to any other intellectual 87087Snate@binkert.org * property including but not limited to intellectual property relating 97087Snate@binkert.org * to a hardware implementation of the functionality of the software 107087Snate@binkert.org * licensed hereunder. You may use the software subject to the license 117087Snate@binkert.org * terms below provided that you ensure that this notice is replicated 127087Snate@binkert.org * unmodified and in its entirety in all distributions of the software, 134997Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 147087Snate@binkert.org * 157087Snate@binkert.org * Redistribution and use in source and binary forms, with or without 167087Snate@binkert.org * modification, are permitted provided that the following conditions are 177087Snate@binkert.org * met: redistributions of source code must retain the above copyright 187087Snate@binkert.org * notice, this list of conditions and the following disclaimer; 197087Snate@binkert.org * redistributions in binary form must reproduce the above copyright 207087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 217087Snate@binkert.org * documentation and/or other materials provided with the distribution; 224997Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 237087Snate@binkert.org * contributors may be used to endorse or promote products derived from 244997Sgblack@eecs.umich.edu * this software without specific prior written permission. 254997Sgblack@eecs.umich.edu * 264997Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 274997Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 284997Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 294997Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 304997Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 314997Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 324997Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 334997Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 344997Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 354997Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 364997Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 374997Sgblack@eecs.umich.edu * 384997Sgblack@eecs.umich.edu * Authors: Gabe Black 394997Sgblack@eecs.umich.edu * Maximilian Stein 4011793Sbrandon.potter@amd.com */ 4111793Sbrandon.potter@amd.com 424997Sgblack@eecs.umich.edu#include "arch/x86/system.hh" 4310474Sandreas.hansson@arm.com 444997Sgblack@eecs.umich.edu#include "arch/x86/bios/intelmp.hh" 459898Sandreas@sandberg.pp.se#include "arch/x86/bios/smbios.hh" 4611793Sbrandon.potter@amd.com#include "arch/x86/isa_traits.hh" 478229Snate@binkert.org#include "base/loader/object_file.hh" 4811793Sbrandon.potter@amd.com#include "cpu/thread_context.hh" 498229Snate@binkert.org#include "params/X86System.hh" 508582Sgblack@eecs.umich.edu 515149Sgblack@eecs.umich.eduusing namespace LittleEndianGuest; 525086Sgblack@eecs.umich.eduusing namespace X86ISA; 535086Sgblack@eecs.umich.edu 548232Snate@binkert.orgX86System::X86System(Params *p) : 558767Sgblack@eecs.umich.edu System(p), smbiosTable(p->smbios_table), 565086Sgblack@eecs.umich.edu mpFloatingPointer(p->intel_mp_pointer), 578767Sgblack@eecs.umich.edu mpConfigTable(p->intel_mp_table), 585895Sgblack@eecs.umich.edu rsdp(p->acpi_description_table_pointer) 595086Sgblack@eecs.umich.edu{ 605086Sgblack@eecs.umich.edu} 615086Sgblack@eecs.umich.edu 6210905Sandreas.sandberg@arm.comvoid 6310905Sandreas.sandberg@arm.comX86ISA::installSegDesc(ThreadContext *tc, SegmentRegIndex seg, 6410905Sandreas.sandberg@arm.com SegDescriptor desc, bool longmode) 655124Sgblack@eecs.umich.edu{ 668953Sgblack@eecs.umich.edu uint64_t base = desc.baseLow + (desc.baseHigh << 24); 678953Sgblack@eecs.umich.edu bool honorBase = !longmode || seg == SEGMENT_REG_FS || 685124Sgblack@eecs.umich.edu seg == SEGMENT_REG_GS || 698953Sgblack@eecs.umich.edu seg == SEGMENT_REG_TSL || 708953Sgblack@eecs.umich.edu seg == SYS_SEGMENT_REG_TR; 715124Sgblack@eecs.umich.edu uint64_t limit = desc.limitLow | (desc.limitHigh << 16); 728953Sgblack@eecs.umich.edu if (desc.g) 735124Sgblack@eecs.umich.edu limit = (limit << 12) | mask(12); 745245Sgblack@eecs.umich.edu 755245Sgblack@eecs.umich.edu SegAttr attr = 0; 765236Sgblack@eecs.umich.edu 775236Sgblack@eecs.umich.edu attr.dpl = desc.dpl; 788953Sgblack@eecs.umich.edu attr.unusable = 0; 798953Sgblack@eecs.umich.edu attr.defaultSize = desc.d; 808953Sgblack@eecs.umich.edu attr.longMode = desc.l; 818953Sgblack@eecs.umich.edu attr.avl = desc.avl; 828953Sgblack@eecs.umich.edu attr.granularity = desc.g; 838953Sgblack@eecs.umich.edu attr.present = desc.p; 848953Sgblack@eecs.umich.edu attr.system = desc.s; 858953Sgblack@eecs.umich.edu attr.type = desc.type; 868953Sgblack@eecs.umich.edu if (desc.s) { 878953Sgblack@eecs.umich.edu if (desc.type.codeOrData) { 888953Sgblack@eecs.umich.edu // Code segment 898953Sgblack@eecs.umich.edu attr.expandDown = 0; 908953Sgblack@eecs.umich.edu attr.readable = desc.type.r; 918953Sgblack@eecs.umich.edu attr.writable = 0; 928953Sgblack@eecs.umich.edu } else { 938953Sgblack@eecs.umich.edu // Data segment 948953Sgblack@eecs.umich.edu attr.expandDown = desc.type.e; 958953Sgblack@eecs.umich.edu attr.readable = 1; 965895Sgblack@eecs.umich.edu attr.writable = desc.type.w; 9712455Sgabeblack@google.com } 985124Sgblack@eecs.umich.edu } else { 998962Sgblack@eecs.umich.edu attr.readable = 1; 1008962Sgblack@eecs.umich.edu attr.writable = 1; 1018962Sgblack@eecs.umich.edu attr.expandDown = 0; 1029064Snilay@cs.wisc.edu } 1038962Sgblack@eecs.umich.edu 1048962Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_BASE(seg), base); 1055124Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_EFF_BASE(seg), honorBase ? base : 0); 1068953Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_LIMIT(seg), limit); 1078953Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_ATTR(seg), (MiscReg)attr); 1088962Sgblack@eecs.umich.edu} 1098953Sgblack@eecs.umich.edu 1108953Sgblack@eecs.umich.eduvoid 1118953Sgblack@eecs.umich.eduX86System::initState() 1125124Sgblack@eecs.umich.edu{ 1138953Sgblack@eecs.umich.edu System::initState(); 1145124Sgblack@eecs.umich.edu 1158953Sgblack@eecs.umich.edu if (!kernel) 1168962Sgblack@eecs.umich.edu fatal("No kernel to load.\n"); 1175895Sgblack@eecs.umich.edu 1185124Sgblack@eecs.umich.edu if (kernel->getArch() == ObjectFile::I386) 1195124Sgblack@eecs.umich.edu fatal("Loading a 32 bit x86 kernel is not supported.\n"); 1205360Sgblack@eecs.umich.edu 1215360Sgblack@eecs.umich.edu ThreadContext *tc = threadContexts[0]; 1225360Sgblack@eecs.umich.edu // This is the boot strap processor (BSP). Initialize it to look like 1238953Sgblack@eecs.umich.edu // the boot loader has just turned control over to the 64 bit OS. We 1248953Sgblack@eecs.umich.edu // won't actually set up real mode or legacy protected mode descriptor 1258953Sgblack@eecs.umich.edu // tables because we aren't executing any code that would require 1268953Sgblack@eecs.umich.edu // them. We do, however toggle the control bits in the correct order 1275124Sgblack@eecs.umich.edu // while allowing consistency checks and the underlying mechansims 1285124Sgblack@eecs.umich.edu // just to be safe. 1295124Sgblack@eecs.umich.edu 1309423SAndreas.Sandberg@arm.com const int NumPDTs = 4; 1315124Sgblack@eecs.umich.edu 1325242Sgblack@eecs.umich.edu const Addr PageMapLevel4 = 0x70000; 1338953Sgblack@eecs.umich.edu const Addr PageDirPtrTable = 0x71000; 1348953Sgblack@eecs.umich.edu const Addr PageDirTable[NumPDTs] = 1358953Sgblack@eecs.umich.edu {0x72000, 0x73000, 0x74000, 0x75000}; 1368953Sgblack@eecs.umich.edu const Addr GDTBase = 0x76000; 1378953Sgblack@eecs.umich.edu 1388953Sgblack@eecs.umich.edu const int PML4Bits = 9; 1395242Sgblack@eecs.umich.edu const int PDPTBits = 9; 1405124Sgblack@eecs.umich.edu const int PDTBits = 9; 1415124Sgblack@eecs.umich.edu 1425124Sgblack@eecs.umich.edu /* 1435357Sgblack@eecs.umich.edu * Set up the gdt. 1445357Sgblack@eecs.umich.edu */ 1455357Sgblack@eecs.umich.edu uint8_t numGDTEntries = 0; 1465357Sgblack@eecs.umich.edu // Place holder at selector 0 1475357Sgblack@eecs.umich.edu uint64_t nullDescriptor = 0; 1485357Sgblack@eecs.umich.edu physProxy.writeBlob(GDTBase + numGDTEntries * 8, 1499423SAndreas.Sandberg@arm.com (uint8_t *)(&nullDescriptor), 8); 1505124Sgblack@eecs.umich.edu numGDTEntries++; 1515242Sgblack@eecs.umich.edu 1528953Sgblack@eecs.umich.edu SegDescriptor initDesc = 0; 1538953Sgblack@eecs.umich.edu initDesc.type.codeOrData = 0; // code or data type 1548953Sgblack@eecs.umich.edu initDesc.type.c = 0; // conforming 1558953Sgblack@eecs.umich.edu initDesc.type.r = 1; // readable 1568953Sgblack@eecs.umich.edu initDesc.dpl = 0; // privilege 1575242Sgblack@eecs.umich.edu initDesc.p = 1; // present 1585242Sgblack@eecs.umich.edu initDesc.l = 1; // longmode - 64 bit 1595124Sgblack@eecs.umich.edu initDesc.d = 0; // operand size 1605124Sgblack@eecs.umich.edu initDesc.g = 1; // granularity 1615124Sgblack@eecs.umich.edu initDesc.s = 1; // system segment 1625358Sgblack@eecs.umich.edu initDesc.limitHigh = 0xF; 1635086Sgblack@eecs.umich.edu initDesc.limitLow = 0xFFFF; 1648953Sgblack@eecs.umich.edu initDesc.baseHigh = 0x0; 1658953Sgblack@eecs.umich.edu initDesc.baseLow = 0x0; 1668953Sgblack@eecs.umich.edu 1678953Sgblack@eecs.umich.edu //64 bit code segment 1688953Sgblack@eecs.umich.edu SegDescriptor csDesc = initDesc; 1695359Sgblack@eecs.umich.edu csDesc.type.codeOrData = 1; 1705086Sgblack@eecs.umich.edu csDesc.dpl = 0; 1715086Sgblack@eecs.umich.edu //Because we're dealing with a pointer and I don't think it's 1725086Sgblack@eecs.umich.edu //guaranteed that there isn't anything in a nonvirtual class between 17312749Sgiacomo.travaglini@arm.com //it's beginning in memory and it's actual data, we'll use an 1746141Sgblack@eecs.umich.edu //intermediary. 1756141Sgblack@eecs.umich.edu uint64_t csDescVal = csDesc; 1766141Sgblack@eecs.umich.edu physProxy.writeBlob(GDTBase + numGDTEntries * 8, 1776141Sgblack@eecs.umich.edu (uint8_t *)(&csDescVal), 8); 1786141Sgblack@eecs.umich.edu 1796141Sgblack@eecs.umich.edu numGDTEntries++; 1806141Sgblack@eecs.umich.edu 1818582Sgblack@eecs.umich.edu SegSelector cs = 0; 1828105Sgblack@eecs.umich.edu cs.si = numGDTEntries - 1; 1838582Sgblack@eecs.umich.edu 1848582Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CS, (MiscReg)cs); 1858582Sgblack@eecs.umich.edu 18610474Sandreas.hansson@arm.com //32 bit data segment 1878582Sgblack@eecs.umich.edu SegDescriptor dsDesc = initDesc; 18813613Sgabeblack@google.com uint64_t dsDescVal = dsDesc; 1896141Sgblack@eecs.umich.edu physProxy.writeBlob(GDTBase + numGDTEntries * 8, 1906141Sgblack@eecs.umich.edu (uint8_t *)(&dsDescVal), 8); 19113613Sgabeblack@google.com 1926141Sgblack@eecs.umich.edu numGDTEntries++; 1936141Sgblack@eecs.umich.edu 1946141Sgblack@eecs.umich.edu SegSelector ds = 0; 1956141Sgblack@eecs.umich.edu ds.si = numGDTEntries - 1; 1966141Sgblack@eecs.umich.edu 1976141Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_DS, (MiscReg)ds); 1986141Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_ES, (MiscReg)ds); 1996141Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_FS, (MiscReg)ds); 2006141Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_GS, (MiscReg)ds); 2016141Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SS, (MiscReg)ds); 2028105Sgblack@eecs.umich.edu 20313613Sgabeblack@google.com tc->setMiscReg(MISCREG_TSL, 0); 2046141Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TSG_BASE, GDTBase); 20510824SAndreas.Sandberg@ARM.com tc->setMiscReg(MISCREG_TSG_LIMIT, 8 * numGDTEntries - 1); 2066141Sgblack@eecs.umich.edu 2076141Sgblack@eecs.umich.edu SegDescriptor tssDesc = initDesc; 2086141Sgblack@eecs.umich.edu uint64_t tssDescVal = tssDesc; 2096141Sgblack@eecs.umich.edu physProxy.writeBlob(GDTBase + numGDTEntries * 8, 2106141Sgblack@eecs.umich.edu (uint8_t *)(&tssDescVal), 8); 2116141Sgblack@eecs.umich.edu 2128098Sgblack@eecs.umich.edu numGDTEntries++; 2138098Sgblack@eecs.umich.edu 2146141Sgblack@eecs.umich.edu SegSelector tss = 0; 2156141Sgblack@eecs.umich.edu tss.si = numGDTEntries - 1; 21610824SAndreas.Sandberg@ARM.com 2176141Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TR, (MiscReg)tss); 2186141Sgblack@eecs.umich.edu installSegDesc(tc, SYS_SEGMENT_REG_TR, tssDesc, true); 2196141Sgblack@eecs.umich.edu 2206141Sgblack@eecs.umich.edu /* 2216141Sgblack@eecs.umich.edu * Identity map the first 4GB of memory. In order to map this region 2226141Sgblack@eecs.umich.edu * of memory in long mode, there needs to be one actual page map level 2236141Sgblack@eecs.umich.edu * 4 entry which points to one page directory pointer table which 2246141Sgblack@eecs.umich.edu * points to 4 different page directory tables which are full of two 2256141Sgblack@eecs.umich.edu * megabyte pages. All of the other entries in valid tables are set 2266141Sgblack@eecs.umich.edu * to indicate that they don't pertain to anything valid and will 22712749Sgiacomo.travaglini@arm.com * cause a fault if used. 22812749Sgiacomo.travaglini@arm.com */ 2299738Sandreas@sandberg.pp.se 2309738Sandreas@sandberg.pp.se // Put valid values in all of the various table entries which indicate 2319738Sandreas@sandberg.pp.se // that those entries don't point to further tables or pages. Then 23210553Salexandru.dutu@amd.com // set the values of those entries which are needed. 23310553Salexandru.dutu@amd.com 23410553Salexandru.dutu@amd.com // Page Map Level 4 23511874Sbrandon.potter@amd.com 23611874Sbrandon.potter@amd.com // read/write, user, not present 23711874Sbrandon.potter@amd.com uint64_t pml4e = X86ISA::htog(0x6); 23811874Sbrandon.potter@amd.com for (int offset = 0; offset < (1 << PML4Bits) * 8; offset += 8) { 23910553Salexandru.dutu@amd.com physProxy.writeBlob(PageMapLevel4 + offset, (uint8_t *)(&pml4e), 8); 24010553Salexandru.dutu@amd.com } 2419738Sandreas@sandberg.pp.se // Point to the only PDPT 2429738Sandreas@sandberg.pp.se pml4e = X86ISA::htog(0x7 | PageDirPtrTable); 2439738Sandreas@sandberg.pp.se physProxy.writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8); 2449738Sandreas@sandberg.pp.se 2459738Sandreas@sandberg.pp.se // Page Directory Pointer Table 2469738Sandreas@sandberg.pp.se 2479738Sandreas@sandberg.pp.se // read/write, user, not present 2489738Sandreas@sandberg.pp.se uint64_t pdpe = X86ISA::htog(0x6); 2499738Sandreas@sandberg.pp.se for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) { 2509738Sandreas@sandberg.pp.se physProxy.writeBlob(PageDirPtrTable + offset, 2519738Sandreas@sandberg.pp.se (uint8_t *)(&pdpe), 8); 2529738Sandreas@sandberg.pp.se } 2539738Sandreas@sandberg.pp.se // Point to the PDTs 2549738Sandreas@sandberg.pp.se for (int table = 0; table < NumPDTs; table++) { 2559738Sandreas@sandberg.pp.se pdpe = X86ISA::htog(0x7 | PageDirTable[table]); 2569738Sandreas@sandberg.pp.se physProxy.writeBlob(PageDirPtrTable + table * 8, 2579738Sandreas@sandberg.pp.se (uint8_t *)(&pdpe), 8); 2589738Sandreas@sandberg.pp.se } 25910824SAndreas.Sandberg@ARM.com 2609738Sandreas@sandberg.pp.se // Page Directory Tables 2619738Sandreas@sandberg.pp.se 2629738Sandreas@sandberg.pp.se Addr base = 0; 2639738Sandreas@sandberg.pp.se const Addr pageSize = 2 << 20; 2649738Sandreas@sandberg.pp.se for (int table = 0; table < NumPDTs; table++) { 2659738Sandreas@sandberg.pp.se for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) { 2669738Sandreas@sandberg.pp.se // read/write, user, present, 4MB 2679738Sandreas@sandberg.pp.se uint64_t pdte = X86ISA::htog(0x87 | base); 2689738Sandreas@sandberg.pp.se physProxy.writeBlob(PageDirTable[table] + offset, 26912749Sgiacomo.travaglini@arm.com (uint8_t *)(&pdte), 8); 27012749Sgiacomo.travaglini@arm.com base += pageSize; 2716023Snate@binkert.org } 2725086Sgblack@eecs.umich.edu } 27311608Snikos.nikoleris@arm.com 2746141Sgblack@eecs.umich.edu /* 2756141Sgblack@eecs.umich.edu * Transition from real mode all the way up to Long mode 2766141Sgblack@eecs.umich.edu */ 2778535Sgblack@eecs.umich.edu CR0 cr0 = tc->readMiscRegNoEffect(MISCREG_CR0); 2788535Sgblack@eecs.umich.edu //Turn off paging. 2796141Sgblack@eecs.umich.edu cr0.pg = 0; 2806141Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 2816141Sgblack@eecs.umich.edu //Turn on protected mode. 2826141Sgblack@eecs.umich.edu cr0.pe = 1; 2836141Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 2846141Sgblack@eecs.umich.edu 2855124Sgblack@eecs.umich.edu CR4 cr4 = tc->readMiscRegNoEffect(MISCREG_CR4); 2865140Sgblack@eecs.umich.edu //Turn on pae. 2875140Sgblack@eecs.umich.edu cr4.pae = 1; 2886141Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR4, cr4); 2895140Sgblack@eecs.umich.edu 2905140Sgblack@eecs.umich.edu //Point to the page tables. 2916141Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR3, PageMapLevel4); 2925237Sgblack@eecs.umich.edu 2935140Sgblack@eecs.umich.edu Efer efer = tc->readMiscRegNoEffect(MISCREG_EFER); 2946141Sgblack@eecs.umich.edu //Enable long mode. 2955237Sgblack@eecs.umich.edu efer.lme = 1; 2965431Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_EFER, efer); 2976059Sgblack@eecs.umich.edu 2986141Sgblack@eecs.umich.edu //Start using longmode segments. 2996059Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_CS, csDesc, true); 30010474Sandreas.hansson@arm.com installSegDesc(tc, SEGMENT_REG_DS, dsDesc, true); 3015433Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_ES, dsDesc, true); 3025965Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_FS, dsDesc, true); 3035433Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_GS, dsDesc, true); 3046099Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_SS, dsDesc, true); 30510474Sandreas.hansson@arm.com 3066023Snate@binkert.org //Activate long mode. 30710474Sandreas.hansson@arm.com cr0.pg = 1; 3085433Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 3095965Sgblack@eecs.umich.edu 3105433Sgblack@eecs.umich.edu tc->pcState(tc->getSystemPtr()->kernelEntry); 3115140Sgblack@eecs.umich.edu 3125140Sgblack@eecs.umich.edu // We should now be in long mode. Yay! 3135965Sgblack@eecs.umich.edu 3149062Sjayneel@cs.wisc.edu Addr ebdaPos = 0xF0000; 3159062Sjayneel@cs.wisc.edu Addr fixed, table; 3169028Sgblack@eecs.umich.edu 3179028Sgblack@eecs.umich.edu //Write out the SMBios/DMI table 3185965Sgblack@eecs.umich.edu writeOutSMBiosTable(ebdaPos, fixed, table); 3195433Sgblack@eecs.umich.edu ebdaPos += (fixed + table); 3205237Sgblack@eecs.umich.edu ebdaPos = roundUp(ebdaPos, 16); 3215965Sgblack@eecs.umich.edu 3225965Sgblack@eecs.umich.edu //Write out the Intel MP Specification configuration table 32310474Sandreas.hansson@arm.com writeOutMPTable(ebdaPos, fixed, table); 3245140Sgblack@eecs.umich.edu ebdaPos += (fixed + table); 3255965Sgblack@eecs.umich.edu} 32610474Sandreas.hansson@arm.com 3275140Sgblack@eecs.umich.eduvoid 3285140Sgblack@eecs.umich.eduX86System::writeOutSMBiosTable(Addr header, 3299025Sgblack@eecs.umich.edu Addr &headerSize, Addr &structSize, Addr table) 3308925Sgblack@eecs.umich.edu{ 3318925Sgblack@eecs.umich.edu // If the table location isn't specified, just put it after the header. 3325140Sgblack@eecs.umich.edu // The header size as of the 2.5 SMBios specification is 0x1F bytes 3336141Sgblack@eecs.umich.edu if (!table) 3345237Sgblack@eecs.umich.edu table = header + 0x1F; 3355140Sgblack@eecs.umich.edu smbiosTable->setTableAddr(table); 3365140Sgblack@eecs.umich.edu 33712140Sswapnilster@gmail.com smbiosTable->writeOut(physProxy, header, headerSize, structSize); 33812140Sswapnilster@gmail.com 33912140Sswapnilster@gmail.com // Do some bounds checking to make sure we at least didn't step on 34012140Sswapnilster@gmail.com // ourselves. 34112140Sswapnilster@gmail.com assert(header > table || header + headerSize <= table); 3425140Sgblack@eecs.umich.edu assert(table > header || table + structSize <= header); 34312140Sswapnilster@gmail.com} 34412140Sswapnilster@gmail.com 34512140Sswapnilster@gmail.comvoid 34612140Sswapnilster@gmail.comX86System::writeOutMPTable(Addr fp, 34712140Sswapnilster@gmail.com Addr &fpSize, Addr &tableSize, Addr table) 34812140Sswapnilster@gmail.com{ 34912140Sswapnilster@gmail.com // If the table location isn't specified and it exists, just put 35012140Sswapnilster@gmail.com // it after the floating pointer. The fp size as of the 1.4 Intel MP 3518752Sgblack@eecs.umich.edu // specification is 0x10 bytes. 3528752Sgblack@eecs.umich.edu if (mpConfigTable) { 3538752Sgblack@eecs.umich.edu if (!table) 3548752Sgblack@eecs.umich.edu table = fp + 0x10; 3558752Sgblack@eecs.umich.edu mpFloatingPointer->setTableAddr(table); 3568752Sgblack@eecs.umich.edu } 3578752Sgblack@eecs.umich.edu 3588752Sgblack@eecs.umich.edu fpSize = mpFloatingPointer->writeOut(physProxy, fp); 3598752Sgblack@eecs.umich.edu if (mpConfigTable) 3608752Sgblack@eecs.umich.edu tableSize = mpConfigTable->writeOut(physProxy, table); 3618752Sgblack@eecs.umich.edu else 36212461Sgabeblack@google.com tableSize = 0; 36312461Sgabeblack@google.com 36412461Sgabeblack@google.com // Do some bounds checking to make sure we at least didn't step on 3658752Sgblack@eecs.umich.edu // ourselves and the fp structure was the size we thought it was. 3668752Sgblack@eecs.umich.edu assert(fp > table || fp + fpSize <= table); 3678752Sgblack@eecs.umich.edu assert(table > fp || table + tableSize <= fp); 36812461Sgabeblack@google.com assert(fpSize == 0x10); 3698752Sgblack@eecs.umich.edu} 3708752Sgblack@eecs.umich.edu 37112461Sgabeblack@google.com 37210474Sandreas.hansson@arm.comX86System::~X86System() 37310474Sandreas.hansson@arm.com{ 3748752Sgblack@eecs.umich.edu delete smbiosTable; 3758752Sgblack@eecs.umich.edu} 3768752Sgblack@eecs.umich.edu 37712461Sgabeblack@google.comX86System * 37812461Sgabeblack@google.comX86SystemParams::create() 37912461Sgabeblack@google.com{ 38012461Sgabeblack@google.com return new X86System(this); 38112461Sgabeblack@google.com} 3828752Sgblack@eecs.umich.edu