system.cc revision 14010
15132Sgblack@eecs.umich.edu/* 25132Sgblack@eecs.umich.edu * Copyright (c) 2007 The Hewlett-Packard Development Company 312483Smaximilian.stein@tu-dresden.de * Copyright (c) 2018 TU Dresden 45132Sgblack@eecs.umich.edu * All rights reserved. 55132Sgblack@eecs.umich.edu * 67087Snate@binkert.org * The license below extends only to copyright in the software and shall 77087Snate@binkert.org * not be construed as granting a license to any other intellectual 87087Snate@binkert.org * property including but not limited to intellectual property relating 97087Snate@binkert.org * to a hardware implementation of the functionality of the software 107087Snate@binkert.org * licensed hereunder. You may use the software subject to the license 117087Snate@binkert.org * terms below provided that you ensure that this notice is replicated 127087Snate@binkert.org * unmodified and in its entirety in all distributions of the software, 137087Snate@binkert.org * modified or unmodified, in source code or in binary form. 145132Sgblack@eecs.umich.edu * 157087Snate@binkert.org * Redistribution and use in source and binary forms, with or without 167087Snate@binkert.org * modification, are permitted provided that the following conditions are 177087Snate@binkert.org * met: redistributions of source code must retain the above copyright 187087Snate@binkert.org * notice, this list of conditions and the following disclaimer; 197087Snate@binkert.org * redistributions in binary form must reproduce the above copyright 207087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 217087Snate@binkert.org * documentation and/or other materials provided with the distribution; 227087Snate@binkert.org * neither the name of the copyright holders nor the names of its 235132Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 247087Snate@binkert.org * this software without specific prior written permission. 255132Sgblack@eecs.umich.edu * 265132Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 275132Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 285132Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 295132Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 305132Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 315132Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 325132Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 335132Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 345132Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 355132Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 365132Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 375132Sgblack@eecs.umich.edu * 385132Sgblack@eecs.umich.edu * Authors: Gabe Black 3912483Smaximilian.stein@tu-dresden.de * Maximilian Stein 405132Sgblack@eecs.umich.edu */ 415132Sgblack@eecs.umich.edu 4211793Sbrandon.potter@amd.com#include "arch/x86/system.hh" 4311793Sbrandon.potter@amd.com 448229Snate@binkert.org#include "arch/x86/bios/intelmp.hh" 455612Sgblack@eecs.umich.edu#include "arch/x86/bios/smbios.hh" 4611793Sbrandon.potter@amd.com#include "arch/x86/isa_traits.hh" 475132Sgblack@eecs.umich.edu#include "base/loader/object_file.hh" 485299Sgblack@eecs.umich.edu#include "cpu/thread_context.hh" 495132Sgblack@eecs.umich.edu#include "params/X86System.hh" 505132Sgblack@eecs.umich.edu 515299Sgblack@eecs.umich.eduusing namespace LittleEndianGuest; 525299Sgblack@eecs.umich.eduusing namespace X86ISA; 535132Sgblack@eecs.umich.edu 545625Sgblack@eecs.umich.eduX86System::X86System(Params *p) : 555625Sgblack@eecs.umich.edu System(p), smbiosTable(p->smbios_table), 565625Sgblack@eecs.umich.edu mpFloatingPointer(p->intel_mp_pointer), 575627Sgblack@eecs.umich.edu mpConfigTable(p->intel_mp_table), 585627Sgblack@eecs.umich.edu rsdp(p->acpi_description_table_pointer) 597704Sgblack@eecs.umich.edu{ 607704Sgblack@eecs.umich.edu} 615132Sgblack@eecs.umich.edu 6210554Salexandru.dutu@amd.comvoid 6310554Salexandru.dutu@amd.comX86ISA::installSegDesc(ThreadContext *tc, SegmentRegIndex seg, 646220Sgblack@eecs.umich.edu SegDescriptor desc, bool longmode) 656220Sgblack@eecs.umich.edu{ 666220Sgblack@eecs.umich.edu bool honorBase = !longmode || seg == SEGMENT_REG_FS || 676220Sgblack@eecs.umich.edu seg == SEGMENT_REG_GS || 686220Sgblack@eecs.umich.edu seg == SEGMENT_REG_TSL || 696220Sgblack@eecs.umich.edu seg == SYS_SEGMENT_REG_TR; 706220Sgblack@eecs.umich.edu 716220Sgblack@eecs.umich.edu SegAttr attr = 0; 726222Sgblack@eecs.umich.edu 736222Sgblack@eecs.umich.edu attr.dpl = desc.dpl; 746222Sgblack@eecs.umich.edu attr.unusable = 0; 756222Sgblack@eecs.umich.edu attr.defaultSize = desc.d; 766222Sgblack@eecs.umich.edu attr.longMode = desc.l; 776222Sgblack@eecs.umich.edu attr.avl = desc.avl; 786222Sgblack@eecs.umich.edu attr.granularity = desc.g; 796222Sgblack@eecs.umich.edu attr.present = desc.p; 806222Sgblack@eecs.umich.edu attr.system = desc.s; 816222Sgblack@eecs.umich.edu attr.type = desc.type; 826220Sgblack@eecs.umich.edu if (desc.s) { 836220Sgblack@eecs.umich.edu if (desc.type.codeOrData) { 846220Sgblack@eecs.umich.edu // Code segment 856222Sgblack@eecs.umich.edu attr.expandDown = 0; 866220Sgblack@eecs.umich.edu attr.readable = desc.type.r; 876222Sgblack@eecs.umich.edu attr.writable = 0; 886220Sgblack@eecs.umich.edu } else { 896220Sgblack@eecs.umich.edu // Data segment 906222Sgblack@eecs.umich.edu attr.expandDown = desc.type.e; 916220Sgblack@eecs.umich.edu attr.readable = 1; 926220Sgblack@eecs.umich.edu attr.writable = desc.type.w; 936220Sgblack@eecs.umich.edu } 946220Sgblack@eecs.umich.edu } else { 956222Sgblack@eecs.umich.edu attr.readable = 1; 966220Sgblack@eecs.umich.edu attr.writable = 1; 976220Sgblack@eecs.umich.edu attr.expandDown = 0; 986220Sgblack@eecs.umich.edu } 996220Sgblack@eecs.umich.edu 10012588Sgabeblack@google.com tc->setMiscReg(MISCREG_SEG_BASE(seg), desc.base); 10112588Sgabeblack@google.com tc->setMiscReg(MISCREG_SEG_EFF_BASE(seg), honorBase ? desc.base : 0); 10212588Sgabeblack@google.com tc->setMiscReg(MISCREG_SEG_LIMIT(seg), desc.limit); 10313613Sgabeblack@google.com tc->setMiscReg(MISCREG_SEG_ATTR(seg), (RegVal)attr); 1046220Sgblack@eecs.umich.edu} 1056220Sgblack@eecs.umich.edu 1065299Sgblack@eecs.umich.eduvoid 1077532Ssteve.reinhardt@amd.comX86System::initState() 1085299Sgblack@eecs.umich.edu{ 1097532Ssteve.reinhardt@amd.com System::initState(); 1107532Ssteve.reinhardt@amd.com 1118958Sgblack@eecs.umich.edu if (!kernel) 1128958Sgblack@eecs.umich.edu fatal("No kernel to load.\n"); 1138958Sgblack@eecs.umich.edu 1148706Sandreas.hansson@arm.com if (kernel->getArch() == ObjectFile::I386) 1158706Sandreas.hansson@arm.com fatal("Loading a 32 bit x86 kernel is not supported.\n"); 1168706Sandreas.hansson@arm.com 1176220Sgblack@eecs.umich.edu ThreadContext *tc = threadContexts[0]; 1185299Sgblack@eecs.umich.edu // This is the boot strap processor (BSP). Initialize it to look like 1195299Sgblack@eecs.umich.edu // the boot loader has just turned control over to the 64 bit OS. We 1205299Sgblack@eecs.umich.edu // won't actually set up real mode or legacy protected mode descriptor 1215299Sgblack@eecs.umich.edu // tables because we aren't executing any code that would require 1225299Sgblack@eecs.umich.edu // them. We do, however toggle the control bits in the correct order 1235299Sgblack@eecs.umich.edu // while allowing consistency checks and the underlying mechansims 1245299Sgblack@eecs.umich.edu // just to be safe. 1255299Sgblack@eecs.umich.edu 1265299Sgblack@eecs.umich.edu const int NumPDTs = 4; 1275299Sgblack@eecs.umich.edu 1285299Sgblack@eecs.umich.edu const Addr PageMapLevel4 = 0x70000; 1295299Sgblack@eecs.umich.edu const Addr PageDirPtrTable = 0x71000; 1305299Sgblack@eecs.umich.edu const Addr PageDirTable[NumPDTs] = 1315299Sgblack@eecs.umich.edu {0x72000, 0x73000, 0x74000, 0x75000}; 1325299Sgblack@eecs.umich.edu const Addr GDTBase = 0x76000; 1335299Sgblack@eecs.umich.edu 1345299Sgblack@eecs.umich.edu const int PML4Bits = 9; 1355299Sgblack@eecs.umich.edu const int PDPTBits = 9; 1365299Sgblack@eecs.umich.edu const int PDTBits = 9; 1375299Sgblack@eecs.umich.edu 1385299Sgblack@eecs.umich.edu /* 1395299Sgblack@eecs.umich.edu * Set up the gdt. 1405299Sgblack@eecs.umich.edu */ 1416220Sgblack@eecs.umich.edu uint8_t numGDTEntries = 0; 1425299Sgblack@eecs.umich.edu // Place holder at selector 0 1435299Sgblack@eecs.umich.edu uint64_t nullDescriptor = 0; 14414010Sgabeblack@google.com physProxy.writeBlob(GDTBase + numGDTEntries * 8, &nullDescriptor, 8); 1456220Sgblack@eecs.umich.edu numGDTEntries++; 1465299Sgblack@eecs.umich.edu 14710554Salexandru.dutu@amd.com SegDescriptor initDesc = 0; 14810554Salexandru.dutu@amd.com initDesc.type.codeOrData = 0; // code or data type 14910554Salexandru.dutu@amd.com initDesc.type.c = 0; // conforming 15010554Salexandru.dutu@amd.com initDesc.type.r = 1; // readable 15110554Salexandru.dutu@amd.com initDesc.dpl = 0; // privilege 15210554Salexandru.dutu@amd.com initDesc.p = 1; // present 15310554Salexandru.dutu@amd.com initDesc.l = 1; // longmode - 64 bit 15410554Salexandru.dutu@amd.com initDesc.d = 0; // operand size 15510554Salexandru.dutu@amd.com initDesc.g = 1; // granularity 15610554Salexandru.dutu@amd.com initDesc.s = 1; // system segment 15712588Sgabeblack@google.com initDesc.limit = 0xFFFFFFFF; 15812588Sgabeblack@google.com initDesc.base = 0; 15910554Salexandru.dutu@amd.com 16012484Schristian.menard@tu-dresden.de // 64 bit code segment 16110554Salexandru.dutu@amd.com SegDescriptor csDesc = initDesc; 1626220Sgblack@eecs.umich.edu csDesc.type.codeOrData = 1; 16310554Salexandru.dutu@amd.com csDesc.dpl = 0; 16412484Schristian.menard@tu-dresden.de // Because we're dealing with a pointer and I don't think it's 16512484Schristian.menard@tu-dresden.de // guaranteed that there isn't anything in a nonvirtual class between 16612484Schristian.menard@tu-dresden.de // it's beginning in memory and it's actual data, we'll use an 16712484Schristian.menard@tu-dresden.de // intermediary. 1685299Sgblack@eecs.umich.edu uint64_t csDescVal = csDesc; 16914010Sgabeblack@google.com physProxy.writeBlob(GDTBase + numGDTEntries * 8, (&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 17613613Sgabeblack@google.com tc->setMiscReg(MISCREG_CS, (RegVal)cs); 1776220Sgblack@eecs.umich.edu 17812484Schristian.menard@tu-dresden.de // 32 bit data segment 17910554Salexandru.dutu@amd.com SegDescriptor dsDesc = initDesc; 1806220Sgblack@eecs.umich.edu uint64_t dsDescVal = dsDesc; 18114010Sgabeblack@google.com physProxy.writeBlob(GDTBase + numGDTEntries * 8, (&dsDescVal), 8); 1826220Sgblack@eecs.umich.edu 1836220Sgblack@eecs.umich.edu numGDTEntries++; 1846220Sgblack@eecs.umich.edu 1856712Snate@binkert.org SegSelector ds = 0; 1866220Sgblack@eecs.umich.edu ds.si = numGDTEntries - 1; 1876220Sgblack@eecs.umich.edu 18813613Sgabeblack@google.com tc->setMiscReg(MISCREG_DS, (RegVal)ds); 18913613Sgabeblack@google.com tc->setMiscReg(MISCREG_ES, (RegVal)ds); 19013613Sgabeblack@google.com tc->setMiscReg(MISCREG_FS, (RegVal)ds); 19113613Sgabeblack@google.com tc->setMiscReg(MISCREG_GS, (RegVal)ds); 19213613Sgabeblack@google.com tc->setMiscReg(MISCREG_SS, (RegVal)ds); 1936220Sgblack@eecs.umich.edu 1946220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TSL, 0); 1956220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TSG_BASE, GDTBase); 1966220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TSG_LIMIT, 8 * numGDTEntries - 1); 1976220Sgblack@eecs.umich.edu 19810554Salexandru.dutu@amd.com SegDescriptor tssDesc = initDesc; 1996220Sgblack@eecs.umich.edu uint64_t tssDescVal = tssDesc; 20014010Sgabeblack@google.com physProxy.writeBlob(GDTBase + numGDTEntries * 8, (&tssDescVal), 8); 2016220Sgblack@eecs.umich.edu 2026220Sgblack@eecs.umich.edu numGDTEntries++; 2036220Sgblack@eecs.umich.edu 2046220Sgblack@eecs.umich.edu SegSelector tss = 0; 2056220Sgblack@eecs.umich.edu tss.si = numGDTEntries - 1; 2066220Sgblack@eecs.umich.edu 20713613Sgabeblack@google.com tc->setMiscReg(MISCREG_TR, (RegVal)tss); 2086220Sgblack@eecs.umich.edu installSegDesc(tc, SYS_SEGMENT_REG_TR, tssDesc, true); 2095299Sgblack@eecs.umich.edu 2105299Sgblack@eecs.umich.edu /* 2115299Sgblack@eecs.umich.edu * Identity map the first 4GB of memory. In order to map this region 2125299Sgblack@eecs.umich.edu * of memory in long mode, there needs to be one actual page map level 2135299Sgblack@eecs.umich.edu * 4 entry which points to one page directory pointer table which 2145299Sgblack@eecs.umich.edu * points to 4 different page directory tables which are full of two 2155299Sgblack@eecs.umich.edu * megabyte pages. All of the other entries in valid tables are set 2165299Sgblack@eecs.umich.edu * to indicate that they don't pertain to anything valid and will 2175299Sgblack@eecs.umich.edu * cause a fault if used. 2185299Sgblack@eecs.umich.edu */ 2195299Sgblack@eecs.umich.edu 2205299Sgblack@eecs.umich.edu // Put valid values in all of the various table entries which indicate 2215299Sgblack@eecs.umich.edu // that those entries don't point to further tables or pages. Then 2225299Sgblack@eecs.umich.edu // set the values of those entries which are needed. 2235299Sgblack@eecs.umich.edu 2245299Sgblack@eecs.umich.edu // Page Map Level 4 2255299Sgblack@eecs.umich.edu 2265299Sgblack@eecs.umich.edu // read/write, user, not present 2275299Sgblack@eecs.umich.edu uint64_t pml4e = X86ISA::htog(0x6); 2285299Sgblack@eecs.umich.edu for (int offset = 0; offset < (1 << PML4Bits) * 8; offset += 8) { 22914010Sgabeblack@google.com physProxy.writeBlob(PageMapLevel4 + offset, (&pml4e), 8); 2305299Sgblack@eecs.umich.edu } 2315299Sgblack@eecs.umich.edu // Point to the only PDPT 2325299Sgblack@eecs.umich.edu pml4e = X86ISA::htog(0x7 | PageDirPtrTable); 23314010Sgabeblack@google.com physProxy.writeBlob(PageMapLevel4, (&pml4e), 8); 2345299Sgblack@eecs.umich.edu 2355299Sgblack@eecs.umich.edu // Page Directory Pointer Table 2365299Sgblack@eecs.umich.edu 2375299Sgblack@eecs.umich.edu // read/write, user, not present 2385299Sgblack@eecs.umich.edu uint64_t pdpe = X86ISA::htog(0x6); 23914010Sgabeblack@google.com for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) 24014010Sgabeblack@google.com physProxy.writeBlob(PageDirPtrTable + offset, &pdpe, 8); 2415299Sgblack@eecs.umich.edu // Point to the PDTs 2425299Sgblack@eecs.umich.edu for (int table = 0; table < NumPDTs; table++) { 2435299Sgblack@eecs.umich.edu pdpe = X86ISA::htog(0x7 | PageDirTable[table]); 24414010Sgabeblack@google.com physProxy.writeBlob(PageDirPtrTable + table * 8, &pdpe, 8); 2455299Sgblack@eecs.umich.edu } 2465299Sgblack@eecs.umich.edu 2475299Sgblack@eecs.umich.edu // Page Directory Tables 2485299Sgblack@eecs.umich.edu 2495299Sgblack@eecs.umich.edu Addr base = 0; 2505299Sgblack@eecs.umich.edu const Addr pageSize = 2 << 20; 2515299Sgblack@eecs.umich.edu for (int table = 0; table < NumPDTs; table++) { 2525299Sgblack@eecs.umich.edu for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) { 2535299Sgblack@eecs.umich.edu // read/write, user, present, 4MB 2545299Sgblack@eecs.umich.edu uint64_t pdte = X86ISA::htog(0x87 | base); 25514010Sgabeblack@google.com physProxy.writeBlob(PageDirTable[table] + offset, &pdte, 8); 2565299Sgblack@eecs.umich.edu base += pageSize; 2575299Sgblack@eecs.umich.edu } 2585299Sgblack@eecs.umich.edu } 2595299Sgblack@eecs.umich.edu 2605299Sgblack@eecs.umich.edu /* 2615299Sgblack@eecs.umich.edu * Transition from real mode all the way up to Long mode 2625299Sgblack@eecs.umich.edu */ 2636220Sgblack@eecs.umich.edu CR0 cr0 = tc->readMiscRegNoEffect(MISCREG_CR0); 26412484Schristian.menard@tu-dresden.de // Turn off paging. 2655299Sgblack@eecs.umich.edu cr0.pg = 0; 2666220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 26712484Schristian.menard@tu-dresden.de // Turn on protected mode. 2685299Sgblack@eecs.umich.edu cr0.pe = 1; 2696220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 2705299Sgblack@eecs.umich.edu 2716220Sgblack@eecs.umich.edu CR4 cr4 = tc->readMiscRegNoEffect(MISCREG_CR4); 27212484Schristian.menard@tu-dresden.de // Turn on pae. 2735299Sgblack@eecs.umich.edu cr4.pae = 1; 2746220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR4, cr4); 2755299Sgblack@eecs.umich.edu 27612484Schristian.menard@tu-dresden.de // Point to the page tables. 2776220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR3, PageMapLevel4); 2785299Sgblack@eecs.umich.edu 2796220Sgblack@eecs.umich.edu Efer efer = tc->readMiscRegNoEffect(MISCREG_EFER); 28012484Schristian.menard@tu-dresden.de // Enable long mode. 2815299Sgblack@eecs.umich.edu efer.lme = 1; 2826220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_EFER, efer); 2836220Sgblack@eecs.umich.edu 28412484Schristian.menard@tu-dresden.de // Start using longmode segments. 2856220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_CS, csDesc, true); 2866220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_DS, dsDesc, true); 2876220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_ES, dsDesc, true); 2886220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_FS, dsDesc, true); 2896220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_GS, dsDesc, true); 2906220Sgblack@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_SS, dsDesc, true); 2915299Sgblack@eecs.umich.edu 29212484Schristian.menard@tu-dresden.de // Activate long mode. 2935299Sgblack@eecs.umich.edu cr0.pg = 1; 2946220Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 2955299Sgblack@eecs.umich.edu 2967720Sgblack@eecs.umich.edu tc->pcState(tc->getSystemPtr()->kernelEntry); 2975299Sgblack@eecs.umich.edu 2985299Sgblack@eecs.umich.edu // We should now be in long mode. Yay! 2995334Sgblack@eecs.umich.edu 3005615Sgblack@eecs.umich.edu Addr ebdaPos = 0xF0000; 3015625Sgblack@eecs.umich.edu Addr fixed, table; 3025615Sgblack@eecs.umich.edu 30312484Schristian.menard@tu-dresden.de // Write out the SMBios/DMI table. 3045625Sgblack@eecs.umich.edu writeOutSMBiosTable(ebdaPos, fixed, table); 3055625Sgblack@eecs.umich.edu ebdaPos += (fixed + table); 3065625Sgblack@eecs.umich.edu ebdaPos = roundUp(ebdaPos, 16); 3075625Sgblack@eecs.umich.edu 30812484Schristian.menard@tu-dresden.de // Write out the Intel MP Specification configuration table. 3095625Sgblack@eecs.umich.edu writeOutMPTable(ebdaPos, fixed, table); 3105625Sgblack@eecs.umich.edu ebdaPos += (fixed + table); 3115299Sgblack@eecs.umich.edu} 3125299Sgblack@eecs.umich.edu 3135334Sgblack@eecs.umich.eduvoid 3145615Sgblack@eecs.umich.eduX86System::writeOutSMBiosTable(Addr header, 3155615Sgblack@eecs.umich.edu Addr &headerSize, Addr &structSize, Addr table) 3165334Sgblack@eecs.umich.edu{ 3175334Sgblack@eecs.umich.edu // If the table location isn't specified, just put it after the header. 31812484Schristian.menard@tu-dresden.de // The header size as of the 2.5 SMBios specification is 0x1F bytes. 3195615Sgblack@eecs.umich.edu if (!table) 3205615Sgblack@eecs.umich.edu table = header + 0x1F; 3215615Sgblack@eecs.umich.edu smbiosTable->setTableAddr(table); 3225334Sgblack@eecs.umich.edu 3238706Sandreas.hansson@arm.com smbiosTable->writeOut(physProxy, header, headerSize, structSize); 3245615Sgblack@eecs.umich.edu 3255615Sgblack@eecs.umich.edu // Do some bounds checking to make sure we at least didn't step on 3265615Sgblack@eecs.umich.edu // ourselves. 3275615Sgblack@eecs.umich.edu assert(header > table || header + headerSize <= table); 3285615Sgblack@eecs.umich.edu assert(table > header || table + structSize <= header); 3295334Sgblack@eecs.umich.edu} 3305334Sgblack@eecs.umich.edu 3315625Sgblack@eecs.umich.eduvoid 3325625Sgblack@eecs.umich.eduX86System::writeOutMPTable(Addr fp, 3335625Sgblack@eecs.umich.edu Addr &fpSize, Addr &tableSize, Addr table) 3345625Sgblack@eecs.umich.edu{ 3355625Sgblack@eecs.umich.edu // If the table location isn't specified and it exists, just put 3365625Sgblack@eecs.umich.edu // it after the floating pointer. The fp size as of the 1.4 Intel MP 3375625Sgblack@eecs.umich.edu // specification is 0x10 bytes. 3385625Sgblack@eecs.umich.edu if (mpConfigTable) { 3395625Sgblack@eecs.umich.edu if (!table) 3405625Sgblack@eecs.umich.edu table = fp + 0x10; 3415625Sgblack@eecs.umich.edu mpFloatingPointer->setTableAddr(table); 3425625Sgblack@eecs.umich.edu } 3435625Sgblack@eecs.umich.edu 3448706Sandreas.hansson@arm.com fpSize = mpFloatingPointer->writeOut(physProxy, fp); 3455625Sgblack@eecs.umich.edu if (mpConfigTable) 3468706Sandreas.hansson@arm.com tableSize = mpConfigTable->writeOut(physProxy, table); 3475625Sgblack@eecs.umich.edu else 3485625Sgblack@eecs.umich.edu tableSize = 0; 3495625Sgblack@eecs.umich.edu 3505625Sgblack@eecs.umich.edu // Do some bounds checking to make sure we at least didn't step on 3515625Sgblack@eecs.umich.edu // ourselves and the fp structure was the size we thought it was. 3525625Sgblack@eecs.umich.edu assert(fp > table || fp + fpSize <= table); 3535625Sgblack@eecs.umich.edu assert(table > fp || table + tableSize <= fp); 3545625Sgblack@eecs.umich.edu assert(fpSize == 0x10); 3555625Sgblack@eecs.umich.edu} 3565625Sgblack@eecs.umich.edu 3575334Sgblack@eecs.umich.edu 3585132Sgblack@eecs.umich.eduX86System::~X86System() 3595132Sgblack@eecs.umich.edu{ 3605334Sgblack@eecs.umich.edu delete smbiosTable; 3615132Sgblack@eecs.umich.edu} 3625132Sgblack@eecs.umich.edu 3635132Sgblack@eecs.umich.eduX86System * 3645132Sgblack@eecs.umich.eduX86SystemParams::create() 3655132Sgblack@eecs.umich.edu{ 3665132Sgblack@eecs.umich.edu return new X86System(this); 3675132Sgblack@eecs.umich.edu} 368