system.cc revision 11793
15132Sgblack@eecs.umich.edu/* 25132Sgblack@eecs.umich.edu * Copyright (c) 2007 The Hewlett-Packard Development Company 35132Sgblack@eecs.umich.edu * All rights reserved. 45132Sgblack@eecs.umich.edu * 57087Snate@binkert.org * The license below extends only to copyright in the software and shall 67087Snate@binkert.org * not be construed as granting a license to any other intellectual 77087Snate@binkert.org * property including but not limited to intellectual property relating 87087Snate@binkert.org * to a hardware implementation of the functionality of the software 97087Snate@binkert.org * licensed hereunder. You may use the software subject to the license 107087Snate@binkert.org * terms below provided that you ensure that this notice is replicated 117087Snate@binkert.org * unmodified and in its entirety in all distributions of the software, 127087Snate@binkert.org * modified or unmodified, in source code or in binary form. 135132Sgblack@eecs.umich.edu * 147087Snate@binkert.org * Redistribution and use in source and binary forms, with or without 157087Snate@binkert.org * modification, are permitted provided that the following conditions are 167087Snate@binkert.org * met: redistributions of source code must retain the above copyright 177087Snate@binkert.org * notice, this list of conditions and the following disclaimer; 187087Snate@binkert.org * redistributions in binary form must reproduce the above copyright 197087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 207087Snate@binkert.org * documentation and/or other materials provided with the distribution; 217087Snate@binkert.org * neither the name of the copyright holders nor the names of its 225132Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 237087Snate@binkert.org * this software without specific prior written permission. 245132Sgblack@eecs.umich.edu * 255132Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 265132Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 275132Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 285132Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 295132Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 305132Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 315132Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 325132Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 335132Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 345132Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 355132Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 365132Sgblack@eecs.umich.edu * 375132Sgblack@eecs.umich.edu * Authors: Gabe Black 385132Sgblack@eecs.umich.edu */ 395132Sgblack@eecs.umich.edu 4011793Sbrandon.potter@amd.com#include "arch/x86/system.hh" 4111793Sbrandon.potter@amd.com 4211793Sbrandon.potter@amd.com#include "arch/vtophys.hh" 438229Snate@binkert.org#include "arch/x86/bios/intelmp.hh" 445612Sgblack@eecs.umich.edu#include "arch/x86/bios/smbios.hh" 4511793Sbrandon.potter@amd.com#include "arch/x86/isa_traits.hh" 468229Snate@binkert.org#include "arch/x86/regs/misc.hh" 4711793Sbrandon.potter@amd.com#include "base/intmath.hh" 485132Sgblack@eecs.umich.edu#include "base/loader/object_file.hh" 495132Sgblack@eecs.umich.edu#include "base/loader/symtab.hh" 505132Sgblack@eecs.umich.edu#include "base/trace.hh" 515299Sgblack@eecs.umich.edu#include "cpu/thread_context.hh" 528706Sandreas.hansson@arm.com#include "mem/port_proxy.hh" 535132Sgblack@eecs.umich.edu#include "params/X86System.hh" 545132Sgblack@eecs.umich.edu#include "sim/byteswap.hh" 555132Sgblack@eecs.umich.edu 565299Sgblack@eecs.umich.eduusing namespace LittleEndianGuest; 575299Sgblack@eecs.umich.eduusing namespace X86ISA; 585132Sgblack@eecs.umich.edu 595625Sgblack@eecs.umich.eduX86System::X86System(Params *p) : 605625Sgblack@eecs.umich.edu System(p), smbiosTable(p->smbios_table), 615625Sgblack@eecs.umich.edu mpFloatingPointer(p->intel_mp_pointer), 625627Sgblack@eecs.umich.edu mpConfigTable(p->intel_mp_table), 635627Sgblack@eecs.umich.edu rsdp(p->acpi_description_table_pointer) 647704Sgblack@eecs.umich.edu{ 657704Sgblack@eecs.umich.edu} 665132Sgblack@eecs.umich.edu 6710554Salexandru.dutu@amd.comvoid 6810554Salexandru.dutu@amd.comX86ISA::installSegDesc(ThreadContext *tc, SegmentRegIndex seg, 696220Sgblack@eecs.umich.edu SegDescriptor desc, bool longmode) 706220Sgblack@eecs.umich.edu{ 716220Sgblack@eecs.umich.edu uint64_t base = desc.baseLow + (desc.baseHigh << 24); 726220Sgblack@eecs.umich.edu bool honorBase = !longmode || seg == SEGMENT_REG_FS || 736220Sgblack@eecs.umich.edu seg == SEGMENT_REG_GS || 746220Sgblack@eecs.umich.edu seg == SEGMENT_REG_TSL || 756220Sgblack@eecs.umich.edu seg == SYS_SEGMENT_REG_TR; 766220Sgblack@eecs.umich.edu uint64_t limit = desc.limitLow | (desc.limitHigh << 16); 776220Sgblack@eecs.umich.edu 786220Sgblack@eecs.umich.edu SegAttr attr = 0; 796222Sgblack@eecs.umich.edu 806222Sgblack@eecs.umich.edu attr.dpl = desc.dpl; 816222Sgblack@eecs.umich.edu attr.unusable = 0; 826222Sgblack@eecs.umich.edu attr.defaultSize = desc.d; 836222Sgblack@eecs.umich.edu attr.longMode = desc.l; 846222Sgblack@eecs.umich.edu attr.avl = desc.avl; 856222Sgblack@eecs.umich.edu attr.granularity = desc.g; 866222Sgblack@eecs.umich.edu attr.present = desc.p; 876222Sgblack@eecs.umich.edu attr.system = desc.s; 886222Sgblack@eecs.umich.edu attr.type = desc.type; 896220Sgblack@eecs.umich.edu if (desc.s) { 906220Sgblack@eecs.umich.edu if (desc.type.codeOrData) { 916220Sgblack@eecs.umich.edu // Code segment 926222Sgblack@eecs.umich.edu attr.expandDown = 0; 936220Sgblack@eecs.umich.edu attr.readable = desc.type.r; 946222Sgblack@eecs.umich.edu attr.writable = 0; 956220Sgblack@eecs.umich.edu } else { 966220Sgblack@eecs.umich.edu // Data segment 976222Sgblack@eecs.umich.edu attr.expandDown = desc.type.e; 986220Sgblack@eecs.umich.edu attr.readable = 1; 996220Sgblack@eecs.umich.edu attr.writable = desc.type.w; 1006220Sgblack@eecs.umich.edu } 1016220Sgblack@eecs.umich.edu } else { 1026222Sgblack@eecs.umich.edu attr.readable = 1; 1036220Sgblack@eecs.umich.edu attr.writable = 1; 1046220Sgblack@eecs.umich.edu attr.expandDown = 0; 1056220Sgblack@eecs.umich.edu } 1066220Sgblack@eecs.umich.edu 1076220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_BASE(seg), base); 1086220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_EFF_BASE(seg), honorBase ? base : 0); 1096220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_LIMIT(seg), limit); 1106220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_ATTR(seg), (MiscReg)attr); 1116220Sgblack@eecs.umich.edu} 1126220Sgblack@eecs.umich.edu 1135299Sgblack@eecs.umich.eduvoid 1147532Ssteve.reinhardt@amd.comX86System::initState() 1155299Sgblack@eecs.umich.edu{ 1167532Ssteve.reinhardt@amd.com System::initState(); 1177532Ssteve.reinhardt@amd.com 1188958Sgblack@eecs.umich.edu if (!kernel) 1198958Sgblack@eecs.umich.edu fatal("No kernel to load.\n"); 1208958Sgblack@eecs.umich.edu 1218706Sandreas.hansson@arm.com if (kernel->getArch() == ObjectFile::I386) 1228706Sandreas.hansson@arm.com fatal("Loading a 32 bit x86 kernel is not supported.\n"); 1238706Sandreas.hansson@arm.com 1246220Sgblack@eecs.umich.edu ThreadContext *tc = threadContexts[0]; 1255299Sgblack@eecs.umich.edu // This is the boot strap processor (BSP). Initialize it to look like 1265299Sgblack@eecs.umich.edu // the boot loader has just turned control over to the 64 bit OS. We 1275299Sgblack@eecs.umich.edu // won't actually set up real mode or legacy protected mode descriptor 1285299Sgblack@eecs.umich.edu // tables because we aren't executing any code that would require 1295299Sgblack@eecs.umich.edu // them. We do, however toggle the control bits in the correct order 1305299Sgblack@eecs.umich.edu // while allowing consistency checks and the underlying mechansims 1315299Sgblack@eecs.umich.edu // just to be safe. 1325299Sgblack@eecs.umich.edu 1335299Sgblack@eecs.umich.edu const int NumPDTs = 4; 1345299Sgblack@eecs.umich.edu 1355299Sgblack@eecs.umich.edu const Addr PageMapLevel4 = 0x70000; 1365299Sgblack@eecs.umich.edu const Addr PageDirPtrTable = 0x71000; 1375299Sgblack@eecs.umich.edu const Addr PageDirTable[NumPDTs] = 1385299Sgblack@eecs.umich.edu {0x72000, 0x73000, 0x74000, 0x75000}; 1395299Sgblack@eecs.umich.edu const Addr GDTBase = 0x76000; 1405299Sgblack@eecs.umich.edu 1415299Sgblack@eecs.umich.edu const int PML4Bits = 9; 1425299Sgblack@eecs.umich.edu const int PDPTBits = 9; 1435299Sgblack@eecs.umich.edu const int PDTBits = 9; 1445299Sgblack@eecs.umich.edu 1455299Sgblack@eecs.umich.edu /* 1465299Sgblack@eecs.umich.edu * Set up the gdt. 1475299Sgblack@eecs.umich.edu */ 1486220Sgblack@eecs.umich.edu uint8_t numGDTEntries = 0; 1495299Sgblack@eecs.umich.edu // Place holder at selector 0 1505299Sgblack@eecs.umich.edu uint64_t nullDescriptor = 0; 1518852Sandreas.hansson@arm.com physProxy.writeBlob(GDTBase + numGDTEntries * 8, 1528852Sandreas.hansson@arm.com (uint8_t *)(&nullDescriptor), 8); 1536220Sgblack@eecs.umich.edu numGDTEntries++; 1545299Sgblack@eecs.umich.edu 15510554Salexandru.dutu@amd.com SegDescriptor initDesc = 0; 15610554Salexandru.dutu@amd.com initDesc.type.codeOrData = 0; // code or data type 15710554Salexandru.dutu@amd.com initDesc.type.c = 0; // conforming 15810554Salexandru.dutu@amd.com initDesc.type.r = 1; // readable 15910554Salexandru.dutu@amd.com initDesc.dpl = 0; // privilege 16010554Salexandru.dutu@amd.com initDesc.p = 1; // present 16110554Salexandru.dutu@amd.com initDesc.l = 1; // longmode - 64 bit 16210554Salexandru.dutu@amd.com initDesc.d = 0; // operand size 16310554Salexandru.dutu@amd.com initDesc.g = 1; // granularity 16410554Salexandru.dutu@amd.com initDesc.s = 1; // system segment 16510554Salexandru.dutu@amd.com initDesc.limitHigh = 0xFFFF; 16610554Salexandru.dutu@amd.com initDesc.limitLow = 0xF; 16710554Salexandru.dutu@amd.com initDesc.baseHigh = 0x0; 16810554Salexandru.dutu@amd.com initDesc.baseLow = 0x0; 16910554Salexandru.dutu@amd.com 1705299Sgblack@eecs.umich.edu //64 bit code segment 17110554Salexandru.dutu@amd.com SegDescriptor csDesc = initDesc; 1726220Sgblack@eecs.umich.edu csDesc.type.codeOrData = 1; 17310554Salexandru.dutu@amd.com csDesc.dpl = 0; 1745299Sgblack@eecs.umich.edu //Because we're dealing with a pointer and I don't think it's 1755299Sgblack@eecs.umich.edu //guaranteed that there isn't anything in a nonvirtual class between 1765299Sgblack@eecs.umich.edu //it's beginning in memory and it's actual data, we'll use an 1775299Sgblack@eecs.umich.edu //intermediary. 1785299Sgblack@eecs.umich.edu uint64_t csDescVal = csDesc; 1798852Sandreas.hansson@arm.com physProxy.writeBlob(GDTBase + numGDTEntries * 8, 1808852Sandreas.hansson@arm.com (uint8_t *)(&csDescVal), 8); 1815299Sgblack@eecs.umich.edu 1826220Sgblack@eecs.umich.edu numGDTEntries++; 1836220Sgblack@eecs.umich.edu 1846220Sgblack@eecs.umich.edu SegSelector cs = 0; 1856220Sgblack@eecs.umich.edu cs.si = numGDTEntries - 1; 1866220Sgblack@eecs.umich.edu 1876220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CS, (MiscReg)cs); 1886220Sgblack@eecs.umich.edu 1896220Sgblack@eecs.umich.edu //32 bit data segment 19010554Salexandru.dutu@amd.com SegDescriptor dsDesc = initDesc; 1916220Sgblack@eecs.umich.edu uint64_t dsDescVal = dsDesc; 1928852Sandreas.hansson@arm.com physProxy.writeBlob(GDTBase + numGDTEntries * 8, 1938852Sandreas.hansson@arm.com (uint8_t *)(&dsDescVal), 8); 1946220Sgblack@eecs.umich.edu 1956220Sgblack@eecs.umich.edu numGDTEntries++; 1966220Sgblack@eecs.umich.edu 1976712Snate@binkert.org SegSelector ds = 0; 1986220Sgblack@eecs.umich.edu ds.si = numGDTEntries - 1; 1996220Sgblack@eecs.umich.edu 2006220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_DS, (MiscReg)ds); 2016220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_ES, (MiscReg)ds); 2026220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_FS, (MiscReg)ds); 2036220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_GS, (MiscReg)ds); 2046220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SS, (MiscReg)ds); 2056220Sgblack@eecs.umich.edu 2066220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TSL, 0); 2076220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TSG_BASE, GDTBase); 2086220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TSG_LIMIT, 8 * numGDTEntries - 1); 2096220Sgblack@eecs.umich.edu 21010554Salexandru.dutu@amd.com SegDescriptor tssDesc = initDesc; 2116220Sgblack@eecs.umich.edu uint64_t tssDescVal = tssDesc; 2128852Sandreas.hansson@arm.com physProxy.writeBlob(GDTBase + numGDTEntries * 8, 2138852Sandreas.hansson@arm.com (uint8_t *)(&tssDescVal), 8); 2146220Sgblack@eecs.umich.edu 2156220Sgblack@eecs.umich.edu numGDTEntries++; 2166220Sgblack@eecs.umich.edu 2176220Sgblack@eecs.umich.edu SegSelector tss = 0; 2186220Sgblack@eecs.umich.edu tss.si = numGDTEntries - 1; 2196220Sgblack@eecs.umich.edu 2206220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TR, (MiscReg)tss); 2216220Sgblack@eecs.umich.edu installSegDesc(tc, SYS_SEGMENT_REG_TR, tssDesc, true); 2225299Sgblack@eecs.umich.edu 2235299Sgblack@eecs.umich.edu /* 2245299Sgblack@eecs.umich.edu * Identity map the first 4GB of memory. In order to map this region 2255299Sgblack@eecs.umich.edu * of memory in long mode, there needs to be one actual page map level 2265299Sgblack@eecs.umich.edu * 4 entry which points to one page directory pointer table which 2275299Sgblack@eecs.umich.edu * points to 4 different page directory tables which are full of two 2285299Sgblack@eecs.umich.edu * megabyte pages. All of the other entries in valid tables are set 2295299Sgblack@eecs.umich.edu * to indicate that they don't pertain to anything valid and will 2305299Sgblack@eecs.umich.edu * cause a fault if used. 2315299Sgblack@eecs.umich.edu */ 2325299Sgblack@eecs.umich.edu 2335299Sgblack@eecs.umich.edu // Put valid values in all of the various table entries which indicate 2345299Sgblack@eecs.umich.edu // that those entries don't point to further tables or pages. Then 2355299Sgblack@eecs.umich.edu // set the values of those entries which are needed. 2365299Sgblack@eecs.umich.edu 2375299Sgblack@eecs.umich.edu // Page Map Level 4 2385299Sgblack@eecs.umich.edu 2395299Sgblack@eecs.umich.edu // read/write, user, not present 2405299Sgblack@eecs.umich.edu uint64_t pml4e = X86ISA::htog(0x6); 2415299Sgblack@eecs.umich.edu for (int offset = 0; offset < (1 << PML4Bits) * 8; offset += 8) { 2428852Sandreas.hansson@arm.com physProxy.writeBlob(PageMapLevel4 + offset, (uint8_t *)(&pml4e), 8); 2435299Sgblack@eecs.umich.edu } 2445299Sgblack@eecs.umich.edu // Point to the only PDPT 2455299Sgblack@eecs.umich.edu pml4e = X86ISA::htog(0x7 | PageDirPtrTable); 2468852Sandreas.hansson@arm.com physProxy.writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8); 2475299Sgblack@eecs.umich.edu 2485299Sgblack@eecs.umich.edu // Page Directory Pointer Table 2495299Sgblack@eecs.umich.edu 2505299Sgblack@eecs.umich.edu // read/write, user, not present 2515299Sgblack@eecs.umich.edu uint64_t pdpe = X86ISA::htog(0x6); 2525299Sgblack@eecs.umich.edu for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) { 2538852Sandreas.hansson@arm.com physProxy.writeBlob(PageDirPtrTable + offset, 2548852Sandreas.hansson@arm.com (uint8_t *)(&pdpe), 8); 2555299Sgblack@eecs.umich.edu } 2565299Sgblack@eecs.umich.edu // Point to the PDTs 2575299Sgblack@eecs.umich.edu for (int table = 0; table < NumPDTs; table++) { 2585299Sgblack@eecs.umich.edu pdpe = X86ISA::htog(0x7 | PageDirTable[table]); 2598852Sandreas.hansson@arm.com physProxy.writeBlob(PageDirPtrTable + table * 8, 2608852Sandreas.hansson@arm.com (uint8_t *)(&pdpe), 8); 2615299Sgblack@eecs.umich.edu } 2625299Sgblack@eecs.umich.edu 2635299Sgblack@eecs.umich.edu // Page Directory Tables 2645299Sgblack@eecs.umich.edu 2655299Sgblack@eecs.umich.edu Addr base = 0; 2665299Sgblack@eecs.umich.edu const Addr pageSize = 2 << 20; 2675299Sgblack@eecs.umich.edu for (int table = 0; table < NumPDTs; table++) { 2685299Sgblack@eecs.umich.edu for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) { 2695299Sgblack@eecs.umich.edu // read/write, user, present, 4MB 2705299Sgblack@eecs.umich.edu uint64_t pdte = X86ISA::htog(0x87 | base); 2718852Sandreas.hansson@arm.com physProxy.writeBlob(PageDirTable[table] + offset, 2728852Sandreas.hansson@arm.com (uint8_t *)(&pdte), 8); 2735299Sgblack@eecs.umich.edu base += pageSize; 2745299Sgblack@eecs.umich.edu } 2755299Sgblack@eecs.umich.edu } 2765299Sgblack@eecs.umich.edu 2775299Sgblack@eecs.umich.edu /* 2785299Sgblack@eecs.umich.edu * Transition from real mode all the way up to Long mode 2795299Sgblack@eecs.umich.edu */ 2806220Sgblack@eecs.umich.edu CR0 cr0 = tc->readMiscRegNoEffect(MISCREG_CR0); 2815299Sgblack@eecs.umich.edu //Turn off paging. 2825299Sgblack@eecs.umich.edu cr0.pg = 0; 2836220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 2845299Sgblack@eecs.umich.edu //Turn on protected mode. 2855299Sgblack@eecs.umich.edu cr0.pe = 1; 2866220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 2875299Sgblack@eecs.umich.edu 2886220Sgblack@eecs.umich.edu CR4 cr4 = tc->readMiscRegNoEffect(MISCREG_CR4); 2895299Sgblack@eecs.umich.edu //Turn on pae. 2905299Sgblack@eecs.umich.edu cr4.pae = 1; 2916220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR4, cr4); 2925299Sgblack@eecs.umich.edu 2935299Sgblack@eecs.umich.edu //Point to the page tables. 2946220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR3, PageMapLevel4); 2955299Sgblack@eecs.umich.edu 2966220Sgblack@eecs.umich.edu Efer efer = tc->readMiscRegNoEffect(MISCREG_EFER); 2975299Sgblack@eecs.umich.edu //Enable long mode. 2985299Sgblack@eecs.umich.edu efer.lme = 1; 2996220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_EFER, efer); 3006220Sgblack@eecs.umich.edu 3016220Sgblack@eecs.umich.edu //Start using longmode segments. 3026220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_CS, csDesc, true); 3036220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_DS, dsDesc, true); 3046220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_ES, dsDesc, true); 3056220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_FS, dsDesc, true); 3066220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_GS, dsDesc, true); 3076220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_SS, dsDesc, true); 3085299Sgblack@eecs.umich.edu 3095299Sgblack@eecs.umich.edu //Activate long mode. 3105299Sgblack@eecs.umich.edu cr0.pg = 1; 3116220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 3125299Sgblack@eecs.umich.edu 3137720Sgblack@eecs.umich.edu tc->pcState(tc->getSystemPtr()->kernelEntry); 3145299Sgblack@eecs.umich.edu 3155299Sgblack@eecs.umich.edu // We should now be in long mode. Yay! 3165334Sgblack@eecs.umich.edu 3175615Sgblack@eecs.umich.edu Addr ebdaPos = 0xF0000; 3185625Sgblack@eecs.umich.edu Addr fixed, table; 3195615Sgblack@eecs.umich.edu 3205334Sgblack@eecs.umich.edu //Write out the SMBios/DMI table 3215625Sgblack@eecs.umich.edu writeOutSMBiosTable(ebdaPos, fixed, table); 3225625Sgblack@eecs.umich.edu ebdaPos += (fixed + table); 3235625Sgblack@eecs.umich.edu ebdaPos = roundUp(ebdaPos, 16); 3245625Sgblack@eecs.umich.edu 3255625Sgblack@eecs.umich.edu //Write out the Intel MP Specification configuration table 3265625Sgblack@eecs.umich.edu writeOutMPTable(ebdaPos, fixed, table); 3275625Sgblack@eecs.umich.edu ebdaPos += (fixed + table); 3285299Sgblack@eecs.umich.edu} 3295299Sgblack@eecs.umich.edu 3305334Sgblack@eecs.umich.eduvoid 3315615Sgblack@eecs.umich.eduX86System::writeOutSMBiosTable(Addr header, 3325615Sgblack@eecs.umich.edu Addr &headerSize, Addr &structSize, Addr table) 3335334Sgblack@eecs.umich.edu{ 3345334Sgblack@eecs.umich.edu // If the table location isn't specified, just put it after the header. 3355334Sgblack@eecs.umich.edu // The header size as of the 2.5 SMBios specification is 0x1F bytes 3365615Sgblack@eecs.umich.edu if (!table) 3375615Sgblack@eecs.umich.edu table = header + 0x1F; 3385615Sgblack@eecs.umich.edu smbiosTable->setTableAddr(table); 3395334Sgblack@eecs.umich.edu 3408706Sandreas.hansson@arm.com smbiosTable->writeOut(physProxy, header, headerSize, structSize); 3415615Sgblack@eecs.umich.edu 3425615Sgblack@eecs.umich.edu // Do some bounds checking to make sure we at least didn't step on 3435615Sgblack@eecs.umich.edu // ourselves. 3445615Sgblack@eecs.umich.edu assert(header > table || header + headerSize <= table); 3455615Sgblack@eecs.umich.edu assert(table > header || table + structSize <= header); 3465334Sgblack@eecs.umich.edu} 3475334Sgblack@eecs.umich.edu 3485625Sgblack@eecs.umich.eduvoid 3495625Sgblack@eecs.umich.eduX86System::writeOutMPTable(Addr fp, 3505625Sgblack@eecs.umich.edu Addr &fpSize, Addr &tableSize, Addr table) 3515625Sgblack@eecs.umich.edu{ 3525625Sgblack@eecs.umich.edu // If the table location isn't specified and it exists, just put 3535625Sgblack@eecs.umich.edu // it after the floating pointer. The fp size as of the 1.4 Intel MP 3545625Sgblack@eecs.umich.edu // specification is 0x10 bytes. 3555625Sgblack@eecs.umich.edu if (mpConfigTable) { 3565625Sgblack@eecs.umich.edu if (!table) 3575625Sgblack@eecs.umich.edu table = fp + 0x10; 3585625Sgblack@eecs.umich.edu mpFloatingPointer->setTableAddr(table); 3595625Sgblack@eecs.umich.edu } 3605625Sgblack@eecs.umich.edu 3618706Sandreas.hansson@arm.com fpSize = mpFloatingPointer->writeOut(physProxy, fp); 3625625Sgblack@eecs.umich.edu if (mpConfigTable) 3638706Sandreas.hansson@arm.com tableSize = mpConfigTable->writeOut(physProxy, table); 3645625Sgblack@eecs.umich.edu else 3655625Sgblack@eecs.umich.edu tableSize = 0; 3665625Sgblack@eecs.umich.edu 3675625Sgblack@eecs.umich.edu // Do some bounds checking to make sure we at least didn't step on 3685625Sgblack@eecs.umich.edu // ourselves and the fp structure was the size we thought it was. 3695625Sgblack@eecs.umich.edu assert(fp > table || fp + fpSize <= table); 3705625Sgblack@eecs.umich.edu assert(table > fp || table + tableSize <= fp); 3715625Sgblack@eecs.umich.edu assert(fpSize == 0x10); 3725625Sgblack@eecs.umich.edu} 3735625Sgblack@eecs.umich.edu 3745334Sgblack@eecs.umich.edu 3755132Sgblack@eecs.umich.eduX86System::~X86System() 3765132Sgblack@eecs.umich.edu{ 3775334Sgblack@eecs.umich.edu delete smbiosTable; 3785132Sgblack@eecs.umich.edu} 3795132Sgblack@eecs.umich.edu 3805132Sgblack@eecs.umich.eduX86System * 3815132Sgblack@eecs.umich.eduX86SystemParams::create() 3825132Sgblack@eecs.umich.edu{ 3835132Sgblack@eecs.umich.edu return new X86System(this); 3845132Sgblack@eecs.umich.edu} 385