-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 23bbe2d
Showing
47 changed files
with
4,723 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Copyright (c) 2022 RIKEN | ||
All rights reserved. | ||
|
||
This software is released under the MIT License. | ||
http://opensource.org/licenses/mit-license.php |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
MAKE = make -C | ||
COMMON_MODULE = common | ||
UEFI_MODULE = uefi | ||
BOOTLOADER = hypervisor_bootloader | ||
BOOTLOADER_ARCH = aarch64-uefi | ||
KERNEL = hypervisor_kernel | ||
KERNEL_ARCH = aarch64-none | ||
CP = cp | ||
MKDIR = mkdir -p | ||
QEMU = qemu-system-aarch64 | ||
RM = rm -rf | ||
MOUNT = mount | ||
UMOUNT = umount | ||
UEFI_FD ?= QEMU_EFI.fd | ||
|
||
all: .FORCE | ||
$(MAKE) $(BOOTLOADER) | ||
$(MAKE) $(KERNEL) | ||
$(MKDIR) bin/EFI/BOOT/ | ||
$(CP) $(BOOTLOADER)/target/$(BOOTLOADER_ARCH)/release/$(BOOTLOADER) bin/EFI/BOOT/BOOTAA64.EFI | ||
$(CP) $(KERNEL)/target/$(KERNEL_ARCH)/release/$(KERNEL) bin/EFI/BOOT/$(KERNEL) | ||
|
||
clean: | ||
$(RM) bin | ||
$(MAKE) $(COMMON_MODULE) clean | ||
$(MAKE) $(UEFI_MODULE) clean | ||
$(MAKE) $(BOOTLOADER) clean | ||
$(MAKE) $(KERNEL) clean | ||
|
||
fmt: | ||
$(MAKE) $(COMMON_MODULE) fmt | ||
$(MAKE) $(UEFI_MODULE) fmt | ||
$(MAKE) $(BOOTLOADER) fmt | ||
$(MAKE) $(KERNEL) fmt | ||
|
||
run: all | ||
$(QEMU) -m 1G -cpu cortex-a53 -machine virt-2.12,virtualization=on -smp 4 -nographic -bios $(UEFI_FD) -drive file=fat:rw:bin/,format=raw,media=disk | ||
|
||
debug: all | ||
$(QEMU) -m 1G -cpu cortex-a53 -machine virt-2.12,virtualization=on -smp 4 -monitor stdio -bios $(UEFI_FD) -drive file=fat:rw:bin/,format=raw,media=disk | ||
|
||
write: | ||
$(MOUNT) $(DEVICE) /mnt | ||
$(CP) bin/EFI/BOOT/BOOTAA64.EFI /mnt/EFI/BOOT/BOOTAA64.EFI | ||
$(CP) bin/EFI/BOOT/$(KERNEL) /mnt/EFI/BOOT/$(KERNEL) | ||
$(UMOUNT) /mnt | ||
|
||
default: | ||
$(MAKE) all | ||
|
||
.FORCE: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/target | ||
/Cargo.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[package] | ||
name = "common" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
CARGO = cargo | ||
|
||
clean: | ||
$(CARGO) clean | ||
|
||
fmt: | ||
$(CARGO) fmt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
//! | ||
//! Advanced Configuration and Power Interface | ||
//! | ||
//! Supported ACPI Version 6.4 | ||
|
||
pub mod madt; | ||
|
||
const RSDP_SIGNATURE: [u8; 8] = *b"RSD PTR "; | ||
const XSDT_SIGNATURE: [u8; 4] = *b"XSDT"; | ||
|
||
const XSDT_STRUCT_SIZE: usize = core::mem::size_of::<XSDT>(); | ||
|
||
#[repr(C, packed)] | ||
struct RSDP { | ||
signature: [u8; 8], | ||
checksum: u8, | ||
oem_id: [u8; 6], | ||
revision: u8, | ||
rsdt_address: u32, | ||
length: u32, | ||
xsdt_address: u64, | ||
ex_checksum: u32, | ||
reserved: [u8; 3], | ||
} | ||
|
||
#[repr(C, packed)] | ||
struct XSDT { | ||
signature: [u8; 4], | ||
length: u32, | ||
revison: u8, | ||
checksum: u8, | ||
oem_id: [u8; 6], | ||
oem_table_id: u64, | ||
oem_revision: u32, | ||
creator_id: u32, | ||
creator_revision: u32, | ||
/* entries */ | ||
} | ||
|
||
#[derive(Debug, Clone)] | ||
pub struct GeneralAddressStructure { | ||
address: u64, | ||
address_type: u8, | ||
} | ||
|
||
#[derive(Debug)] | ||
pub enum AcpiError { | ||
InvalidSignature, | ||
InvalidAddress, | ||
TableNotFound, | ||
} | ||
|
||
impl GeneralAddressStructure { | ||
pub const SPACE_ID_SYSTEM_MEMORY: u8 = 0x00; | ||
const SPACE_ID_INVALID: u8 = 0x0B; | ||
|
||
fn invalid() -> Self { | ||
Self { | ||
address: 0, | ||
address_type: Self::SPACE_ID_INVALID, | ||
} | ||
} | ||
|
||
pub fn new(a: &[u8; 12]) -> Self { | ||
let address_type = a[0]; | ||
if address_type >= Self::SPACE_ID_INVALID { | ||
return Self::invalid(); | ||
} | ||
Self { | ||
address_type, | ||
address: u64::from_le_bytes((a[4..12]).try_into().unwrap()), | ||
} | ||
} | ||
|
||
pub const fn is_invalid(&self) -> bool { | ||
self.address_type == Self::SPACE_ID_INVALID | ||
} | ||
|
||
pub const fn get_address_type(&self) -> u8 { | ||
self.address_type | ||
} | ||
|
||
pub const fn get_address(&self) -> u64 { | ||
self.address | ||
} | ||
} | ||
|
||
pub fn get_acpi_table(rsdp_address: usize, signature: &[u8; 4]) -> Result<usize, AcpiError> { | ||
let rsdp = unsafe { &*(rsdp_address as *const RSDP) }; | ||
if rsdp.signature != RSDP_SIGNATURE { | ||
return Err(AcpiError::InvalidSignature); | ||
} | ||
if rsdp.xsdt_address == 0 { | ||
return Err(AcpiError::InvalidAddress); | ||
} | ||
let xsdt = unsafe { &*(rsdp.xsdt_address as *const XSDT) }; | ||
|
||
if xsdt.signature != XSDT_SIGNATURE { | ||
return Err(AcpiError::InvalidSignature); | ||
} | ||
|
||
for table_index in 0..((xsdt.length as usize - XSDT_STRUCT_SIZE) >> 3) { | ||
let table_address = unsafe { | ||
*((rsdp.xsdt_address as usize + XSDT_STRUCT_SIZE + (table_index << 3)) as *const u64) | ||
} as usize; | ||
|
||
if unsafe { *(table_address as *const [u8; 4]) } == *signature { | ||
return Ok(table_address); | ||
} | ||
} | ||
|
||
return Err(AcpiError::TableNotFound); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
//! | ||
//! Multiple APIC Description Table | ||
//! | ||
//! Supported MADT Revision: ~ 5 | ||
|
||
pub const MADT_SIGNATURE: [u8; 4] = *b"APIC"; | ||
|
||
const MADT_STRUCT_SIZE: usize = core::mem::size_of::<MADT>(); | ||
|
||
const STRUCT_TYPE_GICC: u8 = 0xB; | ||
|
||
const GICC_FLAGS_ENABLED: u32 = 1; | ||
|
||
#[repr(C, packed)] | ||
pub struct MADT { | ||
signature: [u8; 4], | ||
length: u32, | ||
revision: u8, | ||
checksum: u8, | ||
oem_id: [u8; 6], | ||
oem_table_id: [u8; 8], | ||
oem_revision: u32, | ||
creator_id: [u8; 4], | ||
creator_revision: u32, | ||
flags: u32, | ||
local_interrupt_controller_address: u32, | ||
/* interrupt_controller_structure: [struct; n] */ | ||
} | ||
|
||
#[repr(C, packed)] | ||
struct GicCpuInterfaceStructure { | ||
struct_type: u8, | ||
length: u8, | ||
reserved_1: [u8; 2], | ||
cpu_interface_number: u32, | ||
acpi_processor_uid: u32, | ||
flags: u32, | ||
parking_protocol_version: u32, | ||
performance_interrupt_gsiv: u32, | ||
parked_address: u64, | ||
physical_base_address: u64, | ||
gicv: u64, | ||
gich: u64, | ||
vgic_maintenance_interrupt: u32, | ||
gicr_base_address: u64, | ||
mpidr: u64, | ||
processor_power_efficiency_class: u8, | ||
reserved_2: u8, | ||
spe_overflow_interrupt: u16, | ||
} | ||
|
||
/// MADTのリストから順次GicCpuInterfaceStructureを検出し、MPIDRを返却するIterです | ||
/// | ||
/// このIteratorはMADTのInterrupt Controller Structure配列からGicCpuInterfaceStructureを先頭から順に | ||
/// 取得し、その中にあるMPIDRの値を返します。なお該当MPIDRが有効でない([`GICC_FLAGS_ENABLED`]が立ってない) | ||
/// 場合はスキップします。 | ||
pub struct ProcessorIdIter { | ||
base_address: usize, | ||
pointer: usize, | ||
length: usize, | ||
} | ||
|
||
impl MADT { | ||
pub fn get_processor_id_list(&self) -> ProcessorIdIter { | ||
let length = self.length as usize - MADT_STRUCT_SIZE; | ||
let base_address = self as *const _ as usize + MADT_STRUCT_SIZE; | ||
|
||
ProcessorIdIter { | ||
base_address, | ||
pointer: 0, | ||
length, | ||
} | ||
} | ||
} | ||
|
||
impl Iterator for ProcessorIdIter { | ||
type Item = u64; | ||
fn next(&mut self) -> Option<Self::Item> { | ||
if self.pointer >= self.length { | ||
return None; | ||
} | ||
let record_base = self.base_address + self.pointer; | ||
let record_type = unsafe { *(record_base as *const u8) }; | ||
let record_length = unsafe { *((record_base + 1) as *const u8) }; | ||
|
||
self.pointer += record_length as usize; | ||
match record_type { | ||
STRUCT_TYPE_GICC => { | ||
let gicc_struct = unsafe { &*(record_base as *const GicCpuInterfaceStructure) }; | ||
if (gicc_struct.flags & GICC_FLAGS_ENABLED) != 0 { | ||
/* Enabled */ | ||
Some(gicc_struct.mpidr) | ||
} else { | ||
self.next() | ||
} | ||
} | ||
_ => self.next(), | ||
} | ||
} | ||
} |
Oops, something went wrong.