blob: bbad0f8a757e2e96a58ab02d9be7baf304fa121f [file] [log] [blame]
/*
* Copyright (c) 2008 The Hewlett-Packard Development Company
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ARCH_X86_BIOS_ACPI_HH__
#define __ARCH_X86_BIOS_ACPI_HH__
#include <string>
#include <tuple>
#include <type_traits>
#include <vector>
#include "base/compiler.hh"
#include "base/types.hh"
#include "debug/ACPI.hh"
#include "params/X86ACPIMadt.hh"
#include "params/X86ACPIMadtIOAPIC.hh"
#include "params/X86ACPIMadtIntSourceOverride.hh"
#include "params/X86ACPIMadtLAPIC.hh"
#include "params/X86ACPIMadtLAPICOverride.hh"
#include "params/X86ACPIMadtNMI.hh"
#include "params/X86ACPIMadtRecord.hh"
#include "params/X86ACPIRSDP.hh"
#include "params/X86ACPIRSDT.hh"
#include "params/X86ACPISysDescTable.hh"
#include "params/X86ACPIXSDT.hh"
#include "sim/sim_object.hh"
namespace gem5
{
class PortProxy;
namespace X86ISA
{
namespace ACPI
{
class RSDT;
class XSDT;
struct Allocator
{
virtual Addr alloc(std::size_t size, unsigned align=1) = 0;
};
struct LinearAllocator : public Allocator
{
LinearAllocator(Addr begin, Addr end=0) :
next(begin),
end(end)
{}
Addr alloc(std::size_t size, unsigned align) override;
protected:
Addr next;
Addr const end;
};
class RSDP : public SimObject
{
protected:
PARAMS(X86ACPIRSDP);
static const char signature[];
struct GEM5_PACKED MemR0
{
// src: https://wiki.osdev.org/RSDP
char signature[8] = {};
uint8_t checksum = 0;
char oemID[6] = {};
uint8_t revision = 0;
uint32_t rsdtAddress = 0;
};
static_assert(std::is_trivially_copyable_v<MemR0>,
"Type not suitable for memcpy.");
struct GEM5_PACKED Mem : public MemR0
{
// since version 2
uint32_t length = 0;
uint64_t xsdtAddress = 0;
uint8_t extendedChecksum = 0;
uint8_t _reserved[3] = {};
};
static_assert(std::is_trivially_copyable_v<Mem>,
"Type not suitable for memcpy,");
RSDT* rsdt;
XSDT* xsdt;
public:
RSDP(const Params &p);
Addr write(PortProxy& phys_proxy, Allocator& alloc) const;
};
class SysDescTable : public SimObject
{
protected:
PARAMS(X86ACPISysDescTable);
struct GEM5_PACKED Mem
{
// src: https://wiki.osdev.org/RSDT
char signature[4] = {};
uint32_t length = 0;
uint8_t revision = 0;
uint8_t checksum = 0;
char oemID[6] = {};
char oemTableID[8] = {};
uint32_t oemRevision = 0;
uint32_t creatorID = 0;
uint32_t creatorRevision = 0;
};
static_assert(std::is_trivially_copyable_v<Mem>,
"Type not suitable for memcpy.");
virtual Addr writeBuf(PortProxy& phys_proxy, Allocator& alloc,
std::vector<uint8_t>& mem) const = 0;
const char* signature;
uint8_t revision;
SysDescTable(const Params& p, const char* _signature, uint8_t _revision) :
SimObject(p), signature(_signature), revision(_revision)
{}
public:
Addr
write(PortProxy& phys_proxy, Allocator& alloc) const
{
std::vector<uint8_t> mem;
return writeBuf(phys_proxy, alloc, mem);
}
};
template<class T>
class RXSDT : public SysDescTable
{
protected:
using Ptr = T;
std::vector<SysDescTable *> entries;
Addr writeBuf(PortProxy& phys_proxy, Allocator& alloc,
std::vector<uint8_t>& mem) const override;
protected:
RXSDT(const Params& p, const char* _signature, uint8_t _revision);
};
class RSDT : public RXSDT<uint32_t>
{
protected:
PARAMS(X86ACPIRSDT);
public:
RSDT(const Params &p);
};
class XSDT : public RXSDT<uint64_t>
{
protected:
PARAMS(X86ACPIXSDT);
public:
XSDT(const Params &p);
};
namespace MADT
{
class Record : public SimObject
{
protected:
PARAMS(X86ACPIMadtRecord);
struct GEM5_PACKED Mem
{
uint8_t type = 0;
uint8_t length = 0;
};
static_assert(std::is_trivially_copyable_v<Mem>,
"Type not suitable for memcpy.");
uint8_t type;
virtual void prepareBuf(std::vector<uint8_t>& mem) const = 0;
public:
Record(const Params& p, uint8_t _type) : SimObject(p), type(_type) {}
std::vector<uint8_t>
prepare() const
{
std::vector<uint8_t> mem;
prepareBuf(mem);
return mem;
}
};
class LAPIC : public Record
{
protected:
PARAMS(X86ACPIMadtLAPIC);
struct GEM5_PACKED Mem : public Record::Mem
{
uint8_t acpiProcessorId = 0;
uint8_t apicId = 0;
uint32_t flags = 0;
};
static_assert(std::is_trivially_copyable_v<Mem>,
"Type not suitable for memcpy.");
void prepareBuf(std::vector<uint8_t>& mem) const override;
public:
LAPIC(const Params& p) : Record(p, 0) {}
};
class IOAPIC : public Record
{
protected:
PARAMS(X86ACPIMadtIOAPIC);
struct GEM5_PACKED Mem : public Record::Mem
{
uint8_t ioApicId = 0;
uint8_t _reserved = 0;
uint32_t ioApicAddress = 0;
uint32_t intBase = 0;
};
static_assert(std::is_trivially_copyable_v<Mem>,
"Type not suitable for memcpy.");
void prepareBuf(std::vector<uint8_t>& mem) const override;
public:
IOAPIC(const Params& p) : Record(p, 1) {}
};
class IntSourceOverride : public Record
{
protected:
PARAMS(X86ACPIMadtIntSourceOverride);
struct GEM5_PACKED Mem : public Record::Mem
{
uint8_t busSource = 0;
uint8_t irqSource = 0;
uint32_t globalSystemInterrupt = 0;
uint16_t flags = 0;
};
static_assert(std::is_trivially_copyable_v<Mem>,
"Type not suitable for memcpy.");
void prepareBuf(std::vector<uint8_t>& mem) const override;
public:
IntSourceOverride(const Params& p) : Record(p, 2) {}
};
class NMI : public Record
{
protected:
PARAMS(X86ACPIMadtNMI);
struct GEM5_PACKED Mem : public Record::Mem
{
uint8_t acpiProcessorId = 0;
uint16_t flags = 0;
uint8_t lintNo = 0;
};
static_assert(std::is_trivially_copyable_v<Mem>,
"Type not suitable for memcpy.");
void prepareBuf(std::vector<uint8_t>& mem) const override;
public:
NMI(const Params& p) : Record(p, 3) {}
};
class LAPICOverride : public Record
{
protected:
PARAMS(X86ACPIMadtLAPICOverride);
struct GEM5_PACKED Mem : public Record::Mem
{
uint16_t _reserved = 0;
uint64_t localAPICAddress = 0;
};
static_assert(std::is_trivially_copyable_v<Mem>,
"Type not suitable for memcpy.");
void prepareBuf(std::vector<uint8_t>& mem) const override;
public:
LAPICOverride(const Params& p) : Record(p, 5) {}
};
class MADT : public SysDescTable
{
protected:
PARAMS(X86ACPIMadt);
struct GEM5_PACKED Mem : public SysDescTable::Mem
{
uint32_t localAPICAddress = 0;
uint32_t flags = 0;
};
static_assert(std::is_trivially_copyable_v<Mem>,
"Type not suitable for memcpy.");
std::vector<Record *> records;
Addr writeBuf(PortProxy& phys_proxy, Allocator& alloc,
std::vector<uint8_t>& mem) const override;
public:
MADT(const Params &p);
};
} // namespace MADT
} // namespace ACPI
} // namespace X86ISA
} // namespace gem5
#endif // __ARCH_X86_BIOS_E820_HH__