blob: 03f0603c2e7fb34bd1dc73a1ab6d6576f15b8b62 [file] [log] [blame]
Andrew Walbraneef98202022-04-27 16:23:06 +00001// Copyright 2022, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! VM bootloader example.
16
17#![no_main]
18#![no_std]
Andrew Walbranf7b6dc82022-04-20 16:24:30 +000019#![feature(default_alloc_error_handler)]
Andrew Walbraneef98202022-04-27 16:23:06 +000020
21mod exceptions;
Andrew Walbran153aad92022-06-28 15:51:13 +000022mod layout;
Andrew Walbraneef98202022-04-27 16:23:06 +000023
Andrew Walbranf7b6dc82022-04-20 16:24:30 +000024extern crate alloc;
25
Andrew Walbran153aad92022-06-28 15:51:13 +000026use crate::layout::{
David Brazdila51c6f02022-10-12 09:51:48 +000027 bionic_tls, dtb_range, print_addresses, rodata_range, stack_chk_guard, text_range,
28 writable_region, DEVICE_REGION,
Andrew Walbran13564542022-04-20 16:29:45 +000029};
Andrew Walbran153aad92022-06-28 15:51:13 +000030use aarch64_paging::{idmap::IdMap, paging::Attributes};
Andrew Walbranf7b6dc82022-04-20 16:24:30 +000031use alloc::{vec, vec::Vec};
32use buddy_system_allocator::LockedHeap;
David Brazdilb41aa8f2022-07-05 12:41:00 +010033use log::{info, LevelFilter};
34use vmbase::{logger, main, println};
Andrew Walbraneef98202022-04-27 16:23:06 +000035
Andrew Walbran5d4e1c92022-04-12 14:30:54 +000036static INITIALISED_DATA: [u32; 4] = [1, 2, 3, 4];
37static mut ZEROED_DATA: [u32; 10] = [0; 10];
38static mut MUTABLE_DATA: [u32; 4] = [1, 2, 3, 4];
39
Andrew Walbran13564542022-04-20 16:29:45 +000040const ASID: usize = 1;
41const ROOT_LEVEL: usize = 1;
42
Andrew Walbranf7b6dc82022-04-20 16:24:30 +000043#[global_allocator]
44static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::<32>::new();
45
46static mut HEAP: [u8; 65536] = [0; 65536];
47
Andrew Walbraneef98202022-04-27 16:23:06 +000048main!(main);
49
50/// Entry point for VM bootloader.
Andrew Walbrane03395a2022-04-29 15:15:49 +000051pub fn main(arg0: u64, arg1: u64, arg2: u64, arg3: u64) {
David Brazdilb41aa8f2022-07-05 12:41:00 +010052 logger::init(LevelFilter::Debug).unwrap();
53
Andrew Walbraneef98202022-04-27 16:23:06 +000054 println!("Hello world");
David Brazdilb41aa8f2022-07-05 12:41:00 +010055 info!("x0={:#018x}, x1={:#018x}, x2={:#018x}, x3={:#018x}", arg0, arg1, arg2, arg3);
Andrew Walbran6261cf42022-04-12 13:26:52 +000056 print_addresses();
Andrew Walbran153aad92022-06-28 15:51:13 +000057 assert_eq!(arg0, dtb_range().start.0 as u64);
Andrew Walbran5d4e1c92022-04-12 14:30:54 +000058 check_data();
David Brazdila51c6f02022-10-12 09:51:48 +000059 check_stack_guard();
Andrew Walbranf7b6dc82022-04-20 16:24:30 +000060
61 unsafe {
Pierre-Clément Tosi581e9b62022-10-27 16:21:13 +010062 HEAP_ALLOCATOR.lock().init(HEAP.as_mut_ptr() as usize, HEAP.len());
Andrew Walbranf7b6dc82022-04-20 16:24:30 +000063 }
64
65 check_alloc();
Andrew Walbran13564542022-04-20 16:29:45 +000066
67 let mut idmap = IdMap::new(ASID, ROOT_LEVEL);
68 idmap.map_range(&DEVICE_REGION, Attributes::DEVICE_NGNRE | Attributes::EXECUTE_NEVER).unwrap();
69 idmap
70 .map_range(
Andrew Walbran153aad92022-06-28 15:51:13 +000071 &text_range().into(),
Andrew Walbran13564542022-04-20 16:29:45 +000072 Attributes::NORMAL | Attributes::NON_GLOBAL | Attributes::READ_ONLY,
73 )
74 .unwrap();
75 idmap
76 .map_range(
Andrew Walbran153aad92022-06-28 15:51:13 +000077 &rodata_range().into(),
Andrew Walbran13564542022-04-20 16:29:45 +000078 Attributes::NORMAL
79 | Attributes::NON_GLOBAL
80 | Attributes::READ_ONLY
81 | Attributes::EXECUTE_NEVER,
82 )
83 .unwrap();
84 idmap
85 .map_range(
86 &writable_region(),
87 Attributes::NORMAL | Attributes::NON_GLOBAL | Attributes::EXECUTE_NEVER,
88 )
89 .unwrap();
90
David Brazdilb41aa8f2022-07-05 12:41:00 +010091 info!("Activating IdMap...");
92 info!("{:?}", idmap);
Andrew Walbran13564542022-04-20 16:29:45 +000093 idmap.activate();
David Brazdilb41aa8f2022-07-05 12:41:00 +010094 info!("Activated.");
Andrew Walbran13564542022-04-20 16:29:45 +000095
96 check_data();
David Brazdil9a83e612022-09-27 17:38:10 +000097 check_dice();
Andrew Walbran13564542022-04-20 16:29:45 +000098}
99
David Brazdila51c6f02022-10-12 09:51:48 +0000100fn check_stack_guard() {
101 const BIONIC_TLS_STACK_GRD_OFF: usize = 40;
102
103 info!("Testing stack guard");
104 assert_eq!(bionic_tls(BIONIC_TLS_STACK_GRD_OFF), stack_chk_guard());
105}
106
Andrew Walbran5d4e1c92022-04-12 14:30:54 +0000107fn check_data() {
Pierre-Clément Tosi581e9b62022-10-27 16:21:13 +0100108 info!("INITIALISED_DATA: {:?}", INITIALISED_DATA.as_ptr());
Andrew Walbran5d4e1c92022-04-12 14:30:54 +0000109 unsafe {
Pierre-Clément Tosi581e9b62022-10-27 16:21:13 +0100110 info!("ZEROED_DATA: {:?}", ZEROED_DATA.as_ptr());
111 info!("MUTABLE_DATA: {:?}", MUTABLE_DATA.as_ptr());
112 info!("HEAP: {:?}", HEAP.as_ptr());
Andrew Walbran5d4e1c92022-04-12 14:30:54 +0000113 }
114
115 assert_eq!(INITIALISED_DATA[0], 1);
116 assert_eq!(INITIALISED_DATA[1], 2);
117 assert_eq!(INITIALISED_DATA[2], 3);
118 assert_eq!(INITIALISED_DATA[3], 4);
119
120 unsafe {
121 for element in ZEROED_DATA.iter() {
122 assert_eq!(*element, 0);
123 }
124 ZEROED_DATA[0] = 13;
125 assert_eq!(ZEROED_DATA[0], 13);
126 ZEROED_DATA[0] = 0;
127 assert_eq!(ZEROED_DATA[0], 0);
128
129 assert_eq!(MUTABLE_DATA[0], 1);
130 assert_eq!(MUTABLE_DATA[1], 2);
131 assert_eq!(MUTABLE_DATA[2], 3);
132 assert_eq!(MUTABLE_DATA[3], 4);
133 MUTABLE_DATA[0] += 41;
134 assert_eq!(MUTABLE_DATA[0], 42);
Andrew Walbran13564542022-04-20 16:29:45 +0000135 MUTABLE_DATA[0] -= 41;
136 assert_eq!(MUTABLE_DATA[0], 1);
Andrew Walbran5d4e1c92022-04-12 14:30:54 +0000137 }
David Brazdilb41aa8f2022-07-05 12:41:00 +0100138 info!("Data looks good");
Andrew Walbran5d4e1c92022-04-12 14:30:54 +0000139}
140
Andrew Walbranf7b6dc82022-04-20 16:24:30 +0000141fn check_alloc() {
David Brazdilb41aa8f2022-07-05 12:41:00 +0100142 info!("Allocating a Vec...");
Andrew Walbranf7b6dc82022-04-20 16:24:30 +0000143 let mut vector: Vec<u32> = vec![1, 2, 3, 4];
144 assert_eq!(vector[0], 1);
145 assert_eq!(vector[1], 2);
146 assert_eq!(vector[2], 3);
147 assert_eq!(vector[3], 4);
148 vector[2] = 42;
149 assert_eq!(vector[2], 42);
David Brazdilb41aa8f2022-07-05 12:41:00 +0100150 info!("Vec seems to work.");
Andrew Walbranf7b6dc82022-04-20 16:24:30 +0000151}
David Brazdil9a83e612022-09-27 17:38:10 +0000152
153fn check_dice() {
154 info!("Testing DICE integration...");
155 let hash = dice::hash("hello world".as_bytes()).expect("DiceHash failed");
156 assert_eq!(
157 hash,
158 [
159 0x30, 0x9e, 0xcc, 0x48, 0x9c, 0x12, 0xd6, 0xeb, 0x4c, 0xc4, 0x0f, 0x50, 0xc9, 0x02,
160 0xf2, 0xb4, 0xd0, 0xed, 0x77, 0xee, 0x51, 0x1a, 0x7c, 0x7a, 0x9b, 0xcd, 0x3c, 0xa8,
161 0x6d, 0x4c, 0xd8, 0x6f, 0x98, 0x9d, 0xd3, 0x5b, 0xc5, 0xff, 0x49, 0x96, 0x70, 0xda,
162 0x34, 0x25, 0x5b, 0x45, 0xb0, 0xcf, 0xd8, 0x30, 0xe8, 0x1f, 0x60, 0x5d, 0xcf, 0x7d,
163 0xc5, 0x54, 0x2e, 0x93, 0xae, 0x9c, 0xd7, 0x6f
164 ]
165 );
166}