1 // 2 // Copyright (c) 2010-2024 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 8 using System.Text; 9 using System.Linq; 10 using Antmicro.Renode.Peripherals.Bus; 11 using Antmicro.Renode.Peripherals.CPU; 12 using Antmicro.Renode.Core.ACPI; 13 using Antmicro.Renode.Utilities.Packets; 14 15 namespace Antmicro.Renode.Core.Extensions 16 { 17 public static class ACPIExtensions 18 { GenerateACPITable(this IBusController bus, ulong address)19 public static void GenerateACPITable(this IBusController bus, ulong address) 20 { 21 var rootSystemDescriptionTableOffset = 22 (uint)address + (uint)Packet.CalculateLength<RootSystemDescriptionPointer>(); 23 var rootSystemDescriptionPointer = new RootSystemDescriptionPointer(rootSystemDescriptionTableOffset); 24 bus.WriteBytes(Packet.Encode(rootSystemDescriptionPointer), address); 25 26 var fixedACPIDescriptionTableAddress = 27 rootSystemDescriptionTableOffset + (uint)Packet.CalculateLength<RootSystemDescriptionTable>(); 28 var multipleAPICDescriptionTableHeaderAddress = 29 fixedACPIDescriptionTableAddress + (uint)Packet.CalculateLength<FixedACPIDescriptionTable>(); 30 31 var rootSystemDescriptionTable = new RootSystemDescriptionTable(fixedACPIDescriptionTableAddress, multipleAPICDescriptionTableHeaderAddress); 32 bus.WriteBytes(Packet.Encode(rootSystemDescriptionTable), rootSystemDescriptionTableOffset); 33 34 var fixedACPIDescriptionTable = new FixedACPIDescriptionTable(multipleAPICDescriptionTableHeaderAddress - (uint)address, fixedACPIDescriptionTableAddress); 35 bus.WriteBytes(Packet.Encode(fixedACPIDescriptionTable), fixedACPIDescriptionTableAddress); 36 37 var ids = bus.GetCPUs().OfType<BaseX86>().Select(x => (ulong)x.Lapic.ID).ToList(); 38 39 var multipleAPICDescriptionTableLength = Packet.CalculateLength<MultipleAPICDescriptionTable>(); 40 var recordLength = (uint)Packet.CalculateLength<ProcessorLocalAPICRecord>(); 41 42 // Define table without records. They will be defined based on CPUs. 43 var multipleAPICDescriptionTable = new MultipleAPICDescriptionTable((uint)(multipleAPICDescriptionTableLength + ids.Count() * recordLength)); 44 bus.WriteBytes(Packet.Encode(multipleAPICDescriptionTable), multipleAPICDescriptionTableHeaderAddress); 45 46 var recordAddress = 47 multipleAPICDescriptionTableHeaderAddress + (uint)Packet.CalculateLength<MultipleAPICDescriptionTable>(); 48 49 foreach(var id in ids) 50 { 51 var processorLocalAPICRecord = new ProcessorLocalAPICRecord 52 { 53 EntryType = 0x0, // 0x0 means local APIC entry type 54 RecordLength = 0x8, 55 APICID = (byte)id, 56 Flags = 0x01 // bit 0 = Processor Enabled 57 }; 58 var table = Packet.Encode(processorLocalAPICRecord).ToArray(); 59 bus.WriteBytes(table, recordAddress); 60 61 recordAddress += recordLength; 62 } 63 } 64 } 65 } 66