system.cc revision 7087
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" 425299Sgblack@eecs.umich.edu#include "arch/x86/miscregs.hh" 435132Sgblack@eecs.umich.edu#include "arch/x86/system.hh" 445132Sgblack@eecs.umich.edu#include "arch/vtophys.hh" 455625Sgblack@eecs.umich.edu#include "base/intmath.hh" 465132Sgblack@eecs.umich.edu#include "base/loader/object_file.hh" 475132Sgblack@eecs.umich.edu#include "base/loader/symtab.hh" 485625Sgblack@eecs.umich.edu#include "base/remote_gdb.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) 645615Sgblack@eecs.umich.edu{} 655132Sgblack@eecs.umich.edu 666220Sgblack@eecs.umich.edustatic void 676220Sgblack@eecs.umich.eduinstallSegDesc(ThreadContext *tc, SegmentRegIndex seg, 686220Sgblack@eecs.umich.edu SegDescriptor desc, bool longmode) 696220Sgblack@eecs.umich.edu{ 706220Sgblack@eecs.umich.edu uint64_t base = desc.baseLow + (desc.baseHigh << 24); 716220Sgblack@eecs.umich.edu bool honorBase = !longmode || seg == SEGMENT_REG_FS || 726220Sgblack@eecs.umich.edu seg == SEGMENT_REG_GS || 736220Sgblack@eecs.umich.edu seg == SEGMENT_REG_TSL || 746220Sgblack@eecs.umich.edu seg == SYS_SEGMENT_REG_TR; 756220Sgblack@eecs.umich.edu uint64_t limit = desc.limitLow | (desc.limitHigh << 16); 766220Sgblack@eecs.umich.edu 776220Sgblack@eecs.umich.edu SegAttr attr = 0; 786222Sgblack@eecs.umich.edu 796222Sgblack@eecs.umich.edu attr.dpl = desc.dpl; 806222Sgblack@eecs.umich.edu attr.unusable = 0; 816222Sgblack@eecs.umich.edu attr.defaultSize = desc.d; 826222Sgblack@eecs.umich.edu attr.longMode = desc.l; 836222Sgblack@eecs.umich.edu attr.avl = desc.avl; 846222Sgblack@eecs.umich.edu attr.granularity = desc.g; 856222Sgblack@eecs.umich.edu attr.present = desc.p; 866222Sgblack@eecs.umich.edu attr.system = desc.s; 876222Sgblack@eecs.umich.edu attr.type = desc.type; 886220Sgblack@eecs.umich.edu if (desc.s) { 896220Sgblack@eecs.umich.edu if (desc.type.codeOrData) { 906220Sgblack@eecs.umich.edu // Code segment 916222Sgblack@eecs.umich.edu attr.expandDown = 0; 926220Sgblack@eecs.umich.edu attr.readable = desc.type.r; 936222Sgblack@eecs.umich.edu attr.writable = 0; 946220Sgblack@eecs.umich.edu } else { 956220Sgblack@eecs.umich.edu // Data segment 966222Sgblack@eecs.umich.edu attr.expandDown = desc.type.e; 976220Sgblack@eecs.umich.edu attr.readable = 1; 986220Sgblack@eecs.umich.edu attr.writable = desc.type.w; 996220Sgblack@eecs.umich.edu } 1006220Sgblack@eecs.umich.edu } else { 1016222Sgblack@eecs.umich.edu attr.readable = 1; 1026220Sgblack@eecs.umich.edu attr.writable = 1; 1036220Sgblack@eecs.umich.edu attr.expandDown = 0; 1046220Sgblack@eecs.umich.edu } 1056220Sgblack@eecs.umich.edu 1066220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_BASE(seg), base); 1076220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_EFF_BASE(seg), honorBase ? base : 0); 1086220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_LIMIT(seg), limit); 1096220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_ATTR(seg), (MiscReg)attr); 1106220Sgblack@eecs.umich.edu} 1116220Sgblack@eecs.umich.edu 1125299Sgblack@eecs.umich.eduvoid 1135299Sgblack@eecs.umich.eduX86System::startup() 1145299Sgblack@eecs.umich.edu{ 1155299Sgblack@eecs.umich.edu System::startup(); 1166220Sgblack@eecs.umich.edu ThreadContext *tc = threadContexts[0]; 1175299Sgblack@eecs.umich.edu // This is the boot strap processor (BSP). Initialize it to look like 1185299Sgblack@eecs.umich.edu // the boot loader has just turned control over to the 64 bit OS. We 1195299Sgblack@eecs.umich.edu // won't actually set up real mode or legacy protected mode descriptor 1205299Sgblack@eecs.umich.edu // tables because we aren't executing any code that would require 1215299Sgblack@eecs.umich.edu // them. We do, however toggle the control bits in the correct order 1225299Sgblack@eecs.umich.edu // while allowing consistency checks and the underlying mechansims 1235299Sgblack@eecs.umich.edu // just to be safe. 1245299Sgblack@eecs.umich.edu 1255299Sgblack@eecs.umich.edu const int NumPDTs = 4; 1265299Sgblack@eecs.umich.edu 1275299Sgblack@eecs.umich.edu const Addr PageMapLevel4 = 0x70000; 1285299Sgblack@eecs.umich.edu const Addr PageDirPtrTable = 0x71000; 1295299Sgblack@eecs.umich.edu const Addr PageDirTable[NumPDTs] = 1305299Sgblack@eecs.umich.edu {0x72000, 0x73000, 0x74000, 0x75000}; 1315299Sgblack@eecs.umich.edu const Addr GDTBase = 0x76000; 1325299Sgblack@eecs.umich.edu 1335299Sgblack@eecs.umich.edu const int PML4Bits = 9; 1345299Sgblack@eecs.umich.edu const int PDPTBits = 9; 1355299Sgblack@eecs.umich.edu const int PDTBits = 9; 1365299Sgblack@eecs.umich.edu 1375299Sgblack@eecs.umich.edu // Get a port to write the page tables and descriptor tables. 1386220Sgblack@eecs.umich.edu FunctionalPort * physPort = tc->getPhysPort(); 1395299Sgblack@eecs.umich.edu 1405299Sgblack@eecs.umich.edu /* 1415299Sgblack@eecs.umich.edu * Set up the gdt. 1425299Sgblack@eecs.umich.edu */ 1436220Sgblack@eecs.umich.edu uint8_t numGDTEntries = 0; 1445299Sgblack@eecs.umich.edu // Place holder at selector 0 1455299Sgblack@eecs.umich.edu uint64_t nullDescriptor = 0; 1466220Sgblack@eecs.umich.edu physPort->writeBlob(GDTBase + numGDTEntries * 8, 1476220Sgblack@eecs.umich.edu (uint8_t *)(&nullDescriptor), 8); 1486220Sgblack@eecs.umich.edu numGDTEntries++; 1495299Sgblack@eecs.umich.edu 1505299Sgblack@eecs.umich.edu //64 bit code segment 1515299Sgblack@eecs.umich.edu SegDescriptor csDesc = 0; 1526220Sgblack@eecs.umich.edu csDesc.type.codeOrData = 1; 1535299Sgblack@eecs.umich.edu csDesc.type.c = 0; // Not conforming 1546220Sgblack@eecs.umich.edu csDesc.type.r = 1; // Readable 1555299Sgblack@eecs.umich.edu csDesc.dpl = 0; // Privelege level 0 1565299Sgblack@eecs.umich.edu csDesc.p = 1; // Present 1575299Sgblack@eecs.umich.edu csDesc.l = 1; // 64 bit 1585299Sgblack@eecs.umich.edu csDesc.d = 0; // default operand size 1596220Sgblack@eecs.umich.edu csDesc.g = 1; // Page granularity 1606220Sgblack@eecs.umich.edu csDesc.s = 1; // Not a system segment 1616220Sgblack@eecs.umich.edu csDesc.limitHigh = 0xF; 1626220Sgblack@eecs.umich.edu csDesc.limitLow = 0xFF; 1635299Sgblack@eecs.umich.edu //Because we're dealing with a pointer and I don't think it's 1645299Sgblack@eecs.umich.edu //guaranteed that there isn't anything in a nonvirtual class between 1655299Sgblack@eecs.umich.edu //it's beginning in memory and it's actual data, we'll use an 1665299Sgblack@eecs.umich.edu //intermediary. 1675299Sgblack@eecs.umich.edu uint64_t csDescVal = csDesc; 1686220Sgblack@eecs.umich.edu physPort->writeBlob(GDTBase + numGDTEntries * 8, 1696220Sgblack@eecs.umich.edu (uint8_t *)(&csDescVal), 8); 1705299Sgblack@eecs.umich.edu 1716220Sgblack@eecs.umich.edu numGDTEntries++; 1726220Sgblack@eecs.umich.edu 1736220Sgblack@eecs.umich.edu SegSelector cs = 0; 1746220Sgblack@eecs.umich.edu cs.si = numGDTEntries - 1; 1756220Sgblack@eecs.umich.edu 1766220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CS, (MiscReg)cs); 1776220Sgblack@eecs.umich.edu 1786220Sgblack@eecs.umich.edu //32 bit data segment 1796220Sgblack@eecs.umich.edu SegDescriptor dsDesc = 0; 1806220Sgblack@eecs.umich.edu dsDesc.type.codeOrData = 0; 1816220Sgblack@eecs.umich.edu dsDesc.type.e = 0; // Not expand down 1826220Sgblack@eecs.umich.edu dsDesc.type.w = 1; // Writable 1836220Sgblack@eecs.umich.edu dsDesc.dpl = 0; // Privelege level 0 1846220Sgblack@eecs.umich.edu dsDesc.p = 1; // Present 1856220Sgblack@eecs.umich.edu dsDesc.d = 1; // default operand size 1866220Sgblack@eecs.umich.edu dsDesc.g = 1; // Page granularity 1876220Sgblack@eecs.umich.edu dsDesc.s = 1; // Not a system segment 1886220Sgblack@eecs.umich.edu dsDesc.limitHigh = 0xF; 1896220Sgblack@eecs.umich.edu dsDesc.limitLow = 0xFF; 1906220Sgblack@eecs.umich.edu uint64_t dsDescVal = dsDesc; 1916220Sgblack@eecs.umich.edu physPort->writeBlob(GDTBase + numGDTEntries * 8, 1926220Sgblack@eecs.umich.edu (uint8_t *)(&dsDescVal), 8); 1936220Sgblack@eecs.umich.edu 1946220Sgblack@eecs.umich.edu numGDTEntries++; 1956220Sgblack@eecs.umich.edu 1966712Snate@binkert.org SegSelector ds = 0; 1976220Sgblack@eecs.umich.edu ds.si = numGDTEntries - 1; 1986220Sgblack@eecs.umich.edu 1996220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_DS, (MiscReg)ds); 2006220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_ES, (MiscReg)ds); 2016220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_FS, (MiscReg)ds); 2026220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_GS, (MiscReg)ds); 2036220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_SS, (MiscReg)ds); 2046220Sgblack@eecs.umich.edu 2056220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TSL, 0); 2066220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TSG_BASE, GDTBase); 2076220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TSG_LIMIT, 8 * numGDTEntries - 1); 2086220Sgblack@eecs.umich.edu 2096220Sgblack@eecs.umich.edu SegDescriptor tssDesc = 0; 2106220Sgblack@eecs.umich.edu tssDesc.type = 0xB; 2116220Sgblack@eecs.umich.edu tssDesc.dpl = 0; // Privelege level 0 2126220Sgblack@eecs.umich.edu tssDesc.p = 1; // Present 2136220Sgblack@eecs.umich.edu tssDesc.d = 1; // default operand size 2146220Sgblack@eecs.umich.edu tssDesc.g = 1; // Page granularity 2156220Sgblack@eecs.umich.edu tssDesc.s = 1; // Not a system segment 2166220Sgblack@eecs.umich.edu tssDesc.limitHigh = 0xF; 2176220Sgblack@eecs.umich.edu tssDesc.limitLow = 0xFF; 2186220Sgblack@eecs.umich.edu uint64_t tssDescVal = tssDesc; 2196220Sgblack@eecs.umich.edu physPort->writeBlob(GDTBase + numGDTEntries * 8, 2206220Sgblack@eecs.umich.edu (uint8_t *)(&tssDescVal), 8); 2216220Sgblack@eecs.umich.edu 2226220Sgblack@eecs.umich.edu numGDTEntries++; 2236220Sgblack@eecs.umich.edu 2246220Sgblack@eecs.umich.edu SegSelector tss = 0; 2256220Sgblack@eecs.umich.edu tss.si = numGDTEntries - 1; 2266220Sgblack@eecs.umich.edu 2276220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TR, (MiscReg)tss); 2286220Sgblack@eecs.umich.edu installSegDesc(tc, SYS_SEGMENT_REG_TR, tssDesc, true); 2295299Sgblack@eecs.umich.edu 2305299Sgblack@eecs.umich.edu /* 2315299Sgblack@eecs.umich.edu * Identity map the first 4GB of memory. In order to map this region 2325299Sgblack@eecs.umich.edu * of memory in long mode, there needs to be one actual page map level 2335299Sgblack@eecs.umich.edu * 4 entry which points to one page directory pointer table which 2345299Sgblack@eecs.umich.edu * points to 4 different page directory tables which are full of two 2355299Sgblack@eecs.umich.edu * megabyte pages. All of the other entries in valid tables are set 2365299Sgblack@eecs.umich.edu * to indicate that they don't pertain to anything valid and will 2375299Sgblack@eecs.umich.edu * cause a fault if used. 2385299Sgblack@eecs.umich.edu */ 2395299Sgblack@eecs.umich.edu 2405299Sgblack@eecs.umich.edu // Put valid values in all of the various table entries which indicate 2415299Sgblack@eecs.umich.edu // that those entries don't point to further tables or pages. Then 2425299Sgblack@eecs.umich.edu // set the values of those entries which are needed. 2435299Sgblack@eecs.umich.edu 2445299Sgblack@eecs.umich.edu // Page Map Level 4 2455299Sgblack@eecs.umich.edu 2465299Sgblack@eecs.umich.edu // read/write, user, not present 2475299Sgblack@eecs.umich.edu uint64_t pml4e = X86ISA::htog(0x6); 2485299Sgblack@eecs.umich.edu for (int offset = 0; offset < (1 << PML4Bits) * 8; offset += 8) { 2495299Sgblack@eecs.umich.edu physPort->writeBlob(PageMapLevel4 + offset, (uint8_t *)(&pml4e), 8); 2505299Sgblack@eecs.umich.edu } 2515299Sgblack@eecs.umich.edu // Point to the only PDPT 2525299Sgblack@eecs.umich.edu pml4e = X86ISA::htog(0x7 | PageDirPtrTable); 2535299Sgblack@eecs.umich.edu physPort->writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8); 2545299Sgblack@eecs.umich.edu 2555299Sgblack@eecs.umich.edu // Page Directory Pointer Table 2565299Sgblack@eecs.umich.edu 2575299Sgblack@eecs.umich.edu // read/write, user, not present 2585299Sgblack@eecs.umich.edu uint64_t pdpe = X86ISA::htog(0x6); 2595299Sgblack@eecs.umich.edu for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) { 2605299Sgblack@eecs.umich.edu physPort->writeBlob(PageDirPtrTable + offset, 2615299Sgblack@eecs.umich.edu (uint8_t *)(&pdpe), 8); 2625299Sgblack@eecs.umich.edu } 2635299Sgblack@eecs.umich.edu // Point to the PDTs 2645299Sgblack@eecs.umich.edu for (int table = 0; table < NumPDTs; table++) { 2655299Sgblack@eecs.umich.edu pdpe = X86ISA::htog(0x7 | PageDirTable[table]); 2665299Sgblack@eecs.umich.edu physPort->writeBlob(PageDirPtrTable + table * 8, 2675299Sgblack@eecs.umich.edu (uint8_t *)(&pdpe), 8); 2685299Sgblack@eecs.umich.edu } 2695299Sgblack@eecs.umich.edu 2705299Sgblack@eecs.umich.edu // Page Directory Tables 2715299Sgblack@eecs.umich.edu 2725299Sgblack@eecs.umich.edu Addr base = 0; 2735299Sgblack@eecs.umich.edu const Addr pageSize = 2 << 20; 2745299Sgblack@eecs.umich.edu for (int table = 0; table < NumPDTs; table++) { 2755299Sgblack@eecs.umich.edu for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) { 2765299Sgblack@eecs.umich.edu // read/write, user, present, 4MB 2775299Sgblack@eecs.umich.edu uint64_t pdte = X86ISA::htog(0x87 | base); 2785299Sgblack@eecs.umich.edu physPort->writeBlob(PageDirTable[table] + offset, 2795299Sgblack@eecs.umich.edu (uint8_t *)(&pdte), 8); 2805299Sgblack@eecs.umich.edu base += pageSize; 2815299Sgblack@eecs.umich.edu } 2825299Sgblack@eecs.umich.edu } 2835299Sgblack@eecs.umich.edu 2845299Sgblack@eecs.umich.edu /* 2855299Sgblack@eecs.umich.edu * Transition from real mode all the way up to Long mode 2865299Sgblack@eecs.umich.edu */ 2876220Sgblack@eecs.umich.edu CR0 cr0 = tc->readMiscRegNoEffect(MISCREG_CR0); 2885299Sgblack@eecs.umich.edu //Turn off paging. 2895299Sgblack@eecs.umich.edu cr0.pg = 0; 2906220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 2915299Sgblack@eecs.umich.edu //Turn on protected mode. 2925299Sgblack@eecs.umich.edu cr0.pe = 1; 2936220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 2945299Sgblack@eecs.umich.edu 2956220Sgblack@eecs.umich.edu CR4 cr4 = tc->readMiscRegNoEffect(MISCREG_CR4); 2965299Sgblack@eecs.umich.edu //Turn on pae. 2975299Sgblack@eecs.umich.edu cr4.pae = 1; 2986220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR4, cr4); 2995299Sgblack@eecs.umich.edu 3005299Sgblack@eecs.umich.edu //Point to the page tables. 3016220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR3, PageMapLevel4); 3025299Sgblack@eecs.umich.edu 3036220Sgblack@eecs.umich.edu Efer efer = tc->readMiscRegNoEffect(MISCREG_EFER); 3045299Sgblack@eecs.umich.edu //Enable long mode. 3055299Sgblack@eecs.umich.edu efer.lme = 1; 3066220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_EFER, efer); 3076220Sgblack@eecs.umich.edu 3086220Sgblack@eecs.umich.edu //Start using longmode segments. 3096220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_CS, csDesc, true); 3106220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_DS, dsDesc, true); 3116220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_ES, dsDesc, true); 3126220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_FS, dsDesc, true); 3136220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_GS, dsDesc, true); 3146220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_SS, dsDesc, true); 3155299Sgblack@eecs.umich.edu 3165299Sgblack@eecs.umich.edu //Activate long mode. 3175299Sgblack@eecs.umich.edu cr0.pg = 1; 3186220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 3195299Sgblack@eecs.umich.edu 3206220Sgblack@eecs.umich.edu tc->setPC(tc->getSystemPtr()->kernelEntry); 3216220Sgblack@eecs.umich.edu tc->setNextPC(tc->readPC()); 3225299Sgblack@eecs.umich.edu 3235299Sgblack@eecs.umich.edu // We should now be in long mode. Yay! 3245334Sgblack@eecs.umich.edu 3255615Sgblack@eecs.umich.edu Addr ebdaPos = 0xF0000; 3265625Sgblack@eecs.umich.edu Addr fixed, table; 3275615Sgblack@eecs.umich.edu 3285334Sgblack@eecs.umich.edu //Write out the SMBios/DMI table 3295625Sgblack@eecs.umich.edu writeOutSMBiosTable(ebdaPos, fixed, table); 3305625Sgblack@eecs.umich.edu ebdaPos += (fixed + table); 3315625Sgblack@eecs.umich.edu ebdaPos = roundUp(ebdaPos, 16); 3325625Sgblack@eecs.umich.edu 3335625Sgblack@eecs.umich.edu //Write out the Intel MP Specification configuration table 3345625Sgblack@eecs.umich.edu writeOutMPTable(ebdaPos, fixed, table); 3355625Sgblack@eecs.umich.edu ebdaPos += (fixed + table); 3365299Sgblack@eecs.umich.edu} 3375299Sgblack@eecs.umich.edu 3385334Sgblack@eecs.umich.eduvoid 3395615Sgblack@eecs.umich.eduX86System::writeOutSMBiosTable(Addr header, 3405615Sgblack@eecs.umich.edu Addr &headerSize, Addr &structSize, Addr table) 3415334Sgblack@eecs.umich.edu{ 3425334Sgblack@eecs.umich.edu // Get a port to write the table and header to memory. 3435334Sgblack@eecs.umich.edu FunctionalPort * physPort = threadContexts[0]->getPhysPort(); 3445334Sgblack@eecs.umich.edu 3455334Sgblack@eecs.umich.edu // If the table location isn't specified, just put it after the header. 3465334Sgblack@eecs.umich.edu // The header size as of the 2.5 SMBios specification is 0x1F bytes 3475615Sgblack@eecs.umich.edu if (!table) 3485615Sgblack@eecs.umich.edu table = header + 0x1F; 3495615Sgblack@eecs.umich.edu smbiosTable->setTableAddr(table); 3505334Sgblack@eecs.umich.edu 3515615Sgblack@eecs.umich.edu smbiosTable->writeOut(physPort, header, headerSize, structSize); 3525615Sgblack@eecs.umich.edu 3535615Sgblack@eecs.umich.edu // Do some bounds checking to make sure we at least didn't step on 3545615Sgblack@eecs.umich.edu // ourselves. 3555615Sgblack@eecs.umich.edu assert(header > table || header + headerSize <= table); 3565615Sgblack@eecs.umich.edu assert(table > header || table + structSize <= header); 3575334Sgblack@eecs.umich.edu} 3585334Sgblack@eecs.umich.edu 3595625Sgblack@eecs.umich.eduvoid 3605625Sgblack@eecs.umich.eduX86System::writeOutMPTable(Addr fp, 3615625Sgblack@eecs.umich.edu Addr &fpSize, Addr &tableSize, Addr table) 3625625Sgblack@eecs.umich.edu{ 3635625Sgblack@eecs.umich.edu // Get a port to write the table and header to memory. 3645625Sgblack@eecs.umich.edu FunctionalPort * physPort = threadContexts[0]->getPhysPort(); 3655625Sgblack@eecs.umich.edu 3665625Sgblack@eecs.umich.edu // If the table location isn't specified and it exists, just put 3675625Sgblack@eecs.umich.edu // it after the floating pointer. The fp size as of the 1.4 Intel MP 3685625Sgblack@eecs.umich.edu // specification is 0x10 bytes. 3695625Sgblack@eecs.umich.edu if (mpConfigTable) { 3705625Sgblack@eecs.umich.edu if (!table) 3715625Sgblack@eecs.umich.edu table = fp + 0x10; 3725625Sgblack@eecs.umich.edu mpFloatingPointer->setTableAddr(table); 3735625Sgblack@eecs.umich.edu } 3745625Sgblack@eecs.umich.edu 3755625Sgblack@eecs.umich.edu fpSize = mpFloatingPointer->writeOut(physPort, fp); 3765625Sgblack@eecs.umich.edu if (mpConfigTable) 3775625Sgblack@eecs.umich.edu tableSize = mpConfigTable->writeOut(physPort, table); 3785625Sgblack@eecs.umich.edu else 3795625Sgblack@eecs.umich.edu tableSize = 0; 3805625Sgblack@eecs.umich.edu 3815625Sgblack@eecs.umich.edu // Do some bounds checking to make sure we at least didn't step on 3825625Sgblack@eecs.umich.edu // ourselves and the fp structure was the size we thought it was. 3835625Sgblack@eecs.umich.edu assert(fp > table || fp + fpSize <= table); 3845625Sgblack@eecs.umich.edu assert(table > fp || table + tableSize <= fp); 3855625Sgblack@eecs.umich.edu assert(fpSize == 0x10); 3865625Sgblack@eecs.umich.edu} 3875625Sgblack@eecs.umich.edu 3885334Sgblack@eecs.umich.edu 3895132Sgblack@eecs.umich.eduX86System::~X86System() 3905132Sgblack@eecs.umich.edu{ 3915334Sgblack@eecs.umich.edu delete smbiosTable; 3925132Sgblack@eecs.umich.edu} 3935132Sgblack@eecs.umich.edu 3945132Sgblack@eecs.umich.eduvoid 3955132Sgblack@eecs.umich.eduX86System::serialize(std::ostream &os) 3965132Sgblack@eecs.umich.edu{ 3975132Sgblack@eecs.umich.edu System::serialize(os); 3985132Sgblack@eecs.umich.edu} 3995132Sgblack@eecs.umich.edu 4005132Sgblack@eecs.umich.edu 4015132Sgblack@eecs.umich.eduvoid 4025132Sgblack@eecs.umich.eduX86System::unserialize(Checkpoint *cp, const std::string §ion) 4035132Sgblack@eecs.umich.edu{ 4045132Sgblack@eecs.umich.edu System::unserialize(cp,section); 4055132Sgblack@eecs.umich.edu} 4065132Sgblack@eecs.umich.edu 4075132Sgblack@eecs.umich.eduX86System * 4085132Sgblack@eecs.umich.eduX86SystemParams::create() 4095132Sgblack@eecs.umich.edu{ 4105132Sgblack@eecs.umich.edu return new X86System(this); 4115132Sgblack@eecs.umich.edu} 412