system.cc revision 12483:fd8c7ada2fb9
14997Sgblack@eecs.umich.edu/*
25417Sgblack@eecs.umich.edu * Copyright (c) 2007 The Hewlett-Packard Development Company
34997Sgblack@eecs.umich.edu * Copyright (c) 2018 TU Dresden
44997Sgblack@eecs.umich.edu * All rights reserved.
57087Snate@binkert.org *
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,
134997Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
147087Snate@binkert.org *
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;
224997Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
237087Snate@binkert.org * contributors may be used to endorse or promote products derived from
244997Sgblack@eecs.umich.edu * this software without specific prior written permission.
254997Sgblack@eecs.umich.edu *
264997Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
274997Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
284997Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
294997Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
304997Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
314997Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
324997Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
334997Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
344997Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
354997Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
364997Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
374997Sgblack@eecs.umich.edu *
384997Sgblack@eecs.umich.edu * Authors: Gabe Black
394997Sgblack@eecs.umich.edu *          Maximilian Stein
4011793Sbrandon.potter@amd.com */
4111793Sbrandon.potter@amd.com
424997Sgblack@eecs.umich.edu#include "arch/x86/system.hh"
4310474Sandreas.hansson@arm.com
444997Sgblack@eecs.umich.edu#include "arch/x86/bios/intelmp.hh"
459898Sandreas@sandberg.pp.se#include "arch/x86/bios/smbios.hh"
4611793Sbrandon.potter@amd.com#include "arch/x86/isa_traits.hh"
478229Snate@binkert.org#include "base/loader/object_file.hh"
4811793Sbrandon.potter@amd.com#include "cpu/thread_context.hh"
498229Snate@binkert.org#include "params/X86System.hh"
508582Sgblack@eecs.umich.edu
515149Sgblack@eecs.umich.eduusing namespace LittleEndianGuest;
525086Sgblack@eecs.umich.eduusing namespace X86ISA;
535086Sgblack@eecs.umich.edu
548232Snate@binkert.orgX86System::X86System(Params *p) :
558767Sgblack@eecs.umich.edu    System(p), smbiosTable(p->smbios_table),
565086Sgblack@eecs.umich.edu    mpFloatingPointer(p->intel_mp_pointer),
578767Sgblack@eecs.umich.edu    mpConfigTable(p->intel_mp_table),
585895Sgblack@eecs.umich.edu    rsdp(p->acpi_description_table_pointer)
595086Sgblack@eecs.umich.edu{
605086Sgblack@eecs.umich.edu}
615086Sgblack@eecs.umich.edu
6210905Sandreas.sandberg@arm.comvoid
6310905Sandreas.sandberg@arm.comX86ISA::installSegDesc(ThreadContext *tc, SegmentRegIndex seg,
6410905Sandreas.sandberg@arm.com        SegDescriptor desc, bool longmode)
655124Sgblack@eecs.umich.edu{
668953Sgblack@eecs.umich.edu    uint64_t base = desc.baseLow + (desc.baseHigh << 24);
678953Sgblack@eecs.umich.edu    bool honorBase = !longmode || seg == SEGMENT_REG_FS ||
685124Sgblack@eecs.umich.edu                                  seg == SEGMENT_REG_GS ||
698953Sgblack@eecs.umich.edu                                  seg == SEGMENT_REG_TSL ||
708953Sgblack@eecs.umich.edu                                  seg == SYS_SEGMENT_REG_TR;
715124Sgblack@eecs.umich.edu    uint64_t limit = desc.limitLow | (desc.limitHigh << 16);
728953Sgblack@eecs.umich.edu    if (desc.g)
735124Sgblack@eecs.umich.edu        limit = (limit << 12) | mask(12);
745245Sgblack@eecs.umich.edu
755245Sgblack@eecs.umich.edu    SegAttr attr = 0;
765236Sgblack@eecs.umich.edu
775236Sgblack@eecs.umich.edu    attr.dpl = desc.dpl;
788953Sgblack@eecs.umich.edu    attr.unusable = 0;
798953Sgblack@eecs.umich.edu    attr.defaultSize = desc.d;
808953Sgblack@eecs.umich.edu    attr.longMode = desc.l;
818953Sgblack@eecs.umich.edu    attr.avl = desc.avl;
828953Sgblack@eecs.umich.edu    attr.granularity = desc.g;
838953Sgblack@eecs.umich.edu    attr.present = desc.p;
848953Sgblack@eecs.umich.edu    attr.system = desc.s;
858953Sgblack@eecs.umich.edu    attr.type = desc.type;
868953Sgblack@eecs.umich.edu    if (desc.s) {
878953Sgblack@eecs.umich.edu        if (desc.type.codeOrData) {
888953Sgblack@eecs.umich.edu            // Code segment
898953Sgblack@eecs.umich.edu            attr.expandDown = 0;
908953Sgblack@eecs.umich.edu            attr.readable = desc.type.r;
918953Sgblack@eecs.umich.edu            attr.writable = 0;
928953Sgblack@eecs.umich.edu        } else {
938953Sgblack@eecs.umich.edu            // Data segment
948953Sgblack@eecs.umich.edu            attr.expandDown = desc.type.e;
958953Sgblack@eecs.umich.edu            attr.readable = 1;
965895Sgblack@eecs.umich.edu            attr.writable = desc.type.w;
9712455Sgabeblack@google.com        }
985124Sgblack@eecs.umich.edu    } else {
998962Sgblack@eecs.umich.edu        attr.readable = 1;
1008962Sgblack@eecs.umich.edu        attr.writable = 1;
1018962Sgblack@eecs.umich.edu        attr.expandDown = 0;
1029064Snilay@cs.wisc.edu    }
1038962Sgblack@eecs.umich.edu
1048962Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_SEG_BASE(seg), base);
1055124Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_SEG_EFF_BASE(seg), honorBase ? base : 0);
1068953Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_SEG_LIMIT(seg), limit);
1078953Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_SEG_ATTR(seg), (MiscReg)attr);
1088962Sgblack@eecs.umich.edu}
1098953Sgblack@eecs.umich.edu
1108953Sgblack@eecs.umich.eduvoid
1118953Sgblack@eecs.umich.eduX86System::initState()
1125124Sgblack@eecs.umich.edu{
1138953Sgblack@eecs.umich.edu    System::initState();
1145124Sgblack@eecs.umich.edu
1158953Sgblack@eecs.umich.edu    if (!kernel)
1168962Sgblack@eecs.umich.edu        fatal("No kernel to load.\n");
1175895Sgblack@eecs.umich.edu
1185124Sgblack@eecs.umich.edu    if (kernel->getArch() == ObjectFile::I386)
1195124Sgblack@eecs.umich.edu        fatal("Loading a 32 bit x86 kernel is not supported.\n");
1205360Sgblack@eecs.umich.edu
1215360Sgblack@eecs.umich.edu    ThreadContext *tc = threadContexts[0];
1225360Sgblack@eecs.umich.edu    // This is the boot strap processor (BSP). Initialize it to look like
1238953Sgblack@eecs.umich.edu    // the boot loader has just turned control over to the 64 bit OS. We
1248953Sgblack@eecs.umich.edu    // won't actually set up real mode or legacy protected mode descriptor
1258953Sgblack@eecs.umich.edu    // tables because we aren't executing any code that would require
1268953Sgblack@eecs.umich.edu    // them. We do, however toggle the control bits in the correct order
1275124Sgblack@eecs.umich.edu    // while allowing consistency checks and the underlying mechansims
1285124Sgblack@eecs.umich.edu    // just to be safe.
1295124Sgblack@eecs.umich.edu
1309423SAndreas.Sandberg@arm.com    const int NumPDTs = 4;
1315124Sgblack@eecs.umich.edu
1325242Sgblack@eecs.umich.edu    const Addr PageMapLevel4 = 0x70000;
1338953Sgblack@eecs.umich.edu    const Addr PageDirPtrTable = 0x71000;
1348953Sgblack@eecs.umich.edu    const Addr PageDirTable[NumPDTs] =
1358953Sgblack@eecs.umich.edu        {0x72000, 0x73000, 0x74000, 0x75000};
1368953Sgblack@eecs.umich.edu    const Addr GDTBase = 0x76000;
1378953Sgblack@eecs.umich.edu
1388953Sgblack@eecs.umich.edu    const int PML4Bits = 9;
1395242Sgblack@eecs.umich.edu    const int PDPTBits = 9;
1405124Sgblack@eecs.umich.edu    const int PDTBits = 9;
1415124Sgblack@eecs.umich.edu
1425124Sgblack@eecs.umich.edu    /*
1435357Sgblack@eecs.umich.edu     * Set up the gdt.
1445357Sgblack@eecs.umich.edu     */
1455357Sgblack@eecs.umich.edu    uint8_t numGDTEntries = 0;
1465357Sgblack@eecs.umich.edu    // Place holder at selector 0
1475357Sgblack@eecs.umich.edu    uint64_t nullDescriptor = 0;
1485357Sgblack@eecs.umich.edu    physProxy.writeBlob(GDTBase + numGDTEntries * 8,
1499423SAndreas.Sandberg@arm.com                        (uint8_t *)(&nullDescriptor), 8);
1505124Sgblack@eecs.umich.edu    numGDTEntries++;
1515242Sgblack@eecs.umich.edu
1528953Sgblack@eecs.umich.edu    SegDescriptor initDesc = 0;
1538953Sgblack@eecs.umich.edu    initDesc.type.codeOrData = 0; // code or data type
1548953Sgblack@eecs.umich.edu    initDesc.type.c = 0;          // conforming
1558953Sgblack@eecs.umich.edu    initDesc.type.r = 1;          // readable
1568953Sgblack@eecs.umich.edu    initDesc.dpl = 0;             // privilege
1575242Sgblack@eecs.umich.edu    initDesc.p = 1;               // present
1585242Sgblack@eecs.umich.edu    initDesc.l = 1;               // longmode - 64 bit
1595124Sgblack@eecs.umich.edu    initDesc.d = 0;               // operand size
1605124Sgblack@eecs.umich.edu    initDesc.g = 1;               // granularity
1615124Sgblack@eecs.umich.edu    initDesc.s = 1;               // system segment
1625358Sgblack@eecs.umich.edu    initDesc.limitHigh = 0xF;
1635086Sgblack@eecs.umich.edu    initDesc.limitLow = 0xFFFF;
1648953Sgblack@eecs.umich.edu    initDesc.baseHigh = 0x0;
1658953Sgblack@eecs.umich.edu    initDesc.baseLow = 0x0;
1668953Sgblack@eecs.umich.edu
1678953Sgblack@eecs.umich.edu    //64 bit code segment
1688953Sgblack@eecs.umich.edu    SegDescriptor csDesc = initDesc;
1695359Sgblack@eecs.umich.edu    csDesc.type.codeOrData = 1;
1705086Sgblack@eecs.umich.edu    csDesc.dpl = 0;
1715086Sgblack@eecs.umich.edu    //Because we're dealing with a pointer and I don't think it's
1725086Sgblack@eecs.umich.edu    //guaranteed that there isn't anything in a nonvirtual class between
17312749Sgiacomo.travaglini@arm.com    //it's beginning in memory and it's actual data, we'll use an
1746141Sgblack@eecs.umich.edu    //intermediary.
1756141Sgblack@eecs.umich.edu    uint64_t csDescVal = csDesc;
1766141Sgblack@eecs.umich.edu    physProxy.writeBlob(GDTBase + numGDTEntries * 8,
1776141Sgblack@eecs.umich.edu                        (uint8_t *)(&csDescVal), 8);
1786141Sgblack@eecs.umich.edu
1796141Sgblack@eecs.umich.edu    numGDTEntries++;
1806141Sgblack@eecs.umich.edu
1818582Sgblack@eecs.umich.edu    SegSelector cs = 0;
1828105Sgblack@eecs.umich.edu    cs.si = numGDTEntries - 1;
1838582Sgblack@eecs.umich.edu
1848582Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_CS, (MiscReg)cs);
1858582Sgblack@eecs.umich.edu
18610474Sandreas.hansson@arm.com    //32 bit data segment
1878582Sgblack@eecs.umich.edu    SegDescriptor dsDesc = initDesc;
18813613Sgabeblack@google.com    uint64_t dsDescVal = dsDesc;
1896141Sgblack@eecs.umich.edu    physProxy.writeBlob(GDTBase + numGDTEntries * 8,
1906141Sgblack@eecs.umich.edu                        (uint8_t *)(&dsDescVal), 8);
19113613Sgabeblack@google.com
1926141Sgblack@eecs.umich.edu    numGDTEntries++;
1936141Sgblack@eecs.umich.edu
1946141Sgblack@eecs.umich.edu    SegSelector ds = 0;
1956141Sgblack@eecs.umich.edu    ds.si = numGDTEntries - 1;
1966141Sgblack@eecs.umich.edu
1976141Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_DS, (MiscReg)ds);
1986141Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_ES, (MiscReg)ds);
1996141Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_FS, (MiscReg)ds);
2006141Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_GS, (MiscReg)ds);
2016141Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_SS, (MiscReg)ds);
2028105Sgblack@eecs.umich.edu
20313613Sgabeblack@google.com    tc->setMiscReg(MISCREG_TSL, 0);
2046141Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TSG_BASE, GDTBase);
20510824SAndreas.Sandberg@ARM.com    tc->setMiscReg(MISCREG_TSG_LIMIT, 8 * numGDTEntries - 1);
2066141Sgblack@eecs.umich.edu
2076141Sgblack@eecs.umich.edu    SegDescriptor tssDesc = initDesc;
2086141Sgblack@eecs.umich.edu    uint64_t tssDescVal = tssDesc;
2096141Sgblack@eecs.umich.edu    physProxy.writeBlob(GDTBase + numGDTEntries * 8,
2106141Sgblack@eecs.umich.edu                        (uint8_t *)(&tssDescVal), 8);
2116141Sgblack@eecs.umich.edu
2128098Sgblack@eecs.umich.edu    numGDTEntries++;
2138098Sgblack@eecs.umich.edu
2146141Sgblack@eecs.umich.edu    SegSelector tss = 0;
2156141Sgblack@eecs.umich.edu    tss.si = numGDTEntries - 1;
21610824SAndreas.Sandberg@ARM.com
2176141Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_TR, (MiscReg)tss);
2186141Sgblack@eecs.umich.edu    installSegDesc(tc, SYS_SEGMENT_REG_TR, tssDesc, true);
2196141Sgblack@eecs.umich.edu
2206141Sgblack@eecs.umich.edu    /*
2216141Sgblack@eecs.umich.edu     * Identity map the first 4GB of memory. In order to map this region
2226141Sgblack@eecs.umich.edu     * of memory in long mode, there needs to be one actual page map level
2236141Sgblack@eecs.umich.edu     * 4 entry which points to one page directory pointer table which
2246141Sgblack@eecs.umich.edu     * points to 4 different page directory tables which are full of two
2256141Sgblack@eecs.umich.edu     * megabyte pages. All of the other entries in valid tables are set
2266141Sgblack@eecs.umich.edu     * to indicate that they don't pertain to anything valid and will
22712749Sgiacomo.travaglini@arm.com     * cause a fault if used.
22812749Sgiacomo.travaglini@arm.com     */
2299738Sandreas@sandberg.pp.se
2309738Sandreas@sandberg.pp.se    // Put valid values in all of the various table entries which indicate
2319738Sandreas@sandberg.pp.se    // that those entries don't point to further tables or pages. Then
23210553Salexandru.dutu@amd.com    // set the values of those entries which are needed.
23310553Salexandru.dutu@amd.com
23410553Salexandru.dutu@amd.com    // Page Map Level 4
23511874Sbrandon.potter@amd.com
23611874Sbrandon.potter@amd.com    // read/write, user, not present
23711874Sbrandon.potter@amd.com    uint64_t pml4e = X86ISA::htog(0x6);
23811874Sbrandon.potter@amd.com    for (int offset = 0; offset < (1 << PML4Bits) * 8; offset += 8) {
23910553Salexandru.dutu@amd.com        physProxy.writeBlob(PageMapLevel4 + offset, (uint8_t *)(&pml4e), 8);
24010553Salexandru.dutu@amd.com    }
2419738Sandreas@sandberg.pp.se    // Point to the only PDPT
2429738Sandreas@sandberg.pp.se    pml4e = X86ISA::htog(0x7 | PageDirPtrTable);
2439738Sandreas@sandberg.pp.se    physProxy.writeBlob(PageMapLevel4, (uint8_t *)(&pml4e), 8);
2449738Sandreas@sandberg.pp.se
2459738Sandreas@sandberg.pp.se    // Page Directory Pointer Table
2469738Sandreas@sandberg.pp.se
2479738Sandreas@sandberg.pp.se    // read/write, user, not present
2489738Sandreas@sandberg.pp.se    uint64_t pdpe = X86ISA::htog(0x6);
2499738Sandreas@sandberg.pp.se    for (int offset = 0; offset < (1 << PDPTBits) * 8; offset += 8) {
2509738Sandreas@sandberg.pp.se        physProxy.writeBlob(PageDirPtrTable + offset,
2519738Sandreas@sandberg.pp.se                            (uint8_t *)(&pdpe), 8);
2529738Sandreas@sandberg.pp.se    }
2539738Sandreas@sandberg.pp.se    // Point to the PDTs
2549738Sandreas@sandberg.pp.se    for (int table = 0; table < NumPDTs; table++) {
2559738Sandreas@sandberg.pp.se        pdpe = X86ISA::htog(0x7 | PageDirTable[table]);
2569738Sandreas@sandberg.pp.se        physProxy.writeBlob(PageDirPtrTable + table * 8,
2579738Sandreas@sandberg.pp.se                            (uint8_t *)(&pdpe), 8);
2589738Sandreas@sandberg.pp.se    }
25910824SAndreas.Sandberg@ARM.com
2609738Sandreas@sandberg.pp.se    // Page Directory Tables
2619738Sandreas@sandberg.pp.se
2629738Sandreas@sandberg.pp.se    Addr base = 0;
2639738Sandreas@sandberg.pp.se    const Addr pageSize = 2 << 20;
2649738Sandreas@sandberg.pp.se    for (int table = 0; table < NumPDTs; table++) {
2659738Sandreas@sandberg.pp.se        for (int offset = 0; offset < (1 << PDTBits) * 8; offset += 8) {
2669738Sandreas@sandberg.pp.se            // read/write, user, present, 4MB
2679738Sandreas@sandberg.pp.se            uint64_t pdte = X86ISA::htog(0x87 | base);
2689738Sandreas@sandberg.pp.se            physProxy.writeBlob(PageDirTable[table] + offset,
26912749Sgiacomo.travaglini@arm.com                                (uint8_t *)(&pdte), 8);
27012749Sgiacomo.travaglini@arm.com            base += pageSize;
2716023Snate@binkert.org        }
2725086Sgblack@eecs.umich.edu    }
27311608Snikos.nikoleris@arm.com
2746141Sgblack@eecs.umich.edu    /*
2756141Sgblack@eecs.umich.edu     * Transition from real mode all the way up to Long mode
2766141Sgblack@eecs.umich.edu     */
2778535Sgblack@eecs.umich.edu    CR0 cr0 = tc->readMiscRegNoEffect(MISCREG_CR0);
2788535Sgblack@eecs.umich.edu    //Turn off paging.
2796141Sgblack@eecs.umich.edu    cr0.pg = 0;
2806141Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_CR0, cr0);
2816141Sgblack@eecs.umich.edu    //Turn on protected mode.
2826141Sgblack@eecs.umich.edu    cr0.pe = 1;
2836141Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_CR0, cr0);
2846141Sgblack@eecs.umich.edu
2855124Sgblack@eecs.umich.edu    CR4 cr4 = tc->readMiscRegNoEffect(MISCREG_CR4);
2865140Sgblack@eecs.umich.edu    //Turn on pae.
2875140Sgblack@eecs.umich.edu    cr4.pae = 1;
2886141Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_CR4, cr4);
2895140Sgblack@eecs.umich.edu
2905140Sgblack@eecs.umich.edu    //Point to the page tables.
2916141Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_CR3, PageMapLevel4);
2925237Sgblack@eecs.umich.edu
2935140Sgblack@eecs.umich.edu    Efer efer = tc->readMiscRegNoEffect(MISCREG_EFER);
2946141Sgblack@eecs.umich.edu    //Enable long mode.
2955237Sgblack@eecs.umich.edu    efer.lme = 1;
2965431Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_EFER, efer);
2976059Sgblack@eecs.umich.edu
2986141Sgblack@eecs.umich.edu    //Start using longmode segments.
2996059Sgblack@eecs.umich.edu    installSegDesc(tc, SEGMENT_REG_CS, csDesc, true);
30010474Sandreas.hansson@arm.com    installSegDesc(tc, SEGMENT_REG_DS, dsDesc, true);
3015433Sgblack@eecs.umich.edu    installSegDesc(tc, SEGMENT_REG_ES, dsDesc, true);
3025965Sgblack@eecs.umich.edu    installSegDesc(tc, SEGMENT_REG_FS, dsDesc, true);
3035433Sgblack@eecs.umich.edu    installSegDesc(tc, SEGMENT_REG_GS, dsDesc, true);
3046099Sgblack@eecs.umich.edu    installSegDesc(tc, SEGMENT_REG_SS, dsDesc, true);
30510474Sandreas.hansson@arm.com
3066023Snate@binkert.org    //Activate long mode.
30710474Sandreas.hansson@arm.com    cr0.pg = 1;
3085433Sgblack@eecs.umich.edu    tc->setMiscReg(MISCREG_CR0, cr0);
3095965Sgblack@eecs.umich.edu
3105433Sgblack@eecs.umich.edu    tc->pcState(tc->getSystemPtr()->kernelEntry);
3115140Sgblack@eecs.umich.edu
3125140Sgblack@eecs.umich.edu    // We should now be in long mode. Yay!
3135965Sgblack@eecs.umich.edu
3149062Sjayneel@cs.wisc.edu    Addr ebdaPos = 0xF0000;
3159062Sjayneel@cs.wisc.edu    Addr fixed, table;
3169028Sgblack@eecs.umich.edu
3179028Sgblack@eecs.umich.edu    //Write out the SMBios/DMI table
3185965Sgblack@eecs.umich.edu    writeOutSMBiosTable(ebdaPos, fixed, table);
3195433Sgblack@eecs.umich.edu    ebdaPos += (fixed + table);
3205237Sgblack@eecs.umich.edu    ebdaPos = roundUp(ebdaPos, 16);
3215965Sgblack@eecs.umich.edu
3225965Sgblack@eecs.umich.edu    //Write out the Intel MP Specification configuration table
32310474Sandreas.hansson@arm.com    writeOutMPTable(ebdaPos, fixed, table);
3245140Sgblack@eecs.umich.edu    ebdaPos += (fixed + table);
3255965Sgblack@eecs.umich.edu}
32610474Sandreas.hansson@arm.com
3275140Sgblack@eecs.umich.eduvoid
3285140Sgblack@eecs.umich.eduX86System::writeOutSMBiosTable(Addr header,
3299025Sgblack@eecs.umich.edu        Addr &headerSize, Addr &structSize, Addr table)
3308925Sgblack@eecs.umich.edu{
3318925Sgblack@eecs.umich.edu    // If the table location isn't specified, just put it after the header.
3325140Sgblack@eecs.umich.edu    // The header size as of the 2.5 SMBios specification is 0x1F bytes
3336141Sgblack@eecs.umich.edu    if (!table)
3345237Sgblack@eecs.umich.edu        table = header + 0x1F;
3355140Sgblack@eecs.umich.edu    smbiosTable->setTableAddr(table);
3365140Sgblack@eecs.umich.edu
33712140Sswapnilster@gmail.com    smbiosTable->writeOut(physProxy, header, headerSize, structSize);
33812140Sswapnilster@gmail.com
33912140Sswapnilster@gmail.com    // Do some bounds checking to make sure we at least didn't step on
34012140Sswapnilster@gmail.com    // ourselves.
34112140Sswapnilster@gmail.com    assert(header > table || header + headerSize <= table);
3425140Sgblack@eecs.umich.edu    assert(table > header || table + structSize <= header);
34312140Sswapnilster@gmail.com}
34412140Sswapnilster@gmail.com
34512140Sswapnilster@gmail.comvoid
34612140Sswapnilster@gmail.comX86System::writeOutMPTable(Addr fp,
34712140Sswapnilster@gmail.com        Addr &fpSize, Addr &tableSize, Addr table)
34812140Sswapnilster@gmail.com{
34912140Sswapnilster@gmail.com    // If the table location isn't specified and it exists, just put
35012140Sswapnilster@gmail.com    // it after the floating pointer. The fp size as of the 1.4 Intel MP
3518752Sgblack@eecs.umich.edu    // specification is 0x10 bytes.
3528752Sgblack@eecs.umich.edu    if (mpConfigTable) {
3538752Sgblack@eecs.umich.edu        if (!table)
3548752Sgblack@eecs.umich.edu            table = fp + 0x10;
3558752Sgblack@eecs.umich.edu        mpFloatingPointer->setTableAddr(table);
3568752Sgblack@eecs.umich.edu    }
3578752Sgblack@eecs.umich.edu
3588752Sgblack@eecs.umich.edu    fpSize = mpFloatingPointer->writeOut(physProxy, fp);
3598752Sgblack@eecs.umich.edu    if (mpConfigTable)
3608752Sgblack@eecs.umich.edu        tableSize = mpConfigTable->writeOut(physProxy, table);
3618752Sgblack@eecs.umich.edu    else
36212461Sgabeblack@google.com        tableSize = 0;
36312461Sgabeblack@google.com
36412461Sgabeblack@google.com    // Do some bounds checking to make sure we at least didn't step on
3658752Sgblack@eecs.umich.edu    // ourselves and the fp structure was the size we thought it was.
3668752Sgblack@eecs.umich.edu    assert(fp > table || fp + fpSize <= table);
3678752Sgblack@eecs.umich.edu    assert(table > fp || table + tableSize <= fp);
36812461Sgabeblack@google.com    assert(fpSize == 0x10);
3698752Sgblack@eecs.umich.edu}
3708752Sgblack@eecs.umich.edu
37112461Sgabeblack@google.com
37210474Sandreas.hansson@arm.comX86System::~X86System()
37310474Sandreas.hansson@arm.com{
3748752Sgblack@eecs.umich.edu    delete smbiosTable;
3758752Sgblack@eecs.umich.edu}
3768752Sgblack@eecs.umich.edu
37712461Sgabeblack@google.comX86System *
37812461Sgabeblack@google.comX86SystemParams::create()
37912461Sgabeblack@google.com{
38012461Sgabeblack@google.com    return new X86System(this);
38112461Sgabeblack@google.com}
3828752Sgblack@eecs.umich.edu