system.cc revision 7901
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 405612Sgblack@eecs.umich.edu#include "arch/x86/bios/smbios.hh" 415625Sgblack@eecs.umich.edu#include "arch/x86/bios/intelmp.hh" 427901Shestness@cs.utexas.edu#include "arch/x86/isa_traits.hh" 437629Sgblack@eecs.umich.edu#include "arch/x86/regs/misc.hh" 445132Sgblack@eecs.umich.edu#include "arch/x86/system.hh" 455132Sgblack@eecs.umich.edu#include "arch/vtophys.hh" 465625Sgblack@eecs.umich.edu#include "base/intmath.hh" 475132Sgblack@eecs.umich.edu#include "base/loader/object_file.hh" 485132Sgblack@eecs.umich.edu#include "base/loader/symtab.hh" 495132Sgblack@eecs.umich.edu#include "base/trace.hh" 505299Sgblack@eecs.umich.edu#include "cpu/thread_context.hh" 515132Sgblack@eecs.umich.edu#include "mem/physical.hh" 525132Sgblack@eecs.umich.edu#include "params/X86System.hh" 535132Sgblack@eecs.umich.edu#include "sim/byteswap.hh" 545132Sgblack@eecs.umich.edu 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 if (kernel->getArch() == ObjectFile::I386) 667704Sgblack@eecs.umich.edu fatal("Loading a 32 bit x86 kernel is not supported.\n"); 677704Sgblack@eecs.umich.edu} 685132Sgblack@eecs.umich.edu 696220Sgblack@eecs.umich.edustatic void 706220Sgblack@eecs.umich.eduinstallSegDesc(ThreadContext *tc, SegmentRegIndex seg, 716220Sgblack@eecs.umich.edu SegDescriptor desc, bool longmode) 726220Sgblack@eecs.umich.edu{ 736220Sgblack@eecs.umich.edu uint64_t base = desc.baseLow + (desc.baseHigh << 24); 746220Sgblack@eecs.umich.edu bool honorBase = !longmode || seg == SEGMENT_REG_FS || 756220Sgblack@eecs.umich.edu seg == SEGMENT_REG_GS || 766220Sgblack@eecs.umich.edu seg == SEGMENT_REG_TSL || 776220Sgblack@eecs.umich.edu seg == SYS_SEGMENT_REG_TR; 786220Sgblack@eecs.umich.edu uint64_t limit = desc.limitLow | (desc.limitHigh << 16); 796220Sgblack@eecs.umich.edu 806220Sgblack@eecs.umich.edu SegAttr attr = 0; 816222Sgblack@eecs.umich.edu 826222Sgblack@eecs.umich.edu attr.dpl = desc.dpl; 836222Sgblack@eecs.umich.edu attr.unusable = 0; 846222Sgblack@eecs.umich.edu attr.defaultSize = desc.d; 856222Sgblack@eecs.umich.edu attr.longMode = desc.l; 866222Sgblack@eecs.umich.edu attr.avl = desc.avl; 876222Sgblack@eecs.umich.edu attr.granularity = desc.g; 886222Sgblack@eecs.umich.edu attr.present = desc.p; 896222Sgblack@eecs.umich.edu attr.system = desc.s; 906222Sgblack@eecs.umich.edu attr.type = desc.type; 916220Sgblack@eecs.umich.edu if (desc.s) { 926220Sgblack@eecs.umich.edu if (desc.type.codeOrData) { 936220Sgblack@eecs.umich.edu // Code segment 946222Sgblack@eecs.umich.edu attr.expandDown = 0; 956220Sgblack@eecs.umich.edu attr.readable = desc.type.r; 966222Sgblack@eecs.umich.edu attr.writable = 0; 976220Sgblack@eecs.umich.edu } else { 986220Sgblack@eecs.umich.edu // Data segment 996222Sgblack@eecs.umich.edu attr.expandDown = desc.type.e; 1006220Sgblack@eecs.umich.edu attr.readable = 1; 1016220Sgblack@eecs.umich.edu attr.writable = desc.type.w; 1026220Sgblack@eecs.umich.edu } 1036220Sgblack@eecs.umich.edu } else { 1046222Sgblack@eecs.umich.edu attr.readable = 1; 1056220Sgblack@eecs.umich.edu attr.writable = 1; 1066220Sgblack@eecs.umich.edu attr.expandDown = 0; 1076220Sgblack@eecs.umich.edu } 1086220Sgblack@eecs.umich.edu 1096220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_BASE(seg), base); 1106220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_EFF_BASE(seg), honorBase ? base : 0); 1116220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_LIMIT(seg), limit); 1126220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_ATTR(seg), (MiscReg)attr); 1136220Sgblack@eecs.umich.edu} 1146220Sgblack@eecs.umich.edu 1155299Sgblack@eecs.umich.eduvoid 1167532Ssteve.reinhardt@amd.comX86System::initState() 1175299Sgblack@eecs.umich.edu{ 1187532Ssteve.reinhardt@amd.com System::initState(); 1197532Ssteve.reinhardt@amd.com 1206220Sgblack@eecs.umich.edu ThreadContext *tc = threadContexts[0]; 1215299Sgblack@eecs.umich.edu // This is the boot strap processor (BSP). Initialize it to look like 1225299Sgblack@eecs.umich.edu // the boot loader has just turned control over to the 64 bit OS. We 1235299Sgblack@eecs.umich.edu // won't actually set up real mode or legacy protected mode descriptor 1245299Sgblack@eecs.umich.edu // tables because we aren't executing any code that would require 1255299Sgblack@eecs.umich.edu // them. We do, however toggle the control bits in the correct order 1265299Sgblack@eecs.umich.edu // while allowing consistency checks and the underlying mechansims 1275299Sgblack@eecs.umich.edu // just to be safe. 1285299Sgblack@eecs.umich.edu 1295299Sgblack@eecs.umich.edu const int NumPDTs = 4; 1305299Sgblack@eecs.umich.edu 1315299Sgblack@eecs.umich.edu const Addr PageMapLevel4 = 0x70000; 1325299Sgblack@eecs.umich.edu const Addr PageDirPtrTable = 0x71000; 1335299Sgblack@eecs.umich.edu const Addr PageDirTable[NumPDTs] = 1345299Sgblack@eecs.umich.edu {0x72000, 0x73000, 0x74000, 0x75000}; 1355299Sgblack@eecs.umich.edu const Addr GDTBase = 0x76000; 1365299Sgblack@eecs.umich.edu 1375299Sgblack@eecs.umich.edu const int PML4Bits = 9; 1385299Sgblack@eecs.umich.edu const int PDPTBits = 9; 1395299Sgblack@eecs.umich.edu const int PDTBits = 9; 1405299Sgblack@eecs.umich.edu 1415299Sgblack@eecs.umich.edu // Get a port to write the page tables and descriptor tables. 1426220Sgblack@eecs.umich.edu FunctionalPort * physPort = tc->getPhysPort(); 1435299Sgblack@eecs.umich.edu 1445299Sgblack@eecs.umich.edu /* 1455299Sgblack@eecs.umich.edu * Set up the gdt. 1465299Sgblack@eecs.umich.edu */ 1476220Sgblack@eecs.umich.edu uint8_t numGDTEntries = 0; 1485299Sgblack@eecs.umich.edu // Place holder at selector 0 1495299Sgblack@eecs.umich.edu uint64_t nullDescriptor = 0; 1506220Sgblack@eecs.umich.edu physPort->writeBlob(GDTBase + numGDTEntries * 8, 1516220Sgblack@eecs.umich.edu (uint8_t *)(&nullDescriptor), 8); 1526220Sgblack@eecs.umich.edu numGDTEntries++; 1535299Sgblack@eecs.umich.edu 1545299Sgblack@eecs.umich.edu //64 bit code segment 1555299Sgblack@eecs.umich.edu SegDescriptor csDesc = 0; 1566220Sgblack@eecs.umich.edu csDesc.type.codeOrData = 1; 1575299Sgblack@eecs.umich.edu csDesc.type.c = 0; // Not conforming 1586220Sgblack@eecs.umich.edu csDesc.type.r = 1; // Readable 1595299Sgblack@eecs.umich.edu csDesc.dpl = 0; // Privelege level 0 1605299Sgblack@eecs.umich.edu csDesc.p = 1; // Present 1615299Sgblack@eecs.umich.edu csDesc.l = 1; // 64 bit 1625299Sgblack@eecs.umich.edu csDesc.d = 0; // default operand size 1636220Sgblack@eecs.umich.edu csDesc.g = 1; // Page granularity 1646220Sgblack@eecs.umich.edu csDesc.s = 1; // Not a system segment 1656220Sgblack@eecs.umich.edu csDesc.limitHigh = 0xF; 1666220Sgblack@eecs.umich.edu csDesc.limitLow = 0xFF; 1675299Sgblack@eecs.umich.edu //Because we're dealing with a pointer and I don't think it's 1685299Sgblack@eecs.umich.edu //guaranteed that there isn't anything in a nonvirtual class between 1695299Sgblack@eecs.umich.edu //it's beginning in memory and it's actual data, we'll use an 1705299Sgblack@eecs.umich.edu //intermediary. 1715299Sgblack@eecs.umich.edu uint64_t csDescVal = csDesc; 1726220Sgblack@eecs.umich.edu physPort->writeBlob(GDTBase + numGDTEntries * 8, 1736220Sgblack@eecs.umich.edu (uint8_t *)(&csDescVal), 8); 1745299Sgblack@eecs.umich.edu 1756220Sgblack@eecs.umich.edu numGDTEntries++; 1766220Sgblack@eecs.umich.edu 1776220Sgblack@eecs.umich.edu SegSelector cs = 0; 1786220Sgblack@eecs.umich.edu cs.si = numGDTEntries - 1; 1796220Sgblack@eecs.umich.edu 1806220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CS, (MiscReg)cs); 1816220Sgblack@eecs.umich.edu 1826220Sgblack@eecs.umich.edu //32 bit data segment 1836220Sgblack@eecs.umich.edu SegDescriptor dsDesc = 0; 1846220Sgblack@eecs.umich.edu dsDesc.type.codeOrData = 0; 1856220Sgblack@eecs.umich.edu dsDesc.type.e = 0; // Not expand down 1866220Sgblack@eecs.umich.edu dsDesc.type.w = 1; // Writable 1876220Sgblack@eecs.umich.edu dsDesc.dpl = 0; // Privelege level 0 1886220Sgblack@eecs.umich.edu dsDesc.p = 1; // Present 1896220Sgblack@eecs.umich.edu dsDesc.d = 1; // default operand size 1906220Sgblack@eecs.umich.edu dsDesc.g = 1; // Page granularity 1916220Sgblack@eecs.umich.edu dsDesc.s = 1; // Not a system segment 1926220Sgblack@eecs.umich.edu dsDesc.limitHigh = 0xF; 1936220Sgblack@eecs.umich.edu dsDesc.limitLow = 0xFF; 1946220Sgblack@eecs.umich.edu uint64_t dsDescVal = dsDesc; 1956220Sgblack@eecs.umich.edu physPort->writeBlob(GDTBase + numGDTEntries * 8, 1966220Sgblack@eecs.umich.edu (uint8_t *)(&dsDescVal), 8); 1976220Sgblack@eecs.umich.edu 1986220Sgblack@eecs.umich.edu numGDTEntries++; 1996220Sgblack@eecs.umich.edu 2006712Snate@binkert.org SegSelector ds = 0; 2016220Sgblack@eecs.umich.edu ds.si = numGDTEntries - 1; 2026220Sgblack@eecs.umich.edu 2036220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_DS, (MiscReg)ds); 2046220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_ES, (MiscReg)ds); 2056220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_FS, (MiscReg)ds); 2066220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_GS, (MiscReg)ds); 2076220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SS, (MiscReg)ds); 2086220Sgblack@eecs.umich.edu 2096220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TSL, 0); 2106220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TSG_BASE, GDTBase); 2116220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TSG_LIMIT, 8 * numGDTEntries - 1); 2126220Sgblack@eecs.umich.edu 2136220Sgblack@eecs.umich.edu SegDescriptor tssDesc = 0; 2146220Sgblack@eecs.umich.edu tssDesc.type = 0xB; 2156220Sgblack@eecs.umich.edu tssDesc.dpl = 0; // Privelege level 0 2166220Sgblack@eecs.umich.edu tssDesc.p = 1; // Present 2176220Sgblack@eecs.umich.edu tssDesc.d = 1; // default operand size 2186220Sgblack@eecs.umich.edu tssDesc.g = 1; // Page granularity 2196220Sgblack@eecs.umich.edu tssDesc.s = 1; // Not a system segment 2206220Sgblack@eecs.umich.edu tssDesc.limitHigh = 0xF; 2216220Sgblack@eecs.umich.edu tssDesc.limitLow = 0xFF; 2226220Sgblack@eecs.umich.edu uint64_t tssDescVal = tssDesc; 2236220Sgblack@eecs.umich.edu physPort->writeBlob(GDTBase + numGDTEntries * 8, 2246220Sgblack@eecs.umich.edu (uint8_t *)(&tssDescVal), 8); 2256220Sgblack@eecs.umich.edu 2266220Sgblack@eecs.umich.edu numGDTEntries++; 2276220Sgblack@eecs.umich.edu 2286220Sgblack@eecs.umich.edu SegSelector tss = 0; 2296220Sgblack@eecs.umich.edu tss.si = numGDTEntries - 1; 2306220Sgblack@eecs.umich.edu 2316220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TR, (MiscReg)tss); 2326220Sgblack@eecs.umich.edu installSegDesc(tc, SYS_SEGMENT_REG_TR, tssDesc, true); 2335299Sgblack@eecs.umich.edu 2345299Sgblack@eecs.umich.edu /* 2355299Sgblack@eecs.umich.edu * Identity map the first 4GB of memory. In order to map this region 2365299Sgblack@eecs.umich.edu * of memory in long mode, there needs to be one actual page map level 2375299Sgblack@eecs.umich.edu * 4 entry which points to one page directory pointer table which 2385299Sgblack@eecs.umich.edu * points to 4 different page directory tables which are full of two 2395299Sgblack@eecs.umich.edu * megabyte pages. All of the other entries in valid tables are set 2405299Sgblack@eecs.umich.edu * to indicate that they don't pertain to anything valid and will 2415299Sgblack@eecs.umich.edu * cause a fault if used. 2425299Sgblack@eecs.umich.edu */ 2435299Sgblack@eecs.umich.edu 2445299Sgblack@eecs.umich.edu // Put valid values in all of the various table entries which indicate 2455299Sgblack@eecs.umich.edu // that those entries don't point to further tables or pages. Then 2465299Sgblack@eecs.umich.edu // set the values of those entries which are needed. 2475299Sgblack@eecs.umich.edu 2485299Sgblack@eecs.umich.edu // Page Map Level 4 2495299Sgblack@eecs.umich.edu 2505299Sgblack@eecs.umich.edu // read/write, user, not present 2515299Sgblack@eecs.umich.edu uint64_t pml4e = X86ISA::htog(0x6); 2525299Sgblack@eecs.umich.edu for (int offset = 0; offset < (1 << PML4Bits) * 8; offset += 8) { 2535299Sgblack@eecs.umich.edu physPort->writeBlob(PageMapLevel4 + offset, (uint8_t *)(&pml4e), 8); 2545299Sgblack@eecs.umich.edu } 2555299Sgblack@eecs.umich.edu // Point to the only PDPT 2565299Sgblack@eecs.umich.edu pml4e = X86ISA::htog(0x7 | PageDirPtrTable); 2575299Sgblack@eecs.umich.edu physPort->writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8); 2585299Sgblack@eecs.umich.edu 2595299Sgblack@eecs.umich.edu // Page Directory Pointer Table 2605299Sgblack@eecs.umich.edu 2615299Sgblack@eecs.umich.edu // read/write, user, not present 2625299Sgblack@eecs.umich.edu uint64_t pdpe = X86ISA::htog(0x6); 2635299Sgblack@eecs.umich.edu for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) { 2645299Sgblack@eecs.umich.edu physPort->writeBlob(PageDirPtrTable + offset, 2655299Sgblack@eecs.umich.edu (uint8_t *)(&pdpe), 8); 2665299Sgblack@eecs.umich.edu } 2675299Sgblack@eecs.umich.edu // Point to the PDTs 2685299Sgblack@eecs.umich.edu for (int table = 0; table < NumPDTs; table++) { 2695299Sgblack@eecs.umich.edu pdpe = X86ISA::htog(0x7 | PageDirTable[table]); 2705299Sgblack@eecs.umich.edu physPort->writeBlob(PageDirPtrTable + table * 8, 2715299Sgblack@eecs.umich.edu (uint8_t *)(&pdpe), 8); 2725299Sgblack@eecs.umich.edu } 2735299Sgblack@eecs.umich.edu 2745299Sgblack@eecs.umich.edu // Page Directory Tables 2755299Sgblack@eecs.umich.edu 2765299Sgblack@eecs.umich.edu Addr base = 0; 2775299Sgblack@eecs.umich.edu const Addr pageSize = 2 << 20; 2785299Sgblack@eecs.umich.edu for (int table = 0; table < NumPDTs; table++) { 2795299Sgblack@eecs.umich.edu for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) { 2805299Sgblack@eecs.umich.edu // read/write, user, present, 4MB 2815299Sgblack@eecs.umich.edu uint64_t pdte = X86ISA::htog(0x87 | base); 2825299Sgblack@eecs.umich.edu physPort->writeBlob(PageDirTable[table] + offset, 2835299Sgblack@eecs.umich.edu (uint8_t *)(&pdte), 8); 2845299Sgblack@eecs.umich.edu base += pageSize; 2855299Sgblack@eecs.umich.edu } 2865299Sgblack@eecs.umich.edu } 2875299Sgblack@eecs.umich.edu 2885299Sgblack@eecs.umich.edu /* 2895299Sgblack@eecs.umich.edu * Transition from real mode all the way up to Long mode 2905299Sgblack@eecs.umich.edu */ 2916220Sgblack@eecs.umich.edu CR0 cr0 = tc->readMiscRegNoEffect(MISCREG_CR0); 2925299Sgblack@eecs.umich.edu //Turn off paging. 2935299Sgblack@eecs.umich.edu cr0.pg = 0; 2946220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 2955299Sgblack@eecs.umich.edu //Turn on protected mode. 2965299Sgblack@eecs.umich.edu cr0.pe = 1; 2976220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 2985299Sgblack@eecs.umich.edu 2996220Sgblack@eecs.umich.edu CR4 cr4 = tc->readMiscRegNoEffect(MISCREG_CR4); 3005299Sgblack@eecs.umich.edu //Turn on pae. 3015299Sgblack@eecs.umich.edu cr4.pae = 1; 3026220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR4, cr4); 3035299Sgblack@eecs.umich.edu 3045299Sgblack@eecs.umich.edu //Point to the page tables. 3056220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR3, PageMapLevel4); 3065299Sgblack@eecs.umich.edu 3076220Sgblack@eecs.umich.edu Efer efer = tc->readMiscRegNoEffect(MISCREG_EFER); 3085299Sgblack@eecs.umich.edu //Enable long mode. 3095299Sgblack@eecs.umich.edu efer.lme = 1; 3106220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_EFER, efer); 3116220Sgblack@eecs.umich.edu 3126220Sgblack@eecs.umich.edu //Start using longmode segments. 3136220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_CS, csDesc, true); 3146220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_DS, dsDesc, true); 3156220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_ES, dsDesc, true); 3166220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_FS, dsDesc, true); 3176220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_GS, dsDesc, true); 3186220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_SS, dsDesc, true); 3195299Sgblack@eecs.umich.edu 3205299Sgblack@eecs.umich.edu //Activate long mode. 3215299Sgblack@eecs.umich.edu cr0.pg = 1; 3226220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 3235299Sgblack@eecs.umich.edu 3247720Sgblack@eecs.umich.edu tc->pcState(tc->getSystemPtr()->kernelEntry); 3255299Sgblack@eecs.umich.edu 3265299Sgblack@eecs.umich.edu // We should now be in long mode. Yay! 3275334Sgblack@eecs.umich.edu 3285615Sgblack@eecs.umich.edu Addr ebdaPos = 0xF0000; 3295625Sgblack@eecs.umich.edu Addr fixed, table; 3305615Sgblack@eecs.umich.edu 3315334Sgblack@eecs.umich.edu //Write out the SMBios/DMI table 3325625Sgblack@eecs.umich.edu writeOutSMBiosTable(ebdaPos, fixed, table); 3335625Sgblack@eecs.umich.edu ebdaPos += (fixed + table); 3345625Sgblack@eecs.umich.edu ebdaPos = roundUp(ebdaPos, 16); 3355625Sgblack@eecs.umich.edu 3365625Sgblack@eecs.umich.edu //Write out the Intel MP Specification configuration table 3375625Sgblack@eecs.umich.edu writeOutMPTable(ebdaPos, fixed, table); 3385625Sgblack@eecs.umich.edu ebdaPos += (fixed + table); 3395299Sgblack@eecs.umich.edu} 3405299Sgblack@eecs.umich.edu 3415334Sgblack@eecs.umich.eduvoid 3425615Sgblack@eecs.umich.eduX86System::writeOutSMBiosTable(Addr header, 3435615Sgblack@eecs.umich.edu Addr &headerSize, Addr &structSize, Addr table) 3445334Sgblack@eecs.umich.edu{ 3455334Sgblack@eecs.umich.edu // Get a port to write the table and header to memory. 3465334Sgblack@eecs.umich.edu FunctionalPort * physPort = threadContexts[0]->getPhysPort(); 3475334Sgblack@eecs.umich.edu 3485334Sgblack@eecs.umich.edu // If the table location isn't specified, just put it after the header. 3495334Sgblack@eecs.umich.edu // The header size as of the 2.5 SMBios specification is 0x1F bytes 3505615Sgblack@eecs.umich.edu if (!table) 3515615Sgblack@eecs.umich.edu table = header + 0x1F; 3525615Sgblack@eecs.umich.edu smbiosTable->setTableAddr(table); 3535334Sgblack@eecs.umich.edu 3545615Sgblack@eecs.umich.edu smbiosTable->writeOut(physPort, header, headerSize, structSize); 3555615Sgblack@eecs.umich.edu 3565615Sgblack@eecs.umich.edu // Do some bounds checking to make sure we at least didn't step on 3575615Sgblack@eecs.umich.edu // ourselves. 3585615Sgblack@eecs.umich.edu assert(header > table || header + headerSize <= table); 3595615Sgblack@eecs.umich.edu assert(table > header || table + structSize <= header); 3605334Sgblack@eecs.umich.edu} 3615334Sgblack@eecs.umich.edu 3625625Sgblack@eecs.umich.eduvoid 3635625Sgblack@eecs.umich.eduX86System::writeOutMPTable(Addr fp, 3645625Sgblack@eecs.umich.edu Addr &fpSize, Addr &tableSize, Addr table) 3655625Sgblack@eecs.umich.edu{ 3665625Sgblack@eecs.umich.edu // Get a port to write the table and header to memory. 3675625Sgblack@eecs.umich.edu FunctionalPort * physPort = threadContexts[0]->getPhysPort(); 3685625Sgblack@eecs.umich.edu 3695625Sgblack@eecs.umich.edu // If the table location isn't specified and it exists, just put 3705625Sgblack@eecs.umich.edu // it after the floating pointer. The fp size as of the 1.4 Intel MP 3715625Sgblack@eecs.umich.edu // specification is 0x10 bytes. 3725625Sgblack@eecs.umich.edu if (mpConfigTable) { 3735625Sgblack@eecs.umich.edu if (!table) 3745625Sgblack@eecs.umich.edu table = fp + 0x10; 3755625Sgblack@eecs.umich.edu mpFloatingPointer->setTableAddr(table); 3765625Sgblack@eecs.umich.edu } 3775625Sgblack@eecs.umich.edu 3785625Sgblack@eecs.umich.edu fpSize = mpFloatingPointer->writeOut(physPort, fp); 3795625Sgblack@eecs.umich.edu if (mpConfigTable) 3805625Sgblack@eecs.umich.edu tableSize = mpConfigTable->writeOut(physPort, table); 3815625Sgblack@eecs.umich.edu else 3825625Sgblack@eecs.umich.edu tableSize = 0; 3835625Sgblack@eecs.umich.edu 3845625Sgblack@eecs.umich.edu // Do some bounds checking to make sure we at least didn't step on 3855625Sgblack@eecs.umich.edu // ourselves and the fp structure was the size we thought it was. 3865625Sgblack@eecs.umich.edu assert(fp > table || fp + fpSize <= table); 3875625Sgblack@eecs.umich.edu assert(table > fp || table + tableSize <= fp); 3885625Sgblack@eecs.umich.edu assert(fpSize == 0x10); 3895625Sgblack@eecs.umich.edu} 3905625Sgblack@eecs.umich.edu 3915334Sgblack@eecs.umich.edu 3925132Sgblack@eecs.umich.eduX86System::~X86System() 3935132Sgblack@eecs.umich.edu{ 3945334Sgblack@eecs.umich.edu delete smbiosTable; 3955132Sgblack@eecs.umich.edu} 3965132Sgblack@eecs.umich.edu 3975132Sgblack@eecs.umich.eduvoid 3985132Sgblack@eecs.umich.eduX86System::serialize(std::ostream &os) 3995132Sgblack@eecs.umich.edu{ 4005132Sgblack@eecs.umich.edu System::serialize(os); 4015132Sgblack@eecs.umich.edu} 4025132Sgblack@eecs.umich.edu 4035132Sgblack@eecs.umich.edu 4045132Sgblack@eecs.umich.eduvoid 4055132Sgblack@eecs.umich.eduX86System::unserialize(Checkpoint *cp, const std::string §ion) 4065132Sgblack@eecs.umich.edu{ 4075132Sgblack@eecs.umich.edu System::unserialize(cp,section); 4085132Sgblack@eecs.umich.edu} 4095132Sgblack@eecs.umich.edu 4105132Sgblack@eecs.umich.eduX86System * 4115132Sgblack@eecs.umich.eduX86SystemParams::create() 4125132Sgblack@eecs.umich.edu{ 4135132Sgblack@eecs.umich.edu return new X86System(this); 4145132Sgblack@eecs.umich.edu} 415