1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
| // Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0
#![no_main]
#![no_std]
mod exceptions;
mod logger;
use aarch64_paging::descriptor::El1Attributes;
use aarch64_rt::{InitialPagetable, entry, initial_pagetable};
use arm_gic::gicv3::registers::{Gicd, GicrSgi};
use arm_gic::gicv3::{GicCpuInterface, GicV3};
use arm_pl011_uart::{PL011Registers, Uart};
use core::panic::PanicInfo;
use core::ptr::NonNull;
use log::{LevelFilter, error, info, trace};
use safe_mmio::UniqueMmioPointer;
use smccc::Hvc;
use smccc::psci::system_off;
/// GICv3 的基地址。
const GICD_BASE_ADDRESS: NonNull<Gicd> = NonNull::new(0x800_0000 as _).unwrap();
const GICR_BASE_ADDRESS: NonNull<GicrSgi> = NonNull::new(0x80A_0000 as _).unwrap();
/// 主 PL011 UART 的基地址。
const PL011_BASE_ADDRESS: NonNull<PL011Registers> =
NonNull::new(0x900_0000 as _).unwrap();
/// 初始 identity map 中设备内存使用的属性。
const DEVICE_ATTRIBUTES: El1Attributes = El1Attributes::VALID
.union(El1Attributes::ATTRIBUTE_INDEX_0)
.union(El1Attributes::ACCESSED)
.union(El1Attributes::UXN);
/// 初始 identity map 中普通内存使用的属性。
const MEMORY_ATTRIBUTES: El1Attributes = El1Attributes::VALID
.union(El1Attributes::ATTRIBUTE_INDEX_1)
.union(El1Attributes::INNER_SHAREABLE)
.union(El1Attributes::ACCESSED)
.union(El1Attributes::NON_GLOBAL);
initial_pagetable!({
let mut idmap = [0; 512];
// 1 GiB 设备内存。
idmap[0] = DEVICE_ATTRIBUTES.bits();
// 1 GiB 普通内存。
idmap[1] = MEMORY_ATTRIBUTES.bits() | 0x40000000;
// 从 256 GiB 起另有 1 GiB 设备内存。
idmap[256] = DEVICE_ATTRIBUTES.bits() | 0x4000000000;
InitialPagetable(idmap)
});
entry!(main);
fn main(x0: u64, x1: u64, x2: u64, x3: u64) -> ! {
// SAFETY: `PL011_BASE_ADDRESS` 是 PL011 设备的基地址,且没有其他代码访问该地址范围。
let uart = unsafe { Uart::new(UniqueMmioPointer::new(PL011_BASE_ADDRESS)) };
logger::init(uart, LevelFilter::Trace).unwrap();
info!("main({:#x}, {:#x}, {:#x}, {:#x})", x0, x1, x2, x3);
// SAFETY: `GICD_BASE_ADDRESS` 与 `GICR_BASE_ADDRESS` 分别是 GICv3 distributor 与 redistributor 的基地址,且没有其他代码访问这些地址范围。
let mut gic = unsafe {
GicV3::new(
UniqueMmioPointer::new(GICD_BASE_ADDRESS),
GICR_BASE_ADDRESS,
1,
false,
)
};
gic.setup(0);
// TODO:创建 RTC 驱动实例并打印当前时间。
// TODO:等待 3 秒。
system_off::<Hvc>().unwrap();
panic!("system_off returned");
}
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
error!("{info}");
system_off::<Hvc>().unwrap();
loop {}
}
|