1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/openeuler-stratovirt

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Это зеркальный репозиторий, синхронизируется ежедневно с исходного репозитория.
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
acpi_table.rs 17 КБ
Копировать Редактировать Исходные данные Просмотреть построчно История
yezengruan Отправлено год назад 6c1b7ee
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
// Copyright (c) 2020 Huawei Technologies Co.,Ltd. All rights reserved.
//
// StratoVirt is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan
// PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
use super::aml_compiler::AmlBuilder;
use util::byte_code::ByteCode;
/// Offset of checksum field in ACPI table.
pub const TABLE_CHECKSUM_OFFSET: u32 = 9;
pub const INTERRUPT_PPIS_COUNT: u32 = 16;
pub const INTERRUPT_SGIS_COUNT: u32 = 16;
/// GTDT irq number for timer.
pub const ACPI_GTDT_ARCH_TIMER_VIRT_IRQ: u32 = 11;
pub const ACPI_GTDT_ARCH_TIMER_S_EL1_IRQ: u32 = 13;
pub const ACPI_GTDT_ARCH_TIMER_NS_EL1_IRQ: u32 = 14;
pub const ACPI_GTDT_ARCH_TIMER_NS_EL2_IRQ: u32 = 10;
pub const ACPI_GTDT_INTERRUPT_MODE_LEVEL: u32 = 0;
pub const ACPI_GTDT_CAP_ALWAYS_ON: u32 = 4;
/// IORT node types, reference: ARM Document number: ARM DEN 0049B, October 2015.
pub const ACPI_IORT_NODE_ITS_GROUP: u8 = 0x00;
pub const ACPI_IORT_NODE_PCI_ROOT_COMPLEX: u8 = 0x02;
/// Root Complex Node in IORT
pub const ROOT_COMPLEX_ENTRY_SIZE: u16 = 36;
pub const ID_MAPPING_ENTRY_SIZE: u16 = 20;
/// Interrupt controller structure types for MADT.
pub const ACPI_MADT_GENERIC_CPU_INTERFACE: u8 = 11;
pub const ACPI_MADT_GENERIC_DISTRIBUTOR: u8 = 12;
pub const ACPI_MADT_GENERIC_REDISTRIBUTOR: u8 = 14;
pub const ACPI_MADT_GENERIC_TRANSLATOR: u8 = 15;
#[repr(C, packed)]
#[derive(Default, Copy, Clone)]
pub struct AcpiGenericAddress {
space_id: u8,
bit_width: u8,
bit_offset: u8,
access_size: u8,
address: u64,
}
impl AcpiGenericAddress {
pub fn new_io_address<T: Into<u64>>(addr: T) -> AcpiGenericAddress {
AcpiGenericAddress {
space_id: 1,
bit_width: 8 * std::mem::size_of::<T>() as u8,
bit_offset: 0,
access_size: std::mem::size_of::<T>() as u8,
address: addr.into(),
}
}
}
impl ByteCode for AcpiGenericAddress {}
impl AmlBuilder for AcpiGenericAddress {
fn aml_bytes(&self) -> Vec<u8> {
self.as_bytes().to_vec()
}
}
/// The common ACPI table header.
#[repr(C, packed)]
#[derive(Default, Copy, Clone)]
pub struct AcpiTableHeader {
/// Signature of this table.
signature: [u8; 4],
/// The total length of this table, including this header.
length: u32,
/// The revision of this table.
revision: u8,
/// The checksum of this table, including this header.
checksum: u8,
/// OEM ID.
oem_id: [u8; 6],
/// OEM table ID.
oem_table_id: [u8; 8],
/// OEM revision of this table.
oem_revision: u32,
/// Vendor ID for the ASL Compiler, default zero.
asl_compiler_id: [u8; 4],
/// Revision number of the ASL Compiler, default zero.
asl_compiler_revision: u32,
}
impl ByteCode for AcpiTableHeader {}
impl AmlBuilder for AcpiTableHeader {
fn aml_bytes(&self) -> Vec<u8> {
self.as_bytes().to_vec()
}
}
/// ACPI table.
pub struct AcpiTable {
entries: Vec<u8>,
}
impl AcpiTable {
/// The construct function of ACPI table.
///
/// # Arguments
///
/// `signature` - The signature of this table.
/// `revision` - The revision of this table.
/// `oem_id` - OEM ID.
/// `oem_table_id` - OEM table ID.
/// `oem_revision` - OEM revision.
pub fn new(
signature: [u8; 4],
revision: u8,
oem_id: [u8; 6],
oem_table_id: [u8; 8],
oem_revision: u32,
) -> AcpiTable {
AcpiTable {
entries: AcpiTableHeader {
signature,
length: 0,
revision,
checksum: 0,
oem_id,
oem_table_id,
oem_revision,
asl_compiler_id: [0_u8; 4],
asl_compiler_revision: 0_u32,
}
.aml_bytes(),
}
}
/// Get the length of this table.
pub fn table_len(&self) -> usize {
self.entries.len()
}
/// Append the length of this table, do not support truncation.
pub fn set_table_len(&mut self, new_size: usize) {
if new_size < self.entries.len() {
panic!("New size is smaller than old-size, truncation is not supported.");
}
self.entries
.extend(vec![0_u8; new_size - self.entries.len()].as_slice());
self.entries[4..=7].copy_from_slice((new_size as u32).as_bytes());
}
/// Set the value of one field in table.
///
/// # Arguments
///
/// `byte_index` - The location of field in this table.
/// `new_value` - The new value that will be set in the field.
pub fn set_field<T: ByteCode>(&mut self, byte_index: usize, new_value: T) {
let value_len = std::mem::size_of::<T>();
if byte_index >= self.entries.len() || byte_index + value_len > self.entries.len() {
panic!("Set field in table failed: overflow occurs.");
}
self.entries[byte_index..(byte_index + value_len)].copy_from_slice(new_value.as_bytes());
}
/// Append byte stream to the end of table.
pub fn append_child(&mut self, bytes: &[u8]) {
self.entries.extend(bytes);
let table_len = self.entries.len() as u32;
self.entries[4..=7].copy_from_slice(table_len.as_bytes());
}
}
impl AmlBuilder for AcpiTable {
fn aml_bytes(&self) -> Vec<u8> {
self.entries.clone()
}
}
#[repr(C, packed)]
#[derive(Default, Copy, Clone)]
pub struct ProcessorHierarchyNode {
r#type: u8,
length: u8,
reserved: u16,
flags: u32,
parent: u32,
acpi_processor_id: u32,
num_private_resources: u32,
}
impl ByteCode for ProcessorHierarchyNode {}
impl AmlBuilder for ProcessorHierarchyNode {
fn aml_bytes(&self) -> Vec<u8> {
self.as_bytes().to_vec()
}
}
impl ProcessorHierarchyNode {
pub fn new(
flags: u32,
parent: u32,
acpi_processor_id: u32,
num_private_resources: u32,
) -> Self {
Self {
r#type: 0,
length: 20 + num_private_resources as u8 * 4,
reserved: 0,
flags,
parent,
acpi_processor_id,
num_private_resources,
}
}
}
pub fn processor_append_priv_res(pptt: &mut AcpiTable, priv_resources: Vec<u32>) {
let start = pptt.table_len();
pptt.set_table_len(start + priv_resources.len() * 4);
for (i, priv_res) in priv_resources.iter().enumerate() {
pptt.set_field(start + i * 4, *priv_res);
}
}
/// The Type of the hardcoded cache info
pub enum CacheType {
L1D,
L1I,
L2,
L3,
}
struct CacheNode {
size: u32,
sets: u32,
associativity: u8,
attributes: u8,
line_size: u16,
}
const CACHE_NODES: [CacheNode; CacheType::L3 as usize + 1] = [
// L1 data cache
CacheNode {
size: 65536,
sets: 256,
associativity: 4,
attributes: 2,
line_size: 64,
},
// L1 instruction cache
CacheNode {
size: 65536,
sets: 256,
associativity: 4,
attributes: 4,
line_size: 64,
},
// L2 unified cache
CacheNode {
size: 524288,
sets: 1024,
associativity: 8,
attributes: 10,
line_size: 64,
},
// L3 unified cache
CacheNode {
size: 33554432,
sets: 2048,
associativity: 15,
attributes: 10,
line_size: 128,
},
];
#[repr(C, packed)]
#[derive(Default, Copy, Clone)]
pub struct CacheHierarchyNode {
r#type: u8,
length: u8,
reserved: u16,
flags: u32,
next_level: u32,
size: u32,
number_sets: u32,
associativity: u8,
attributes: u8,
line_size: u16,
}
impl ByteCode for CacheHierarchyNode {}
impl AmlBuilder for CacheHierarchyNode {
fn aml_bytes(&self) -> Vec<u8> {
self.as_bytes().to_vec()
}
}
impl CacheHierarchyNode {
pub fn new(next_level: u32, cache_type: CacheType) -> Self {
let cache_node = &CACHE_NODES[cache_type as usize];
Self {
r#type: 1,
length: 24,
reserved: 0,
flags: 127,
next_level,
size: cache_node.size,
number_sets: cache_node.sets,
associativity: cache_node.associativity,
attributes: cache_node.attributes,
line_size: cache_node.line_size,
}
}
}
/// ACPI RSDP structure.
#[repr(C, packed)]
#[derive(Default, Copy, Clone)]
pub struct AcpiRsdp {
/// The signature of RSDP, which is "RSD PTR ".
signature: [u8; 8],
/// The checksum of the first 20 bytes of RSDP.
checksum: u8,
/// OEM ID.
oem_id: [u8; 6],
/// The revision of this structure, only revision 2 is supported.
revision: u8,
/// 32-bit address of RSDT table.
rsdt_tlb_addr: u32,
/// The length of this table.
length: u32,
/// 64-bit address of XSDT table.
xsdt_tlb_addr: u64,
/// Extended checksum of this RSDP structure.
extended_checksum: u8,
/// Reserved field.
reserved: [u8; 3],
}
impl AcpiRsdp {
pub fn new(oem_id: [u8; 6]) -> AcpiRsdp {
AcpiRsdp {
signature: *b"RSD PTR ",
checksum: 0,
oem_id,
revision: 2,
rsdt_tlb_addr: 0_u32,
length: std::mem::size_of::<AcpiRsdp>() as u32,
xsdt_tlb_addr: 0_u64,
extended_checksum: 0,
reserved: [0_u8; 3],
}
}
}
impl ByteCode for AcpiRsdp {}
impl AmlBuilder for AcpiRsdp {
fn aml_bytes(&self) -> Vec<u8> {
self.as_bytes().to_vec()
}
}
/// ACPI SRAT processor affinity structure.
#[repr(C, packed)]
#[derive(Default, Copy, Clone)]
pub struct AcpiSratProcessorAffinity {
/// Type ID.
pub type_id: u8,
/// The length of this structure.
pub length: u8,
/// Bit `\[`7:0`\]` of the proximity domain to which the processor belongs.
pub proximity_lo: u8,
/// The processor local APIC ID.
pub local_apic_id: u8,
/// The processor affinity flags.
pub flags: u32,
/// The processor local SAPIC EID.
pub local_sapic_eid: u8,
/// Bit `\[`31:8`\]` of the proximity domain to which the processor belongs.
pub proximity_hi: [u8; 3],
/// The clock domain to which the processor belongs.
pub clock_domain: u32,
}
impl ByteCode for AcpiSratProcessorAffinity {}
impl AmlBuilder for AcpiSratProcessorAffinity {
fn aml_bytes(&self) -> Vec<u8> {
Vec::from(self.as_bytes())
}
}
/// ACPI SRAT GICC affinity structure.
#[repr(C, packed)]
#[derive(Default, Copy, Clone)]
pub struct AcpiSratGiccAffinity {
/// Type ID.
pub type_id: u8,
/// The length of this structure.
pub length: u8,
/// Represents the proximity domain to which the "range of memory" belongs.
pub proximity_domain: u32,
/// The ACPI processor UID of the associated GICC
pub process_uid: u32,
/// The GICC affinity flags.
pub flags: u32,
/// The clock domain to which the processor belongs.
pub clock_domain: u32,
}
impl ByteCode for AcpiSratGiccAffinity {}
impl AmlBuilder for AcpiSratGiccAffinity {
fn aml_bytes(&self) -> Vec<u8> {
Vec::from(self.as_bytes())
}
}
/// ACPI SRAT memory affinity structure.
#[repr(C, packed)]
#[derive(Default, Copy, Clone)]
pub struct AcpiSratMemoryAffinity {
/// Type ID.
pub type_id: u8,
/// The length of this structure.
pub length: u8,
/// Represents the proximity domain to which the "range of memory" belongs.
pub proximity_domain: u32,
/// Reserved field.
pub reserved1: u16,
/// The base address of the memory range.
pub base_addr: u64,
/// The length of the memory range.
pub range_length: u64,
/// Reserved field.
pub reserved2: u32,
/// Indicates whether memory is enabled and can be hot plugged.
pub flags: u32,
/// Reserved field.
pub reserved3: u64,
}
impl ByteCode for AcpiSratMemoryAffinity {}
impl AmlBuilder for AcpiSratMemoryAffinity {
fn aml_bytes(&self) -> Vec<u8> {
Vec::from(self.as_bytes())
}
}
/// This module describes ACPI MADT's sub-tables on x86_64 platform.
#[cfg(target_arch = "x86_64")]
pub mod madt_subtable {
use super::*;
pub const IOAPIC_BASE_ADDR: u32 = 0xfec0_0000;
pub const LAPIC_BASE_ADDR: u32 = 0xfee0_0000;
/// MADT processor Local APIC structure.
#[repr(C, packed)]
#[derive(Default, Copy, Clone)]
pub struct AcpiLocalApic {
/// Type ID.
pub type_id: u8,
/// The length of this structure.
pub length: u8,
/// ACPI processor UID.
pub processor_uid: u8,
/// The processor's Local APIC ID.
pub apic_id: u8,
/// Local APIC flags.
pub flags: u32,
}
impl ByteCode for AcpiLocalApic {}
impl AmlBuilder for AcpiLocalApic {
fn aml_bytes(&self) -> Vec<u8> {
Vec::from(self.as_bytes())
}
}
/// IO APIC structure.
#[repr(C, packed)]
#[derive(Default, Copy, Clone)]
pub struct AcpiIoApic {
/// Type ID.
pub type_id: u8,
/// The length of this structure.
pub length: u8,
/// This IO APIC's ID.
pub io_apic_id: u8,
/// Reserved field.
pub reserved: u8,
/// The 32-bit address of this IO APIC.
pub io_apic_addr: u32,
/// The GSI number where this I/O APIC’s interrupt inputs start.
pub gsi_base: u32,
}
impl ByteCode for AcpiIoApic {}
impl AmlBuilder for AcpiIoApic {
fn aml_bytes(&self) -> Vec<u8> {
Vec::from(self.as_bytes())
}
}
}
/// This module describes ACPI MADT's sub-tables on aarch64 platform.
#[cfg(target_arch = "aarch64")]
pub mod madt_subtable {
use super::*;
pub const ARCH_GIC_MAINT_IRQ: u32 = 9;
/// GIC CPU Interface structure.
#[repr(C, packed)]
#[derive(Default, Copy, Clone)]
pub struct AcpiGicCpu {
/// Type ID.
pub type_id: u8,
/// The length of this structure.
pub length: u8,
/// Reserved field.
reserved_1: u16,
/// CPU interface number.
pub cpu_interface_num: u32,
/// ACPI processor UID.
pub processor_uid: u32,
/// Flags.
pub flags: u32,
/// The version of Arm processor parking protocol.
pub parking_version: u32,
/// The GSIV used for performance monitoring interrupts.
pub perf_interrupt: u32,
/// The 64-bit address of the processor’s parking protocol mailbox.
pub parked_addr: u64,
/// CPU can access this CPU interface via this 64-bit address.
pub base_addr: u64,
/// Address of the GIC virtual CPU interface registers.
pub gicv_addr: u64,
/// Address of the GIC virtual interface control block registers.
pub gich_addr: u64,
/// GSIV for Virtual GIC maintenance interrupt.
pub vgic_interrupt: u32,
/// If GIC's version is above 3, this field is 64-bit address of redistributor.
pub gicr_addr: u64,
/// MPIDR.
pub mpidr: u64,
/// Reserved field.
reserved_2: u32,
}
impl ByteCode for AcpiGicCpu {}
impl AmlBuilder for AcpiGicCpu {
fn aml_bytes(&self) -> Vec<u8> {
Vec::from(self.as_bytes())
}
}
/// GIC distributor structure.
#[repr(C, packed)]
#[derive(Default, Copy, Clone)]
pub struct AcpiGicDistributor {
/// Type ID.
pub type_id: u8,
/// The length of this structure.
pub length: u8,
/// Reserved field.
reserved_1: u16,
/// This distributor's hardware ID.
pub gic_id: u32,
/// The 64-bit address of this distributor.
pub base_addr: u64,
/// System vector base, must be zero.
pub sys_vector_base: u32,
/// GIC version.
pub gic_version: u8,
/// Reserved field.
reserved_2: [u8; 3],
}
impl ByteCode for AcpiGicDistributor {}
impl AmlBuilder for AcpiGicDistributor {
fn aml_bytes(&self) -> Vec<u8> {
Vec::from(self.as_bytes())
}
}
/// GIC Redistributor structure.
#[repr(C, packed)]
#[derive(Default, Copy, Clone)]
pub struct AcpiGicRedistributor {
/// Type ID.
pub type_id: u8,
/// The length of this structure.
pub length: u8,
/// Reserved field.
reserved_1: u16,
/// The 64-bit address of this redistributor.
pub base_addr: u64,
/// Length of the GIC redistributor discovery page range.
pub range_length: u32,
}
impl ByteCode for AcpiGicRedistributor {}
impl AmlBuilder for AcpiGicRedistributor {
fn aml_bytes(&self) -> Vec<u8> {
Vec::from(self.as_bytes())
}
}
/// GIC Interrupt Translation Service (ITS) Structure.
#[repr(C, packed)]
#[derive(Default, Copy, Clone)]
pub struct AcpiGicIts {
/// Type ID.
pub type_id: u8,
/// The length of this structure.
pub length: u8,
/// Reserved field.
reserved_1: u16,
/// ITS ID, must be unique.
pub its_id: u32,
/// The 64-bit address of this ITS.
pub base_addr: u64,
/// Reserved field.
reserved_2: u32,
}
impl ByteCode for AcpiGicIts {}
impl AmlBuilder for AcpiGicIts {
fn aml_bytes(&self) -> Vec<u8> {
Vec::from(self.as_bytes())
}
}
}

Комментарий ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://gitlife.ru/oschina-mirror/openeuler-stratovirt.git
git@gitlife.ru:oschina-mirror/openeuler-stratovirt.git
oschina-mirror
openeuler-stratovirt
openeuler-stratovirt
v2.4.0