[gem5-dev] Change in gem5/gem5[develop]: arch-x86: Add ACPI support for MADT

2021-05-07 Thread Maximilian Stein (Gerrit) via gem5-dev
Maximilian Stein has submitted this change. (  
https://gem5-review.googlesource.com/c/public/gem5/+/41953 )


Change subject: arch-x86: Add ACPI support for MADT
..

arch-x86: Add ACPI support for MADT

This extends the ACPI implementation to support the MADT. This table
contains information about the interrupt system (Local APIC, IO-APIC)
and partially replaces the Intel MP tables.
The change is particularly needed to support other OSes than Linux that
do not support Intel MP.

Change-Id: I132226f46f4d54e2e0b964e2986004e3e5f5f347
Signed-off-by: Maximilian Stein 
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/41953
Reviewed-by: Gabe Black 
Maintainer: Gabe Black 
Tested-by: kokoro 
---
M src/arch/x86/bios/ACPI.py
M src/arch/x86/bios/acpi.cc
M src/arch/x86/bios/acpi.hh
3 files changed, 336 insertions(+), 0 deletions(-)

Approvals:
  Gabe Black: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/arch/x86/bios/ACPI.py b/src/arch/x86/bios/ACPI.py
index 19edac4..5dfcb4d 100644
--- a/src/arch/x86/bios/ACPI.py
+++ b/src/arch/x86/bios/ACPI.py
@@ -67,6 +67,66 @@

 entries = VectorParam.X86ACPISysDescTable([], 'system description  
tables')


+
+class X86ACPIMadtRecord(SimObject):
+type = 'X86ACPIMadtRecord'
+cxx_class = 'X86ISA::ACPI::MADT::Record'
+cxx_header = 'arch/x86/bios/acpi.hh'
+abstract = True
+
+class X86ACPIMadt(X86ACPISysDescTable):
+type = 'X86ACPIMadt'
+cxx_class = 'X86ISA::ACPI::MADT::MADT'
+cxx_header = 'arch/x86/bios/acpi.hh'
+
+local_apic_address = Param.UInt32(0, 'Address of the local apic')
+flags = Param.UInt32(0, 'Flags')
+records = VectorParam.X86ACPIMadtRecord([], 'Records in this MADT')
+
+class X86ACPIMadtLAPIC(X86ACPIMadtRecord):
+type = 'X86ACPIMadtLAPIC'
+cxx_header = 'arch/x86/bios/acpi.hh'
+cxx_class = 'X86ISA::ACPI::MADT::LAPIC'
+
+acpi_processor_id = Param.UInt8(0, 'ACPI Processor ID')
+apic_id = Param.UInt8(0, 'APIC ID')
+flags = Param.UInt32(0, 'Flags')
+
+class X86ACPIMadtIOAPIC(X86ACPIMadtRecord):
+type = 'X86ACPIMadtIOAPIC'
+cxx_header = 'arch/x86/bios/acpi.hh'
+cxx_class = 'X86ISA::ACPI::MADT::IOAPIC'
+
+id = Param.UInt8(0, 'I/O APIC ID')
+address = Param.Addr(0, 'I/O APIC Address')
+int_base = Param.UInt32(0, 'Global Interrupt Base')
+
+class X86ACPIMadtIntSourceOverride(X86ACPIMadtRecord):
+type = 'X86ACPIMadtIntSourceOverride'
+cxx_header = 'arch/x86/bios/acpi.hh'
+cxx_class = 'X86ISA::ACPI::MADT::IntSourceOverride'
+
+bus_source = Param.UInt8(0, 'Bus Source')
+irq_source = Param.UInt8(0, 'IRQ Source')
+sys_int = Param.UInt32(0, 'Global System Interrupt')
+flags = Param.UInt16(0, 'Flags')
+
+class X86ACPIMadtNMI(X86ACPIMadtRecord):
+type = 'X86ACPIMadtNMI'
+cxx_header = 'arch/x86/bios/acpi.hh'
+cxx_class = 'X86ISA::ACPI::MADT::NMI'
+
+acpi_processor_id = Param.UInt8(0, 'ACPI Processor ID')
+flags = Param.UInt16(0, 'Flags')
+lint_no = Param.UInt8(0, 'LINT# (0 or 1)')
+
+class X86ACPIMadtLAPICOverride(X86ACPIMadtRecord):
+type = 'X86ACPIMadtLAPICOverride'
+cxx_header = 'arch/x86/bios/acpi.hh'
+cxx_class = 'X86ISA::ACPI::MADT::LAPICOverride'
+
+address = Param.Addr(0, '64-bit Physical Address of Local APIC')
+
 # Root System Description Pointer Structure
 class X86ACPIRSDP(SimObject):
 type = 'X86ACPIRSDP'
diff --git a/src/arch/x86/bios/acpi.cc b/src/arch/x86/bios/acpi.cc
index 91c8e47..53b6e4d 100644
--- a/src/arch/x86/bios/acpi.cc
+++ b/src/arch/x86/bios/acpi.cc
@@ -195,6 +195,119 @@
 entries = p.entries;
 }

+
+ MADT
+MADT::MADT::MADT(const Params& p) :
+SysDescTable(p, "APIC", 4),
+records(p.records)
+{}
+
+Addr
+MADT::MADT::writeBuf(PortProxy& phys_proxy, Allocator& alloc,
+std::vector& mem) const
+{
+// Since this table ends with a variably sized array, it can't be  
extended

+// by another table type.
+assert(mem.empty());
+mem.resize(sizeof(Mem));
+
+Mem* header = reinterpret_cast(mem.data());
+header->localAPICAddress = params().local_apic_address;
+header->flags = params().flags;
+
+for (const auto& record : records) {
+auto entry = record->prepare();
+mem.insert(mem.end(), entry.begin(), entry.end());
+}
+
+DPRINTF(ACPI, "MADT: writing %d records (size: %d)\n",
+records.size(), mem.size());
+
+return SysDescTable::writeBuf(phys_proxy, alloc, mem);
+}
+
+void
+MADT::Record::prepareBuf(std::vector& mem) const
+{
+assert(mem.size() >= sizeof(Mem));
+DPRINTF(ACPI, "MADT: writing record type %d (size: %d)\n",
+type, mem.size());
+
+Mem* header = reinterpret_cast(mem.data());
+header->type = type;
+header->length = mem.size();
+}
+
+void
+MADT::LAPIC::prepareBuf(std::vector& mem) const
+{
+assert(mem.empty());
+mem.resize(sizeof(Mem));
+
+ 

[gem5-dev] Change in gem5/gem5[develop]: arch-x86: Add ACPI support for MADT

2021-02-26 Thread Maximilian Stein (Gerrit) via gem5-dev
Maximilian Stein has uploaded this change for review. (  
https://gem5-review.googlesource.com/c/public/gem5/+/41953 )



Change subject: arch-x86: Add ACPI support for MADT
..

arch-x86: Add ACPI support for MADT

This extends ACPI to support the MADT. This table contains information
about the interrupt system (Local APIC, IO-APIC) and partly replaces the
Intel MP tables.
The change is particularly needed to support other OSes than Linux that
do not support Intel MP.

This patch contains the necessary python and c++ classes to create MADT
records, setup the MADT itself, and extends the RSDP, RSDT, and XSDT.

Change-Id: I132226f46f4d54e2e0b964e2986004e3e5f5f347
Signed-off-by: Maximilian Stein 
---
M configs/common/FSConfig.py
M src/arch/x86/SConscript
M src/arch/x86/bios/ACPI.py
M src/arch/x86/bios/acpi.cc
M src/arch/x86/bios/acpi.hh
M src/arch/x86/fs_workload.cc
6 files changed, 619 insertions(+), 34 deletions(-)



diff --git a/configs/common/FSConfig.py b/configs/common/FSConfig.py
index 6665225..98df117 100644
--- a/configs/common/FSConfig.py
+++ b/configs/common/FSConfig.py
@@ -501,6 +501,7 @@
 # Set up the Intel MP table
 base_entries = []
 ext_entries = []
+madt_records = []
 for i in range(numCPUs):
 bp = X86IntelMPProcessor(
 local_apic_id = i,
@@ -508,6 +509,11 @@
 enable = True,
 bootstrap = (i == 0))
 base_entries.append(bp)
+lapic = X86ACPIMadtLAPIC(
+acpi_processor_id=i,
+apic_id=i,
+flags=1)
+madt_records.append(lapic)
 io_apic = X86IntelMPIOAPIC(
 id = numCPUs,
 version = 0x11,
@@ -515,6 +521,8 @@
 address = 0xfec0)
 self.pc.south_bridge.io_apic.apic_id = io_apic.id
 base_entries.append(io_apic)
+madt_records.append(X86ACPIMadtIOAPIC(id=io_apic.id,
+address=io_apic.address, int_base=0))
 # In gem5 Pc::calcPciConfigAddr(), it required "assert(bus==0)",
 # but linux kernel cannot config PCI device if it was not connected to
 # PCI bus, so we fix PCI bus id to 0, and ISA bus id to 1.
@@ -534,6 +542,13 @@
 dest_io_apic_id = io_apic.id,
 dest_io_apic_intin = 16)
 base_entries.append(pci_dev4_inta)
+pci_dev4_inta_madt = X86ACPIMadtIntSourceOverride(
+bus_source = pci_dev4_inta.source_bus_id,
+irq_source = pci_dev4_inta.source_bus_irq,
+sys_int = pci_dev4_inta.dest_io_apic_intin,
+flags = 0
+)
+madt_records.append(pci_dev4_inta_madt)
 def assignISAInt(irq, apicPin):
 assign_8259_to_apic = X86IntelMPIOIntAssignment(
 interrupt_type = 'ExtInt',
@@ -553,6 +568,14 @@
 dest_io_apic_id = io_apic.id,
 dest_io_apic_intin = apicPin)
 base_entries.append(assign_to_apic)
+# acpi
+assign_to_apic_acpi = X86ACPIMadtIntSourceOverride(
+bus_source = 1,
+irq_source = irq,
+sys_int = apicPin,
+flags = 0
+)
+madt_records.append(assign_to_apic_acpi)
 assignISAInt(0, 2)
 assignISAInt(1, 1)
 for i in range(3, 15):
@@ -560,6 +583,13 @@
 workload.intel_mp_table.base_entries = base_entries
 workload.intel_mp_table.ext_entries = ext_entries

+madt = X86ACPIMadt(local_apic_address=0,
+records=madt_records, oem_id='madt')
+workload.acpi_description_table_pointer.rsdt.entries.append(madt)
+workload.acpi_description_table_pointer.xsdt.entries.append(madt)
+workload.acpi_description_table_pointer.oem_id = 'gem5'
+workload.acpi_description_table_pointer.rsdt.oem_id='gem5'
+workload.acpi_description_table_pointer.xsdt.oem_id='gem5'
 return self

 def makeLinuxX86System(mem_mode, numCPUs=1, mdesc=None, Ruby=False,
diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript
index f790ec1..1fcf1dc 100644
--- a/src/arch/x86/SConscript
+++ b/src/arch/x86/SConscript
@@ -81,6 +81,7 @@
   "Page table walker state machine debugging")
 DebugFlag('Decoder', "Decoder debug output")
 DebugFlag('X86', "Generic X86 ISA debugging")
+DebugFlag('ACPI', "ACPI debugging")

 python_files = (
 '__init__.py',
diff --git a/src/arch/x86/bios/ACPI.py b/src/arch/x86/bios/ACPI.py
index 77de42f..5dfcb4d 100644
--- a/src/arch/x86/bios/ACPI.py
+++ b/src/arch/x86/bios/ACPI.py
@@ -48,8 +48,8 @@
 oem_table_id = Param.String('', 'oem table ID')
 oem_revision = Param.UInt32(0, 'oem revision number for the table')

-creator_id = Param.String('',
-'string identifying the generator of the table')
+creator_id = Param.UInt32(0,
+'ID identifying the generator of the table')
 creator_revision = Param.UInt32(0,
 'revision number for the creator of the table')

@@ -67,6 +67,66 @@

 entries = VectorPa