Skip to content

Commit e1c7a5d

Browse files
committed
break the ground
1 parent 4c850ad commit e1c7a5d

File tree

8 files changed

+1057
-0
lines changed

8 files changed

+1057
-0
lines changed

Cargo.lock

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ version = "0.0.0"
88
dependencies = [
99
"bitfield-struct 0.10.1",
1010
"open_enum",
11+
"static_assertions",
1112
"zerocopy 0.8.24",
1213
]
1314

@@ -6454,6 +6455,7 @@ checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
64546455
name = "simple_tmk"
64556456
version = "0.0.0"
64566457
dependencies = [
6458+
"aarch64defs",
64576459
"minimal_rt_build",
64586460
"tmk_core",
64596461
"tmk_macros",

tmk/simple_tmk/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ edition.workspace = true
1010
tmk_core.workspace = true
1111
tmk_macros.workspace = true
1212
x86defs.workspace = true
13+
aarch64defs.workspace = true
1314

1415
[build-dependencies]
1516
minimal_rt_build.workspace = true

tmk/simple_tmk/src/aarch64/gicv3.rs

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
use crate::prelude::*;
2+
use aarch64defs::gic::*;
3+
4+
/// GICv3 intrerface
5+
pub struct Gicv3<'a> {
6+
/// Ditributor
7+
gicd: &'a mut GicDistributor,
8+
/// Redistibutors for each CPU
9+
gicr: &'a mut [GicRedistributor],
10+
}
11+
12+
/// GICv3
13+
///
14+
/// Initalization and configurations are described in "4. Configuring the GIC" of
15+
/// [GICv3 and GICv4 Software Overview](https://developer.arm.com/documentation/dai0492/b/)
16+
impl<'a> Gicv3<'a> {
17+
/// Initialize the GICv3 interface
18+
pub fn new(gicd_base: usize, gicr_base: usize, num_cpus: usize) -> Self {
19+
let gicd_base = gicd_base as *mut GicDistributor;
20+
let gicr_base = gicr_base as *mut GicRedistributor;
21+
22+
let gicd = unsafe { gicd_base.as_mut().expect("non NULL GICD") };
23+
let gicr = unsafe { core::slice::from_raw_parts_mut(gicr_base, num_cpus) };
24+
25+
let mut gic = Self { gicd, gicr };
26+
27+
let gicd_ver = gic.gicd.pidr2.gic_version();
28+
assert_eq!(gicd_ver, 3, "Expected GIC v3, got {gicd_ver}");
29+
30+
for (i, r) in gic.gicr.iter().enumerate() {
31+
let r_ver = r.lpi.pidr2.gic_version();
32+
assert_eq!(r_ver, 3, "Expected GICR v3, got {r_ver} on CPU {i}");
33+
}
34+
35+
gic.init_gicd();
36+
gic.init_gicr();
37+
gic.init_icc();
38+
39+
gic
40+
}
41+
42+
/// Initialize the distributor, route all SPIs to the BSP
43+
fn init_gicd(&mut self) {
44+
self.gicd.ctlr.reset();
45+
self.gicd.ctlr.wait_pending_write();
46+
47+
// Mask and clear all SPIs
48+
let max_spi = self.spi_lines();
49+
for i in 1..max_spi / 32 {
50+
self.gicd.icenabler[i] = !0;
51+
self.gicd.icpendr[i] = !0;
52+
self.gicd.igroupr[i] = !0;
53+
self.gicd.igrpmodr[i] = !0;
54+
}
55+
self.gicd.ctlr.wait_pending_write();
56+
57+
self.gicd.ctlr.set_enable_grp0(1);
58+
self.gicd.ctlr.set_enable_grp1_ns(1);
59+
self.gicd.ctlr.set_are_ns(1);
60+
61+
unsafe { core::arch::asm!("isb sy", options(nostack)) };
62+
63+
// CPU 0, affinity 0.0.0.0
64+
for i in 32..max_spi {
65+
self.gicd.irouter[i] = 0;
66+
}
67+
self.gicd.ctlr.wait_pending_write();
68+
69+
unsafe { core::arch::asm!("isb sy", options(nostack)) };
70+
}
71+
72+
/// Initialize the redistributor
73+
fn init_gicr(&mut self) {
74+
todo!()
75+
}
76+
77+
/// Initialize the control interface to the CPU
78+
/// through the ICC_* system registers
79+
fn init_icc(&mut self) {
80+
todo!()
81+
}
82+
83+
pub fn gicd(&self) -> &GicDistributor {
84+
self.gicd
85+
}
86+
87+
pub fn gicr(&self) -> &[GicRedistributor] {
88+
self.gicr
89+
}
90+
91+
pub fn spi_lines(&self) -> usize {
92+
32 * (self.gicd.typer.it_lines() + 1) as usize
93+
}
94+
95+
pub fn lpi_lines(&self) -> usize {
96+
let intid = self.gicd.typer.id_bits();
97+
if intid <= 14 {
98+
return 0;
99+
}
100+
101+
1 << (self.gicd.typer.lpi_lines() + 1)
102+
}
103+
}

tmk/simple_tmk/src/aarch64/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![cfg(target_arch = "x86_64")]
2+
3+
mod gicv3;
4+
5+
use crate::prelude::*;

tmk/simple_tmk/src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
mod prelude;
1111

12+
mod aarch64;
1213
mod common;
1314
mod x86_64;
1415

tmk/tmk_core/src/aarch64.rs

+104
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,103 @@ mod entry {
1313
".weak _DYNAMIC",
1414
".hidden _DYNAMIC",
1515
".globl _start",
16+
17+
// Good only for the EL1
18+
" __exception_common:",
19+
20+
"str x29, [sp, #-16]!",
21+
"stp x27, x28, [sp, #-16]!",
22+
"stp x25, x26, [sp, #-16]!",
23+
"stp x23, x24, [sp, #-16]!",
24+
"stp x21, x22, [sp, #-16]!",
25+
"stp x19, x20, [sp, #-16]!",
26+
"stp x17, x18, [sp, #-16]!",
27+
"stp x15, x16, [sp, #-16]!",
28+
"stp x13, x14, [sp, #-16]!",
29+
"stp x11, x12, [sp, #-16]!",
30+
"stp x9, x10, [sp, #-16]!",
31+
"stp x7, x8, [sp, #-16]!",
32+
"stp x5, x6, [sp, #-16]!",
33+
"stp x3, x4, [sp, #-16]!",
34+
"stp x1, x2, [sp, #-16]!",
35+
36+
"add sp, sp, #-16",
37+
38+
"mrs x2, spsr_el1",
39+
"mrs x1, elr_el1",
40+
"stp x1, x2, [sp, #-16]!",
41+
42+
"str x0, [sp, #-16]!",
43+
44+
"mrs x2, tpidr_el1",
45+
"add x1, sp, #38*8",
46+
"stp x1, x2, [sp, #32]",
47+
48+
"mov x0, sp",
49+
"bl exception_handler",
50+
51+
"ldr x1, [sp, #40]",
52+
"msr tpidr_el1, x1",
53+
54+
"add sp, sp, #16",
55+
56+
"ldp x1, x2, [sp], #16",
57+
"msr elr_el1, x1",
58+
"msr spsr_el1, x2",
59+
60+
"add sp, sp, #16",
61+
62+
"ldp x1, x2, [sp], #16",
63+
"ldp x3, x4, [sp], #16",
64+
"ldp x5, x6, [sp], #16",
65+
"ldp x7, x8, [sp], #16",
66+
"ldp x9, x10, [sp], #16",
67+
"ldp x11, x12, [sp], #16",
68+
"ldp x13, x14, [sp], #16",
69+
"ldp x15, x16, [sp], #16",
70+
"ldp x17, x18, [sp], #16",
71+
"ldp x19, x20, [sp], #16",
72+
"ldp x21, x22, [sp], #16",
73+
"ldp x23, x24, [sp], #16",
74+
"ldp x25, x26, [sp], #16",
75+
"ldp x27, x28, [sp], #16",
76+
"ldr x29, [sp], #16",
77+
"ldp lr, x0, [sp], #16",
78+
79+
"eret",
80+
81+
".macro EXCEPTION_ENTRY source, kind",
82+
".align 7",
83+
" stp lr, x0, [sp, #-16]!",
84+
" mov x0, \\source",
85+
" movk x0, \\kind, lsl #16",
86+
" b __exception_common",
87+
".endm",
88+
89+
// Vector table must be aligned to a 2KB boundary
90+
".balign 0x800",
91+
" _vector_table_el1:",
92+
// Target and source at same exception level with source SP = SP_EL0
93+
" EXCEPTION_ENTRY #0x0, #0x0", // Synchronous exception
94+
" EXCEPTION_ENTRY #0x0, #0x1", // IRQ
95+
" EXCEPTION_ENTRY #0x0, #0x2", // FIQ
96+
" EXCEPTION_ENTRY #0x0, #0x3", // SError
97+
// Target and source at same exception level with source SP = SP_ELx
98+
" EXCEPTION_ENTRY #0x1, #0x0 // Synchronous exception",
99+
" EXCEPTION_ENTRY #0x1, #0x1 // IRQ",
100+
" EXCEPTION_ENTRY #0x1, #0x2 // FIQ",
101+
" EXCEPTION_ENTRY #0x1, #0x3 // SError",
102+
// Source is at lower exception level running on AArch64
103+
" EXCEPTION_ENTRY #0x2, #0x0", // Synchronous exception
104+
" EXCEPTION_ENTRY #0x2, #0x1", // IRQ
105+
" EXCEPTION_ENTRY #0x2, #0x2", // FIQ
106+
" EXCEPTION_ENTRY #0x2, #0x3", // SError
107+
// Source is at lower exception level running on AArch32
108+
" EXCEPTION_ENTRY #0x3, #0x0", // Synchronous exception
109+
" EXCEPTION_ENTRY #0x3, #0x1", // IRQ
110+
" EXCEPTION_ENTRY #0x3, #0x2", // FIQ
111+
" EXCEPTION_ENTRY #0x3, #0x3", // SError
112+
16113
"_start:",
17114
"mov x19, x0",
18115
"adrp x1, {stack}",
@@ -27,6 +124,12 @@ mod entry {
27124
"msr CPACR_EL1, x0",
28125
"isb",
29126

127+
// Set up the vector table.
128+
"adrp x3, _vector_table_el1,
129+
"add x3, x3, :lo12:_vector_table_el1,
130+
"msr VBAR_EL1, x3,
131+
"isb,
132+
30133
"adrp x0, __ehdr_start",
31134
"add x0, x0, :lo12:__ehdr_start",
32135
"mov x1, x0",
@@ -35,6 +138,7 @@ mod entry {
35138
"bl {relocate}",
36139
"mov x0, x19",
37140
"b {entry}",
141+
38142
relocate = sym minimal_rt::reloc::relocate,
39143
stack = sym STACK,
40144
entry = sym crate::entry,

vm/aarch64/aarch64defs/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ rust-version.workspace = true
88

99
[dependencies]
1010
open_enum.workspace = true
11+
static_assertions.workspace = true
1112

1213
bitfield-struct.workspace = true
1314
zerocopy.workspace = true

0 commit comments

Comments
 (0)