system.cc revision 12588:c007da6c777a
15347Ssaidi@eecs.umich.edu/* 23395Shsul@eecs.umich.edu * Copyright (c) 2007 The Hewlett-Packard Development Company 33395Shsul@eecs.umich.edu * Copyright (c) 2018 TU Dresden 43395Shsul@eecs.umich.edu * All rights reserved. 53395Shsul@eecs.umich.edu * 63395Shsul@eecs.umich.edu * The license below extends only to copyright in the software and shall 73395Shsul@eecs.umich.edu * not be construed as granting a license to any other intellectual 83395Shsul@eecs.umich.edu * property including but not limited to intellectual property relating 93395Shsul@eecs.umich.edu * to a hardware implementation of the functionality of the software 103395Shsul@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 113395Shsul@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 123395Shsul@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 133395Shsul@eecs.umich.edu * modified or unmodified, in source code or in binary form. 143395Shsul@eecs.umich.edu * 153395Shsul@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 163395Shsul@eecs.umich.edu * modification, are permitted provided that the following conditions are 173395Shsul@eecs.umich.edu * met: redistributions of source code must retain the above copyright 183395Shsul@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 193395Shsul@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 203395Shsul@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 213395Shsul@eecs.umich.edu * documentation and/or other materials provided with the distribution; 223395Shsul@eecs.umich.edu * neither the name of the copyright holders nor the names of its 233395Shsul@eecs.umich.edu * contributors may be used to endorse or promote products derived from 243395Shsul@eecs.umich.edu * this software without specific prior written permission. 253395Shsul@eecs.umich.edu * 263395Shsul@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 273395Shsul@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 283395Shsul@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 293395Shsul@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 303509Shsul@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 313395Shsul@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 323395Shsul@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 333395Shsul@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 343448Shsul@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 353395Shsul@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 363481Shsul@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 373481Shsul@eecs.umich.edu * 383481Shsul@eecs.umich.edu * Authors: Gabe Black 393481Shsul@eecs.umich.edu * Maximilian Stein 405347Ssaidi@eecs.umich.edu */ 413481Shsul@eecs.umich.edu 423681Sktlim@umich.edu#include "arch/x86/system.hh" 433681Sktlim@umich.edu 443681Sktlim@umich.edu#include "arch/x86/bios/intelmp.hh" 455347Ssaidi@eecs.umich.edu#include "arch/x86/bios/smbios.hh" 463481Shsul@eecs.umich.edu#include "arch/x86/isa_traits.hh" 475347Ssaidi@eecs.umich.edu#include "base/loader/object_file.hh" 483481Shsul@eecs.umich.edu#include "cpu/thread_context.hh" 493481Shsul@eecs.umich.edu#include "params/X86System.hh" 503481Shsul@eecs.umich.edu 513481Shsul@eecs.umich.eduusing namespace LittleEndianGuest; 523481Shsul@eecs.umich.eduusing namespace X86ISA; 533481Shsul@eecs.umich.edu 545369Ssaidi@eecs.umich.eduX86System::X86System(Params *p) : 553481Shsul@eecs.umich.edu System(p), smbiosTable(p->smbios_table), 565347Ssaidi@eecs.umich.edu mpFloatingPointer(p->intel_mp_pointer), 573481Shsul@eecs.umich.edu mpConfigTable(p->intel_mp_table), 583481Shsul@eecs.umich.edu rsdp(p->acpi_description_table_pointer) 593481Shsul@eecs.umich.edu{ 603481Shsul@eecs.umich.edu} 613481Shsul@eecs.umich.edu 623481Shsul@eecs.umich.eduvoid 633481Shsul@eecs.umich.eduX86ISA::installSegDesc(ThreadContext *tc, SegmentRegIndex seg, 643395Shsul@eecs.umich.edu SegDescriptor desc, bool longmode) 653395Shsul@eecs.umich.edu{ 663395Shsul@eecs.umich.edu bool honorBase = !longmode || seg == SEGMENT_REG_FS || 674167Sbinkertn@umich.edu seg == SEGMENT_REG_GS || 683395Shsul@eecs.umich.edu seg == SEGMENT_REG_TSL || 693395Shsul@eecs.umich.edu seg == SYS_SEGMENT_REG_TR; 703395Shsul@eecs.umich.edu 713511Shsul@eecs.umich.edu SegAttr attr = 0; 723395Shsul@eecs.umich.edu 733395Shsul@eecs.umich.edu attr.dpl = desc.dpl; 743395Shsul@eecs.umich.edu attr.unusable = 0; 755211Ssaidi@eecs.umich.edu attr.defaultSize = desc.d; 765211Ssaidi@eecs.umich.edu attr.longMode = desc.l; 773395Shsul@eecs.umich.edu attr.avl = desc.avl; 783395Shsul@eecs.umich.edu attr.granularity = desc.g; 793395Shsul@eecs.umich.edu attr.present = desc.p; 805370Ssaidi@eecs.umich.edu attr.system = desc.s; 815370Ssaidi@eecs.umich.edu attr.type = desc.type; 825370Ssaidi@eecs.umich.edu if (desc.s) { 835370Ssaidi@eecs.umich.edu if (desc.type.codeOrData) { 845370Ssaidi@eecs.umich.edu // Code segment 855370Ssaidi@eecs.umich.edu attr.expandDown = 0; 863395Shsul@eecs.umich.edu attr.readable = desc.type.r; 873395Shsul@eecs.umich.edu attr.writable = 0; 883481Shsul@eecs.umich.edu } else { 893481Shsul@eecs.umich.edu // Data segment 903481Shsul@eecs.umich.edu attr.expandDown = desc.type.e; 913481Shsul@eecs.umich.edu attr.readable = 1; 923481Shsul@eecs.umich.edu attr.writable = desc.type.w; 933481Shsul@eecs.umich.edu } 943481Shsul@eecs.umich.edu } else { 955361Srstrong@cs.ucsd.edu attr.readable = 1; 965369Ssaidi@eecs.umich.edu attr.writable = 1; 973481Shsul@eecs.umich.edu attr.expandDown = 0; 983481Shsul@eecs.umich.edu } 993481Shsul@eecs.umich.edu 1003481Shsul@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_BASE(seg), desc.base); 1015369Ssaidi@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_EFF_BASE(seg), honorBase ? desc.base : 0); 1025369Ssaidi@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_LIMIT(seg), desc.limit); 1035369Ssaidi@eecs.umich.edu tc->setMiscReg(MISCREG_SEG_ATTR(seg), (MiscReg)attr); 1043481Shsul@eecs.umich.edu} 1055311Ssaidi@eecs.umich.edu 1063481Shsul@eecs.umich.eduvoid 1073395Shsul@eecs.umich.eduX86System::initState() 1083395Shsul@eecs.umich.edu{ 1093395Shsul@eecs.umich.edu System::initState(); 1103395Shsul@eecs.umich.edu 1113478Shsul@eecs.umich.edu if (!kernel) 1123395Shsul@eecs.umich.edu fatal("No kernel to load.\n"); 1133478Shsul@eecs.umich.edu 1143395Shsul@eecs.umich.edu if (kernel->getArch() == ObjectFile::I386) 1153395Shsul@eecs.umich.edu fatal("Loading a 32 bit x86 kernel is not supported.\n"); 1163478Shsul@eecs.umich.edu 1173395Shsul@eecs.umich.edu ThreadContext *tc = threadContexts[0]; 1183395Shsul@eecs.umich.edu // This is the boot strap processor (BSP). Initialize it to look like 1193478Shsul@eecs.umich.edu // the boot loader has just turned control over to the 64 bit OS. We 1203395Shsul@eecs.umich.edu // won't actually set up real mode or legacy protected mode descriptor 1213478Shsul@eecs.umich.edu // tables because we aren't executing any code that would require 1223480Shsul@eecs.umich.edu // them. We do, however toggle the control bits in the correct order 1235361Srstrong@cs.ucsd.edu // while allowing consistency checks and the underlying mechansims 1245369Ssaidi@eecs.umich.edu // just to be safe. 1255361Srstrong@cs.ucsd.edu 1265361Srstrong@cs.ucsd.edu const int NumPDTs = 4; 1275361Srstrong@cs.ucsd.edu 1285369Ssaidi@eecs.umich.edu const Addr PageMapLevel4 = 0x70000; 1295361Srstrong@cs.ucsd.edu const Addr PageDirPtrTable = 0x71000; 1305361Srstrong@cs.ucsd.edu const Addr PageDirTable[NumPDTs] = 1315361Srstrong@cs.ucsd.edu {0x72000, 0x73000, 0x74000, 0x75000}; 1325361Srstrong@cs.ucsd.edu const Addr GDTBase = 0x76000; 1335361Srstrong@cs.ucsd.edu 1345361Srstrong@cs.ucsd.edu const int PML4Bits = 9; 1355361Srstrong@cs.ucsd.edu const int PDPTBits = 9; 1365361Srstrong@cs.ucsd.edu const int PDTBits = 9; 1375361Srstrong@cs.ucsd.edu 1385361Srstrong@cs.ucsd.edu /* 1395361Srstrong@cs.ucsd.edu * Set up the gdt. 1405361Srstrong@cs.ucsd.edu */ 1415361Srstrong@cs.ucsd.edu uint8_t numGDTEntries = 0; 1425361Srstrong@cs.ucsd.edu // Place holder at selector 0 1435361Srstrong@cs.ucsd.edu uint64_t nullDescriptor = 0; 1445353Svilas.sridharan@gmail.com physProxy.writeBlob(GDTBase + numGDTEntries * 8, 1455353Svilas.sridharan@gmail.com (uint8_t *)(&nullDescriptor), 8); 1465353Svilas.sridharan@gmail.com numGDTEntries++; 1473514Sktlim@umich.edu 1483481Shsul@eecs.umich.edu SegDescriptor initDesc = 0; 1493480Shsul@eecs.umich.edu initDesc.type.codeOrData = 0; // code or data type 1503480Shsul@eecs.umich.edu initDesc.type.c = 0; // conforming 1513480Shsul@eecs.umich.edu initDesc.type.r = 1; // readable 1523395Shsul@eecs.umich.edu initDesc.dpl = 0; // privilege 1533514Sktlim@umich.edu initDesc.p = 1; // present 1543514Sktlim@umich.edu initDesc.l = 1; // longmode - 64 bit 1553395Shsul@eecs.umich.edu initDesc.d = 0; // operand size 1563478Shsul@eecs.umich.edu initDesc.g = 1; // granularity 1573395Shsul@eecs.umich.edu initDesc.s = 1; // system segment 1585361Srstrong@cs.ucsd.edu initDesc.limit = 0xFFFFFFFF; 1595369Ssaidi@eecs.umich.edu initDesc.base = 0; 1605361Srstrong@cs.ucsd.edu 1615361Srstrong@cs.ucsd.edu // 64 bit code segment 1625361Srstrong@cs.ucsd.edu SegDescriptor csDesc = initDesc; 1635361Srstrong@cs.ucsd.edu csDesc.type.codeOrData = 1; 1645361Srstrong@cs.ucsd.edu csDesc.dpl = 0; 1655361Srstrong@cs.ucsd.edu // Because we're dealing with a pointer and I don't think it's 1665361Srstrong@cs.ucsd.edu // guaranteed that there isn't anything in a nonvirtual class between 1675369Ssaidi@eecs.umich.edu // it's beginning in memory and it's actual data, we'll use an 1685361Srstrong@cs.ucsd.edu // intermediary. 1695361Srstrong@cs.ucsd.edu uint64_t csDescVal = csDesc; 1705361Srstrong@cs.ucsd.edu physProxy.writeBlob(GDTBase + numGDTEntries * 8, 1715361Srstrong@cs.ucsd.edu (uint8_t *)(&csDescVal), 8); 1725361Srstrong@cs.ucsd.edu 1735361Srstrong@cs.ucsd.edu numGDTEntries++; 1745361Srstrong@cs.ucsd.edu 1755361Srstrong@cs.ucsd.edu SegSelector cs = 0; 1765361Srstrong@cs.ucsd.edu cs.si = numGDTEntries - 1; 1775361Srstrong@cs.ucsd.edu 1783395Shsul@eecs.umich.edu tc->setMiscReg(MISCREG_CS, (MiscReg)cs); 1793395Shsul@eecs.umich.edu 1805369Ssaidi@eecs.umich.edu // 32 bit data segment 1815361Srstrong@cs.ucsd.edu SegDescriptor dsDesc = initDesc; 1823395Shsul@eecs.umich.edu uint64_t dsDescVal = dsDesc; 1833395Shsul@eecs.umich.edu physProxy.writeBlob(GDTBase + numGDTEntries * 8, 1843395Shsul@eecs.umich.edu (uint8_t *)(&dsDescVal), 8); 1853395Shsul@eecs.umich.edu 1863395Shsul@eecs.umich.edu numGDTEntries++; 1873395Shsul@eecs.umich.edu 1885361Srstrong@cs.ucsd.edu SegSelector ds = 0; 1895361Srstrong@cs.ucsd.edu ds.si = numGDTEntries - 1; 1905361Srstrong@cs.ucsd.edu 1915361Srstrong@cs.ucsd.edu tc->setMiscReg(MISCREG_DS, (MiscReg)ds); 1925361Srstrong@cs.ucsd.edu tc->setMiscReg(MISCREG_ES, (MiscReg)ds); 1935361Srstrong@cs.ucsd.edu tc->setMiscReg(MISCREG_FS, (MiscReg)ds); 1943395Shsul@eecs.umich.edu tc->setMiscReg(MISCREG_GS, (MiscReg)ds); 1955361Srstrong@cs.ucsd.edu tc->setMiscReg(MISCREG_SS, (MiscReg)ds); 1965361Srstrong@cs.ucsd.edu 1975361Srstrong@cs.ucsd.edu tc->setMiscReg(MISCREG_TSL, 0); 1985361Srstrong@cs.ucsd.edu tc->setMiscReg(MISCREG_TSG_BASE, GDTBase); 1995361Srstrong@cs.ucsd.edu tc->setMiscReg(MISCREG_TSG_LIMIT, 8 * numGDTEntries - 1); 2005369Ssaidi@eecs.umich.edu 2015361Srstrong@cs.ucsd.edu SegDescriptor tssDesc = initDesc; 2023395Shsul@eecs.umich.edu uint64_t tssDescVal = tssDesc; 2035361Srstrong@cs.ucsd.edu physProxy.writeBlob(GDTBase + numGDTEntries * 8, 2045369Ssaidi@eecs.umich.edu (uint8_t *)(&tssDescVal), 8); 2053395Shsul@eecs.umich.edu 2065361Srstrong@cs.ucsd.edu numGDTEntries++; 2075361Srstrong@cs.ucsd.edu 2085361Srstrong@cs.ucsd.edu SegSelector tss = 0; 2095361Srstrong@cs.ucsd.edu tss.si = numGDTEntries - 1; 2105361Srstrong@cs.ucsd.edu 2113395Shsul@eecs.umich.edu tc->setMiscReg(MISCREG_TR, (MiscReg)tss); 2125361Srstrong@cs.ucsd.edu installSegDesc(tc, SYS_SEGMENT_REG_TR, tssDesc, true); 2135361Srstrong@cs.ucsd.edu 2145361Srstrong@cs.ucsd.edu /* 2155361Srstrong@cs.ucsd.edu * Identity map the first 4GB of memory. In order to map this region 2165361Srstrong@cs.ucsd.edu * of memory in long mode, there needs to be one actual page map level 2175361Srstrong@cs.ucsd.edu * 4 entry which points to one page directory pointer table which 2185361Srstrong@cs.ucsd.edu * points to 4 different page directory tables which are full of two 2195361Srstrong@cs.ucsd.edu * megabyte pages. All of the other entries in valid tables are set 2205361Srstrong@cs.ucsd.edu * to indicate that they don't pertain to anything valid and will 2215361Srstrong@cs.ucsd.edu * cause a fault if used. 2225361Srstrong@cs.ucsd.edu */ 2233999Ssaidi@eecs.umich.edu 2245361Srstrong@cs.ucsd.edu // Put valid values in all of the various table entries which indicate 2255361Srstrong@cs.ucsd.edu // that those entries don't point to further tables or pages. Then 2265361Srstrong@cs.ucsd.edu // set the values of those entries which are needed. 2275361Srstrong@cs.ucsd.edu 2285361Srstrong@cs.ucsd.edu // Page Map Level 4 2295361Srstrong@cs.ucsd.edu 2305361Srstrong@cs.ucsd.edu // read/write, user, not present 2315361Srstrong@cs.ucsd.edu uint64_t pml4e = X86ISA::htog(0x6); 2325361Srstrong@cs.ucsd.edu for (int offset = 0; offset < (1 << PML4Bits) * 8; offset += 8) { 2335361Srstrong@cs.ucsd.edu physProxy.writeBlob(PageMapLevel4 + offset, (uint8_t *)(&pml4e), 8); 2345361Srstrong@cs.ucsd.edu } 2355361Srstrong@cs.ucsd.edu // Point to the only PDPT 2365361Srstrong@cs.ucsd.edu pml4e = X86ISA::htog(0x7 | PageDirPtrTable); 2373395Shsul@eecs.umich.edu physProxy.writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8); 2383481Shsul@eecs.umich.edu 2395361Srstrong@cs.ucsd.edu // Page Directory Pointer Table 2405361Srstrong@cs.ucsd.edu 2415361Srstrong@cs.ucsd.edu // read/write, user, not present 2425361Srstrong@cs.ucsd.edu uint64_t pdpe = X86ISA::htog(0x6); 2435361Srstrong@cs.ucsd.edu for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) { 2445361Srstrong@cs.ucsd.edu physProxy.writeBlob(PageDirPtrTable + offset, 2455361Srstrong@cs.ucsd.edu (uint8_t *)(&pdpe), 8); 2465361Srstrong@cs.ucsd.edu } 2475361Srstrong@cs.ucsd.edu // Point to the PDTs 2485361Srstrong@cs.ucsd.edu for (int table = 0; table < NumPDTs; table++) { 2495361Srstrong@cs.ucsd.edu pdpe = X86ISA::htog(0x7 | PageDirTable[table]); 2505361Srstrong@cs.ucsd.edu physProxy.writeBlob(PageDirPtrTable + table * 8, 2513395Shsul@eecs.umich.edu (uint8_t *)(&pdpe), 8); 2525361Srstrong@cs.ucsd.edu } 2535361Srstrong@cs.ucsd.edu 2545361Srstrong@cs.ucsd.edu // Page Directory Tables 2555361Srstrong@cs.ucsd.edu 2565361Srstrong@cs.ucsd.edu Addr base = 0; 2573395Shsul@eecs.umich.edu const Addr pageSize = 2 << 20; 2583395Shsul@eecs.umich.edu for (int table = 0; table < NumPDTs; table++) { 2593395Shsul@eecs.umich.edu for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) { 2603395Shsul@eecs.umich.edu // read/write, user, present, 4MB 2613395Shsul@eecs.umich.edu uint64_t pdte = X86ISA::htog(0x87 | base); 2623481Shsul@eecs.umich.edu physProxy.writeBlob(PageDirTable[table] + offset, 2635361Srstrong@cs.ucsd.edu (uint8_t *)(&pdte), 8); 2645361Srstrong@cs.ucsd.edu base += pageSize; 2655361Srstrong@cs.ucsd.edu } 2665361Srstrong@cs.ucsd.edu } 2675361Srstrong@cs.ucsd.edu 2685361Srstrong@cs.ucsd.edu /* 2695361Srstrong@cs.ucsd.edu * Transition from real mode all the way up to Long mode 2705353Svilas.sridharan@gmail.com */ 2715361Srstrong@cs.ucsd.edu CR0 cr0 = tc->readMiscRegNoEffect(MISCREG_CR0); 2725361Srstrong@cs.ucsd.edu // Turn off paging. 2735361Srstrong@cs.ucsd.edu cr0.pg = 0; 2745072Ssaidi@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 2753481Shsul@eecs.umich.edu // Turn on protected mode. 2765072Ssaidi@eecs.umich.edu cr0.pe = 1; 2773395Shsul@eecs.umich.edu tc->setMiscReg(MISCREG_CR0, cr0); 2783395Shsul@eecs.umich.edu 2793395Shsul@eecs.umich.edu CR4 cr4 = tc->readMiscRegNoEffect(MISCREG_CR4); 2803395Shsul@eecs.umich.edu // Turn on pae. 2815361Srstrong@cs.ucsd.edu cr4.pae = 1; 2825361Srstrong@cs.ucsd.edu tc->setMiscReg(MISCREG_CR4, cr4); 2835361Srstrong@cs.ucsd.edu 2845361Srstrong@cs.ucsd.edu // Point to the page tables. 2855369Ssaidi@eecs.umich.edu tc->setMiscReg(MISCREG_CR3, PageMapLevel4); 2865361Srstrong@cs.ucsd.edu 2875369Ssaidi@eecs.umich.edu Efer efer = tc->readMiscRegNoEffect(MISCREG_EFER); 2883395Shsul@eecs.umich.edu // Enable long mode. 2895361Srstrong@cs.ucsd.edu efer.lme = 1; 2905369Ssaidi@eecs.umich.edu tc->setMiscReg(MISCREG_EFER, efer); 2915361Srstrong@cs.ucsd.edu 2923395Shsul@eecs.umich.edu // Start using longmode segments. 2935361Srstrong@cs.ucsd.edu installSegDesc(tc, SEGMENT_REG_CS, csDesc, true); 2945361Srstrong@cs.ucsd.edu installSegDesc(tc, SEGMENT_REG_DS, dsDesc, true); 2955361Srstrong@cs.ucsd.edu installSegDesc(tc, SEGMENT_REG_ES, dsDesc, true); 2963395Shsul@eecs.umich.edu installSegDesc(tc, SEGMENT_REG_FS, dsDesc, true); 2975361Srstrong@cs.ucsd.edu installSegDesc(tc, SEGMENT_REG_GS, dsDesc, true); 2985361Srstrong@cs.ucsd.edu installSegDesc(tc, SEGMENT_REG_SS, dsDesc, true); 2995361Srstrong@cs.ucsd.edu 3003999Ssaidi@eecs.umich.edu // Activate long mode. 3015361Srstrong@cs.ucsd.edu cr0.pg = 1; 3025361Srstrong@cs.ucsd.edu tc->setMiscReg(MISCREG_CR0, cr0); 3035361Srstrong@cs.ucsd.edu 3045361Srstrong@cs.ucsd.edu tc->pcState(tc->getSystemPtr()->kernelEntry); 3055361Srstrong@cs.ucsd.edu 3065361Srstrong@cs.ucsd.edu // We should now be in long mode. Yay! 3073999Ssaidi@eecs.umich.edu 3085361Srstrong@cs.ucsd.edu Addr ebdaPos = 0xF0000; 3095361Srstrong@cs.ucsd.edu Addr fixed, table; 3105361Srstrong@cs.ucsd.edu 3115369Ssaidi@eecs.umich.edu // Write out the SMBios/DMI table. 3125369Ssaidi@eecs.umich.edu writeOutSMBiosTable(ebdaPos, fixed, table); 3135369Ssaidi@eecs.umich.edu ebdaPos += (fixed + table); 3145369Ssaidi@eecs.umich.edu ebdaPos = roundUp(ebdaPos, 16); 3155361Srstrong@cs.ucsd.edu 3165361Srstrong@cs.ucsd.edu // Write out the Intel MP Specification configuration table. 3175361Srstrong@cs.ucsd.edu writeOutMPTable(ebdaPos, fixed, table); 3185361Srstrong@cs.ucsd.edu ebdaPos += (fixed + table); 3195361Srstrong@cs.ucsd.edu} 3205361Srstrong@cs.ucsd.edu 3215361Srstrong@cs.ucsd.eduvoid 3225361Srstrong@cs.ucsd.eduX86System::writeOutSMBiosTable(Addr header, 3235361Srstrong@cs.ucsd.edu Addr &headerSize, Addr &structSize, Addr table) 3245361Srstrong@cs.ucsd.edu{ 3255361Srstrong@cs.ucsd.edu // If the table location isn't specified, just put it after the header. 3265361Srstrong@cs.ucsd.edu // The header size as of the 2.5 SMBios specification is 0x1F bytes. 3275361Srstrong@cs.ucsd.edu if (!table) 3285361Srstrong@cs.ucsd.edu table = header + 0x1F; 3295361Srstrong@cs.ucsd.edu smbiosTable->setTableAddr(table); 3305361Srstrong@cs.ucsd.edu 3315361Srstrong@cs.ucsd.edu smbiosTable->writeOut(physProxy, header, headerSize, structSize); 3325361Srstrong@cs.ucsd.edu 3335361Srstrong@cs.ucsd.edu // Do some bounds checking to make sure we at least didn't step on 3345361Srstrong@cs.ucsd.edu // ourselves. 3355361Srstrong@cs.ucsd.edu assert(header > table || header + headerSize <= table); 3365361Srstrong@cs.ucsd.edu assert(table > header || table + structSize <= header); 3375361Srstrong@cs.ucsd.edu} 3385361Srstrong@cs.ucsd.edu 3395361Srstrong@cs.ucsd.eduvoid 3405361Srstrong@cs.ucsd.eduX86System::writeOutMPTable(Addr fp, 3415361Srstrong@cs.ucsd.edu Addr &fpSize, Addr &tableSize, Addr table) 3425361Srstrong@cs.ucsd.edu{ 3435361Srstrong@cs.ucsd.edu // If the table location isn't specified and it exists, just put 3445361Srstrong@cs.ucsd.edu // it after the floating pointer. The fp size as of the 1.4 Intel MP 3455361Srstrong@cs.ucsd.edu // specification is 0x10 bytes. 3465361Srstrong@cs.ucsd.edu if (mpConfigTable) { 3473395Shsul@eecs.umich.edu if (!table) 3483395Shsul@eecs.umich.edu table = fp + 0x10; 3493395Shsul@eecs.umich.edu mpFloatingPointer->setTableAddr(table); 3503509Shsul@eecs.umich.edu } 3513395Shsul@eecs.umich.edu 3523395Shsul@eecs.umich.edu fpSize = mpFloatingPointer->writeOut(physProxy, fp); 3535361Srstrong@cs.ucsd.edu if (mpConfigTable) 3543395Shsul@eecs.umich.edu tableSize = mpConfigTable->writeOut(physProxy, table); 3553395Shsul@eecs.umich.edu else 3563511Shsul@eecs.umich.edu tableSize = 0; 3573395Shsul@eecs.umich.edu 3583395Shsul@eecs.umich.edu // Do some bounds checking to make sure we at least didn't step on 3593395Shsul@eecs.umich.edu // ourselves and the fp structure was the size we thought it was. 3603395Shsul@eecs.umich.edu assert(fp > table || fp + fpSize <= table); 3613514Sktlim@umich.edu assert(table > fp || table + tableSize <= fp); 3623395Shsul@eecs.umich.edu assert(fpSize == 0x10); 363} 364 365 366X86System::~X86System() 367{ 368 delete smbiosTable; 369} 370 371X86System * 372X86SystemParams::create() 373{ 374 return new X86System(this); 375} 376