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