system.cc revision 8229
17259Sgblack@eecs.umich.edu/* 212669Schuan.zhu@arm.com * Copyright (c) 2007 The Hewlett-Packard Development Company 37259Sgblack@eecs.umich.edu * All rights reserved. 47259Sgblack@eecs.umich.edu * 57259Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 67259Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 77259Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 87259Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 97259Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 107259Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 117259Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 127259Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 137259Sgblack@eecs.umich.edu * 147259Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 157259Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 167259Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 177259Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 187259Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 197259Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 207259Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 217259Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 227259Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 237259Sgblack@eecs.umich.edu * this software without specific prior written permission. 247259Sgblack@eecs.umich.edu * 257259Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 267259Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 277259Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 287259Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 297259Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 307259Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 317259Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 327259Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 337259Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 347259Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 357259Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 367259Sgblack@eecs.umich.edu * 377259Sgblack@eecs.umich.edu * Authors: Gabe Black 387405SAli.Saidi@ARM.com */ 3910037SARM gem5 Developers 407259Sgblack@eecs.umich.edu#include "arch/x86/bios/intelmp.hh" 417259Sgblack@eecs.umich.edu#include "arch/x86/bios/smbios.hh" 4211793Sbrandon.potter@amd.com#include "arch/x86/regs/misc.hh" 4311793Sbrandon.potter@amd.com#include "arch/x86/isa_traits.hh" 4411939Snikos.nikoleris@arm.com#include "arch/x86/system.hh" 4511939Snikos.nikoleris@arm.com#include "arch/vtophys.hh" 467405SAli.Saidi@ARM.com#include "base/loader/object_file.hh" 4712334Sgabeblack@google.com#include "base/loader/symtab.hh" 4810037SARM gem5 Developers#include "base/intmath.hh" 4910828SGiacomo.Gabrielli@arm.com#include "base/trace.hh" 507259Sgblack@eecs.umich.edu#include "cpu/thread_context.hh" 517259Sgblack@eecs.umich.edu#include "mem/physical.hh" 527259Sgblack@eecs.umich.edu#include "params/X86System.hh" 537259Sgblack@eecs.umich.edu#include "sim/byteswap.hh" 547259Sgblack@eecs.umich.edu 558868SMatt.Horsnell@arm.comusing namespace LittleEndianGuest; 568868SMatt.Horsnell@arm.comusing namespace X86ISA; 578868SMatt.Horsnell@arm.com 588868SMatt.Horsnell@arm.comX86System::X86System(Params *p) : 5910037SARM gem5 Developers System(p), smbiosTable(p->smbios_table), 608868SMatt.Horsnell@arm.com mpFloatingPointer(p->intel_mp_pointer), 6110037SARM gem5 Developers mpConfigTable(p->intel_mp_table), 628868SMatt.Horsnell@arm.com rsdp(p->acpi_description_table_pointer) 6310037SARM gem5 Developers{ 6410037SARM gem5 Developers if (kernel->getArch() == ObjectFile::I386) 6510037SARM gem5 Developers fatal("Loading a 32 bit x86 kernel is not supported.\n"); 6610037SARM gem5 Developers} 6710037SARM gem5 Developers 6810037SARM gem5 Developersstatic void 6910037SARM gem5 DevelopersinstallSegDesc(ThreadContext *tc, SegmentRegIndex seg, 708868SMatt.Horsnell@arm.com SegDescriptor desc, bool longmode) 7110037SARM gem5 Developers{ 7210037SARM gem5 Developers uint64_t base = desc.baseLow + (desc.baseHigh << 24); 7310037SARM gem5 Developers bool honorBase = !longmode || seg == SEGMENT_REG_FS || 7410037SARM gem5 Developers seg == SEGMENT_REG_GS || 7510037SARM gem5 Developers seg == SEGMENT_REG_TSL || 7610037SARM gem5 Developers seg == SYS_SEGMENT_REG_TR; 7710037SARM gem5 Developers uint64_t limit = desc.limitLow | (desc.limitHigh << 16); 7810037SARM gem5 Developers 7910037SARM gem5 Developers SegAttr attr = 0; 8010037SARM gem5 Developers 8110037SARM gem5 Developers attr.dpl = desc.dpl; 829959Schander.sudanthi@arm.com attr.unusable = 0; 8310037SARM gem5 Developers attr.defaultSize = desc.d; 849959Schander.sudanthi@arm.com attr.longMode = desc.l; 859959Schander.sudanthi@arm.com attr.avl = desc.avl; 869959Schander.sudanthi@arm.com attr.granularity = desc.g; 879959Schander.sudanthi@arm.com attr.present = desc.p; 889959Schander.sudanthi@arm.com attr.system = desc.s; 899959Schander.sudanthi@arm.com attr.type = desc.type; 909959Schander.sudanthi@arm.com if (desc.s) { 919959Schander.sudanthi@arm.com if (desc.type.codeOrData) { 929959Schander.sudanthi@arm.com // Code segment 9310037SARM gem5 Developers attr.expandDown = 0; 949959Schander.sudanthi@arm.com attr.readable = desc.type.r; 9510037SARM gem5 Developers attr.writable = 0; 9610037SARM gem5 Developers } else { 9710037SARM gem5 Developers // Data segment 9810037SARM gem5 Developers attr.expandDown = desc.type.e; 9910037SARM gem5 Developers attr.readable = 1; 10010037SARM gem5 Developers attr.writable = desc.type.w; 10110037SARM gem5 Developers } 10210037SARM gem5 Developers } else { 10310037SARM gem5 Developers attr.readable = 1; 10410037SARM gem5 Developers attr.writable = 1; 10510037SARM gem5 Developers attr.expandDown = 0; 1068868SMatt.Horsnell@arm.com } 10710037SARM gem5 Developers 10810037SARM gem5 Developers tc->setMiscReg(MISCREG_SEG_BASE(seg), base); 10910037SARM gem5 Developers tc->setMiscReg(MISCREG_SEG_EFF_BASE(seg), honorBase ? base : 0); 11010037SARM gem5 Developers tc->setMiscReg(MISCREG_SEG_LIMIT(seg), limit); 11110037SARM gem5 Developers tc->setMiscReg(MISCREG_SEG_ATTR(seg), (MiscReg)attr); 11210037SARM gem5 Developers} 11310037SARM gem5 Developers 11410037SARM gem5 Developersvoid 11510037SARM gem5 DevelopersX86System::initState() 11610037SARM gem5 Developers{ 11710037SARM gem5 Developers System::initState(); 11810037SARM gem5 Developers 11910037SARM gem5 Developers ThreadContext *tc = threadContexts[0]; 12010037SARM gem5 Developers // This is the boot strap processor (BSP). Initialize it to look like 12110037SARM gem5 Developers // the boot loader has just turned control over to the 64 bit OS. We 1228868SMatt.Horsnell@arm.com // won't actually set up real mode or legacy protected mode descriptor 12310037SARM gem5 Developers // tables because we aren't executing any code that would require 12410037SARM gem5 Developers // them. We do, however toggle the control bits in the correct order 12510037SARM gem5 Developers // while allowing consistency checks and the underlying mechansims 12610037SARM gem5 Developers // just to be safe. 12710037SARM gem5 Developers 1288868SMatt.Horsnell@arm.com const int NumPDTs = 4; 12910037SARM gem5 Developers 13010037SARM gem5 Developers const Addr PageMapLevel4 = 0x70000; 1318868SMatt.Horsnell@arm.com const Addr PageDirPtrTable = 0x71000; 1327259Sgblack@eecs.umich.edu const Addr PageDirTable[NumPDTs] = 1337259Sgblack@eecs.umich.edu {0x72000, 0x73000, 0x74000, 0x75000}; 1347259Sgblack@eecs.umich.edu const Addr GDTBase = 0x76000; 1357259Sgblack@eecs.umich.edu 1367259Sgblack@eecs.umich.edu const int PML4Bits = 9; 1377259Sgblack@eecs.umich.edu const int PDPTBits = 9; 1387259Sgblack@eecs.umich.edu const int PDTBits = 9; 1397259Sgblack@eecs.umich.edu 1407259Sgblack@eecs.umich.edu // Get a port to write the page tables and descriptor tables. 1417259Sgblack@eecs.umich.edu FunctionalPort * physPort = tc->getPhysPort(); 1427259Sgblack@eecs.umich.edu 1437259Sgblack@eecs.umich.edu /* 1447259Sgblack@eecs.umich.edu * Set up the gdt. 1457351Sgblack@eecs.umich.edu */ 1467351Sgblack@eecs.umich.edu uint8_t numGDTEntries = 0; 1477259Sgblack@eecs.umich.edu // Place holder at selector 0 1487259Sgblack@eecs.umich.edu uint64_t nullDescriptor = 0; 14910037SARM gem5 Developers physPort->writeBlob(GDTBase + numGDTEntries * 8, 15010037SARM gem5 Developers (uint8_t *)(&nullDescriptor), 8); 1517259Sgblack@eecs.umich.edu numGDTEntries++; 1527259Sgblack@eecs.umich.edu 1537259Sgblack@eecs.umich.edu //64 bit code segment 1547259Sgblack@eecs.umich.edu SegDescriptor csDesc = 0; 1557259Sgblack@eecs.umich.edu csDesc.type.codeOrData = 1; 1567259Sgblack@eecs.umich.edu csDesc.type.c = 0; // Not conforming 1577259Sgblack@eecs.umich.edu csDesc.type.r = 1; // Readable 1587259Sgblack@eecs.umich.edu csDesc.dpl = 0; // Privelege level 0 1597259Sgblack@eecs.umich.edu csDesc.p = 1; // Present 1607259Sgblack@eecs.umich.edu csDesc.l = 1; // 64 bit 1617259Sgblack@eecs.umich.edu csDesc.d = 0; // default operand size 1627259Sgblack@eecs.umich.edu csDesc.g = 1; // Page granularity 1637259Sgblack@eecs.umich.edu csDesc.s = 1; // Not a system segment 1647259Sgblack@eecs.umich.edu csDesc.limitHigh = 0xF; 1657259Sgblack@eecs.umich.edu csDesc.limitLow = 0xFF; 1667259Sgblack@eecs.umich.edu //Because we're dealing with a pointer and I don't think it's 1677259Sgblack@eecs.umich.edu //guaranteed that there isn't anything in a nonvirtual class between 1687259Sgblack@eecs.umich.edu //it's beginning in memory and it's actual data, we'll use an 1697259Sgblack@eecs.umich.edu //intermediary. 1707259Sgblack@eecs.umich.edu uint64_t csDescVal = csDesc; 1717259Sgblack@eecs.umich.edu physPort->writeBlob(GDTBase + numGDTEntries * 8, 1727259Sgblack@eecs.umich.edu (uint8_t *)(&csDescVal), 8); 1737259Sgblack@eecs.umich.edu 1747259Sgblack@eecs.umich.edu numGDTEntries++; 1757259Sgblack@eecs.umich.edu 1767259Sgblack@eecs.umich.edu SegSelector cs = 0; 1777259Sgblack@eecs.umich.edu cs.si = numGDTEntries - 1; 1787259Sgblack@eecs.umich.edu 1797259Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CS, (MiscReg)cs); 1807259Sgblack@eecs.umich.edu 1817259Sgblack@eecs.umich.edu //32 bit data segment 1827259Sgblack@eecs.umich.edu SegDescriptor dsDesc = 0; 1837259Sgblack@eecs.umich.edu dsDesc.type.codeOrData = 0; 1847259Sgblack@eecs.umich.edu dsDesc.type.e = 0; // Not expand down 1857259Sgblack@eecs.umich.edu dsDesc.type.w = 1; // Writable 1867259Sgblack@eecs.umich.edu dsDesc.dpl = 0; // Privelege level 0 1877259Sgblack@eecs.umich.edu dsDesc.p = 1; // Present 1887259Sgblack@eecs.umich.edu dsDesc.d = 1; // default operand size 1897259Sgblack@eecs.umich.edu dsDesc.g = 1; // Page granularity 1907259Sgblack@eecs.umich.edu dsDesc.s = 1; // Not a system segment 1917259Sgblack@eecs.umich.edu dsDesc.limitHigh = 0xF; 1927259Sgblack@eecs.umich.edu dsDesc.limitLow = 0xFF; 1937259Sgblack@eecs.umich.edu uint64_t dsDescVal = dsDesc; 1947259Sgblack@eecs.umich.edu physPort->writeBlob(GDTBase + numGDTEntries * 8, 1957259Sgblack@eecs.umich.edu (uint8_t *)(&dsDescVal), 8); 1967259Sgblack@eecs.umich.edu 1977259Sgblack@eecs.umich.edu numGDTEntries++; 1987259Sgblack@eecs.umich.edu 1997259Sgblack@eecs.umich.edu SegSelector ds = 0; 2007259Sgblack@eecs.umich.edu ds.si = numGDTEntries - 1; 2017259Sgblack@eecs.umich.edu 2027259Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_DS, (MiscReg)ds); 2037259Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_ES, (MiscReg)ds); 2047259Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_FS, (MiscReg)ds); 2057259Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_GS, (MiscReg)ds); 2067259Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SS, (MiscReg)ds); 2077259Sgblack@eecs.umich.edu 2087259Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TSL, 0); 2097259Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TSG_BASE, GDTBase); 2107259Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TSG_LIMIT, 8 * numGDTEntries - 1); 2117259Sgblack@eecs.umich.edu 2127259Sgblack@eecs.umich.edu SegDescriptor tssDesc = 0; 2137259Sgblack@eecs.umich.edu tssDesc.type = 0xB; 2147259Sgblack@eecs.umich.edu tssDesc.dpl = 0; // Privelege level 0 21510037SARM gem5 Developers tssDesc.p = 1; // Present 21610037SARM gem5 Developers tssDesc.d = 1; // default operand size 21710037SARM gem5 Developers tssDesc.g = 1; // Page granularity 21810037SARM gem5 Developers tssDesc.s = 1; // Not a system segment 21910037SARM gem5 Developers tssDesc.limitHigh = 0xF; 22010037SARM gem5 Developers tssDesc.limitLow = 0xFF; 22110037SARM gem5 Developers uint64_t tssDescVal = tssDesc; 22210037SARM gem5 Developers physPort->writeBlob(GDTBase + numGDTEntries * 8, 2237259Sgblack@eecs.umich.edu (uint8_t *)(&tssDescVal), 8); 2247259Sgblack@eecs.umich.edu 2257259Sgblack@eecs.umich.edu numGDTEntries++; 2267351Sgblack@eecs.umich.edu 2277351Sgblack@eecs.umich.edu SegSelector tss = 0; 2287351Sgblack@eecs.umich.edu tss.si = numGDTEntries - 1; 2297351Sgblack@eecs.umich.edu 2307351Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TR, (MiscReg)tss); 2317351Sgblack@eecs.umich.edu installSegDesc(tc, SYS_SEGMENT_REG_TR, tssDesc, true); 2327351Sgblack@eecs.umich.edu 2337351Sgblack@eecs.umich.edu /* 2347351Sgblack@eecs.umich.edu * Identity map the first 4GB of memory. In order to map this region 2357351Sgblack@eecs.umich.edu * of memory in long mode, there needs to be one actual page map level 2367351Sgblack@eecs.umich.edu * 4 entry which points to one page directory pointer table which 2377351Sgblack@eecs.umich.edu * points to 4 different page directory tables which are full of two 2387351Sgblack@eecs.umich.edu * megabyte pages. All of the other entries in valid tables are set 2397351Sgblack@eecs.umich.edu * to indicate that they don't pertain to anything valid and will 2407351Sgblack@eecs.umich.edu * cause a fault if used. 2417351Sgblack@eecs.umich.edu */ 2427351Sgblack@eecs.umich.edu 2437351Sgblack@eecs.umich.edu // Put valid values in all of the various table entries which indicate 2447351Sgblack@eecs.umich.edu // that those entries don't point to further tables or pages. Then 2457351Sgblack@eecs.umich.edu // set the values of those entries which are needed. 24610037SARM gem5 Developers 24710037SARM gem5 Developers // Page Map Level 4 24810037SARM gem5 Developers 24910037SARM gem5 Developers // read/write, user, not present 25010037SARM gem5 Developers uint64_t pml4e = X86ISA::htog(0x6); 25110037SARM gem5 Developers for (int offset = 0; offset < (1 << PML4Bits) * 8; offset += 8) { 25210037SARM gem5 Developers physPort->writeBlob(PageMapLevel4 + offset, (uint8_t *)(&pml4e), 8); 25310037SARM gem5 Developers } 25410037SARM gem5 Developers // Point to the only PDPT 25510037SARM gem5 Developers pml4e = X86ISA::htog(0x7 | PageDirPtrTable); 25610037SARM gem5 Developers physPort->writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8); 25710037SARM gem5 Developers 25810037SARM gem5 Developers // Page Directory Pointer Table 25910037SARM gem5 Developers 26010037SARM gem5 Developers // read/write, user, not present 26110037SARM gem5 Developers uint64_t pdpe = X86ISA::htog(0x6); 26210037SARM gem5 Developers for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) { 26310037SARM gem5 Developers physPort->writeBlob(PageDirPtrTable + offset, 26410037SARM gem5 Developers (uint8_t *)(&pdpe), 8); 26510037SARM gem5 Developers } 2667351Sgblack@eecs.umich.edu // Point to the PDTs 2677351Sgblack@eecs.umich.edu for (int table = 0; table < NumPDTs; table++) { 2687351Sgblack@eecs.umich.edu pdpe = X86ISA::htog(0x7 | PageDirTable[table]); 2697406SAli.Saidi@ARM.com physPort->writeBlob(PageDirPtrTable + table * 8, 2707259Sgblack@eecs.umich.edu (uint8_t *)(&pdpe), 8); 2717259Sgblack@eecs.umich.edu } 2727351Sgblack@eecs.umich.edu 2737259Sgblack@eecs.umich.edu // Page Directory Tables 2747351Sgblack@eecs.umich.edu 2757351Sgblack@eecs.umich.edu Addr base = 0; 2767351Sgblack@eecs.umich.edu const Addr pageSize = 2 << 20; 2777259Sgblack@eecs.umich.edu for (int table = 0; table < NumPDTs; table++) { 27810037SARM gem5 Developers for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) { 27910037SARM gem5 Developers // read/write, user, present, 4MB 28010037SARM gem5 Developers uint64_t pdte = X86ISA::htog(0x87 | base); 28110037SARM gem5 Developers physPort->writeBlob(PageDirTable[table] + offset, 28210037SARM gem5 Developers (uint8_t *)(&pdte), 8); 2837259Sgblack@eecs.umich.edu base += pageSize; 2847259Sgblack@eecs.umich.edu } 2857351Sgblack@eecs.umich.edu } 2867351Sgblack@eecs.umich.edu 2877351Sgblack@eecs.umich.edu /* 2887351Sgblack@eecs.umich.edu * Transition from real mode all the way up to Long mode 2897351Sgblack@eecs.umich.edu */ 2907259Sgblack@eecs.umich.edu CR0 cr0 = tc->readMiscRegNoEffect(MISCREG_CR0); 2917259Sgblack@eecs.umich.edu //Turn off paging. 2927259Sgblack@eecs.umich.edu cr0.pg = 0; 2937259Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 2947259Sgblack@eecs.umich.edu //Turn on protected mode. 2957259Sgblack@eecs.umich.edu cr0.pe = 1; 2967259Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 2977259Sgblack@eecs.umich.edu 2987259Sgblack@eecs.umich.edu CR4 cr4 = tc->readMiscRegNoEffect(MISCREG_CR4); 2997259Sgblack@eecs.umich.edu //Turn on pae. 3007259Sgblack@eecs.umich.edu cr4.pae = 1; 3017259Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR4, cr4); 3027259Sgblack@eecs.umich.edu 3037259Sgblack@eecs.umich.edu //Point to the page tables. 3047259Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR3, PageMapLevel4); 30510037SARM gem5 Developers 30610037SARM gem5 Developers Efer efer = tc->readMiscRegNoEffect(MISCREG_EFER); 30710037SARM gem5 Developers //Enable long mode. 30810037SARM gem5 Developers efer.lme = 1; 30910037SARM gem5 Developers tc->setMiscReg(MISCREG_EFER, efer); 31010037SARM gem5 Developers 31110037SARM gem5 Developers //Start using longmode segments. 31210037SARM gem5 Developers installSegDesc(tc, SEGMENT_REG_CS, csDesc, true); 31310037SARM gem5 Developers installSegDesc(tc, SEGMENT_REG_DS, dsDesc, true); 3147259Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_ES, dsDesc, true); 3157259Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_FS, dsDesc, true); 3167259Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_GS, dsDesc, true); 3177351Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_SS, dsDesc, true); 3187351Sgblack@eecs.umich.edu 3197259Sgblack@eecs.umich.edu //Activate long mode. 3207351Sgblack@eecs.umich.edu cr0.pg = 1; 3217259Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 3227351Sgblack@eecs.umich.edu 3237259Sgblack@eecs.umich.edu tc->pcState(tc->getSystemPtr()->kernelEntry); 32410037SARM gem5 Developers 32510037SARM gem5 Developers // We should now be in long mode. Yay! 32610037SARM gem5 Developers 32710037SARM gem5 Developers Addr ebdaPos = 0xF0000; 32810037SARM gem5 Developers Addr fixed, table; 32910037SARM gem5 Developers 33010037SARM gem5 Developers //Write out the SMBios/DMI table 33110037SARM gem5 Developers writeOutSMBiosTable(ebdaPos, fixed, table); 33210037SARM gem5 Developers ebdaPos += (fixed + table); 3337259Sgblack@eecs.umich.edu ebdaPos = roundUp(ebdaPos, 16); 3347259Sgblack@eecs.umich.edu 3357259Sgblack@eecs.umich.edu //Write out the Intel MP Specification configuration table 3367259Sgblack@eecs.umich.edu writeOutMPTable(ebdaPos, fixed, table); 3377259Sgblack@eecs.umich.edu ebdaPos += (fixed + table); 3387259Sgblack@eecs.umich.edu} 3397259Sgblack@eecs.umich.edu 3407259Sgblack@eecs.umich.eduvoid 3417259Sgblack@eecs.umich.eduX86System::writeOutSMBiosTable(Addr header, 3427259Sgblack@eecs.umich.edu Addr &headerSize, Addr &structSize, Addr table) 3437259Sgblack@eecs.umich.edu{ 3447259Sgblack@eecs.umich.edu // Get a port to write the table and header to memory. 3457259Sgblack@eecs.umich.edu FunctionalPort * physPort = threadContexts[0]->getPhysPort(); 3467259Sgblack@eecs.umich.edu 3477259Sgblack@eecs.umich.edu // If the table location isn't specified, just put it after the header. 3487259Sgblack@eecs.umich.edu // The header size as of the 2.5 SMBios specification is 0x1F bytes 3497259Sgblack@eecs.umich.edu if (!table) 3507259Sgblack@eecs.umich.edu table = header + 0x1F; 3517351Sgblack@eecs.umich.edu smbiosTable->setTableAddr(table); 3527351Sgblack@eecs.umich.edu 3537351Sgblack@eecs.umich.edu smbiosTable->writeOut(physPort, header, headerSize, structSize); 3547351Sgblack@eecs.umich.edu 3557351Sgblack@eecs.umich.edu // Do some bounds checking to make sure we at least didn't step on 3567259Sgblack@eecs.umich.edu // ourselves. 3577259Sgblack@eecs.umich.edu assert(header > table || header + headerSize <= table); 3587259Sgblack@eecs.umich.edu assert(table > header || table + structSize <= header); 3597259Sgblack@eecs.umich.edu} 3607259Sgblack@eecs.umich.edu 3617259Sgblack@eecs.umich.eduvoid 3627259Sgblack@eecs.umich.eduX86System::writeOutMPTable(Addr fp, 3637259Sgblack@eecs.umich.edu Addr &fpSize, Addr &tableSize, Addr table) 3647259Sgblack@eecs.umich.edu{ 3657259Sgblack@eecs.umich.edu // Get a port to write the table and header to memory. 3667259Sgblack@eecs.umich.edu FunctionalPort * physPort = threadContexts[0]->getPhysPort(); 3677259Sgblack@eecs.umich.edu 3687259Sgblack@eecs.umich.edu // If the table location isn't specified and it exists, just put 3697259Sgblack@eecs.umich.edu // it after the floating pointer. The fp size as of the 1.4 Intel MP 3707259Sgblack@eecs.umich.edu // specification is 0x10 bytes. 3717259Sgblack@eecs.umich.edu if (mpConfigTable) { 3727259Sgblack@eecs.umich.edu if (!table) 3737259Sgblack@eecs.umich.edu table = fp + 0x10; 3747259Sgblack@eecs.umich.edu mpFloatingPointer->setTableAddr(table); 3757259Sgblack@eecs.umich.edu } 3767259Sgblack@eecs.umich.edu 3777351Sgblack@eecs.umich.edu fpSize = mpFloatingPointer->writeOut(physPort, fp); 3787351Sgblack@eecs.umich.edu if (mpConfigTable) 3797351Sgblack@eecs.umich.edu tableSize = mpConfigTable->writeOut(physPort, table); 38010037SARM gem5 Developers else 3817351Sgblack@eecs.umich.edu tableSize = 0; 38210037SARM gem5 Developers 3837351Sgblack@eecs.umich.edu // Do some bounds checking to make sure we at least didn't step on 38410037SARM gem5 Developers // ourselves and the fp structure was the size we thought it was. 3857351Sgblack@eecs.umich.edu assert(fp > table || fp + fpSize <= table); 38610037SARM gem5 Developers assert(table > fp || table + tableSize <= fp); 3877351Sgblack@eecs.umich.edu assert(fpSize == 0x10); 38810037SARM gem5 Developers} 3897351Sgblack@eecs.umich.edu 39010037SARM gem5 Developers 3917351Sgblack@eecs.umich.eduX86System::~X86System() 39210037SARM gem5 Developers{ 3937351Sgblack@eecs.umich.edu delete smbiosTable; 39410037SARM gem5 Developers} 3957351Sgblack@eecs.umich.edu 3967351Sgblack@eecs.umich.eduvoid 3977259Sgblack@eecs.umich.eduX86System::serialize(std::ostream &os) 3987259Sgblack@eecs.umich.edu{ 3997259Sgblack@eecs.umich.edu System::serialize(os); 4007259Sgblack@eecs.umich.edu} 4017259Sgblack@eecs.umich.edu 40210037SARM gem5 Developers 4037259Sgblack@eecs.umich.eduvoid 4047259Sgblack@eecs.umich.eduX86System::unserialize(Checkpoint *cp, const std::string §ion) 4057259Sgblack@eecs.umich.edu{ 4067259Sgblack@eecs.umich.edu System::unserialize(cp,section); 4077259Sgblack@eecs.umich.edu} 4087259Sgblack@eecs.umich.edu 4097259Sgblack@eecs.umich.eduX86System * 4107259Sgblack@eecs.umich.eduX86SystemParams::create() 4117259Sgblack@eecs.umich.edu{ 4127259Sgblack@eecs.umich.edu return new X86System(this); 4137259Sgblack@eecs.umich.edu} 4147259Sgblack@eecs.umich.edu