blob: 8710c49da8085ee4adeedc55fd98a20136b36eda [file] [log] [blame]
David Brazdil66fc1202022-07-04 21:48:45 +01001// 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//! Project Rialto main source file.
16
17#![no_main]
18#![no_std]
19#![feature(default_alloc_error_handler)]
20
21mod exceptions;
22
23extern crate alloc;
David Brazdil66fc1202022-07-04 21:48:45 +010024
25use aarch64_paging::{
26 idmap::IdMap,
27 paging::{Attributes, MemoryRegion},
28 AddressRangeError,
29};
30use buddy_system_allocator::LockedHeap;
31use log::{debug, info};
32use vmbase::main;
33
34const SZ_1K: usize = 1024;
35const SZ_64K: usize = 64 * SZ_1K;
36const SZ_1M: usize = 1024 * SZ_1K;
37const SZ_1G: usize = 1024 * SZ_1M;
38
39// Root level is given by the value of TCR_EL1.TG0 and TCR_EL1.T0SZ, set in
40// entry.S. For 4KB granule and 39-bit VA, the root level is 1.
41const PT_ROOT_LEVEL: usize = 1;
42const PT_ASID: usize = 1;
43
David Brazdil6629b6e2022-07-09 22:48:49 +010044const PROT_DEV: Attributes = Attributes::from_bits_truncate(
45 Attributes::DEVICE_NGNRE.bits() | Attributes::EXECUTE_NEVER.bits(),
46);
47const PROT_RX: Attributes = Attributes::from_bits_truncate(
48 Attributes::NORMAL.bits() | Attributes::NON_GLOBAL.bits() | Attributes::READ_ONLY.bits(),
49);
50const PROT_RO: Attributes = Attributes::from_bits_truncate(
51 Attributes::NORMAL.bits()
52 | Attributes::NON_GLOBAL.bits()
53 | Attributes::READ_ONLY.bits()
54 | Attributes::EXECUTE_NEVER.bits(),
55);
56const PROT_RW: Attributes = Attributes::from_bits_truncate(
57 Attributes::NORMAL.bits() | Attributes::NON_GLOBAL.bits() | Attributes::EXECUTE_NEVER.bits(),
58);
59
David Brazdil66fc1202022-07-04 21:48:45 +010060#[global_allocator]
61static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::<32>::new();
62
63static mut HEAP: [u8; SZ_64K] = [0; SZ_64K];
64
65unsafe fn kimg_ptr(sym: &u8) -> *const u8 {
66 sym as *const u8
67}
68
69unsafe fn kimg_addr(sym: &u8) -> usize {
70 kimg_ptr(sym) as usize
71}
72
73unsafe fn kimg_region(begin: &u8, end: &u8) -> MemoryRegion {
74 MemoryRegion::new(kimg_addr(begin), kimg_addr(end))
75}
76
77fn init_heap() {
78 // SAFETY: Allocator set to otherwise unused, static memory.
79 unsafe {
80 HEAP_ALLOCATOR.lock().init(&mut HEAP as *mut u8 as usize, HEAP.len());
81 }
82 info!("Initialized heap.");
83}
84
85fn init_kernel_pgt(pgt: &mut IdMap) -> Result<(), AddressRangeError> {
86 // The first 1 GiB of address space is used by crosvm for MMIO.
87 let reg_dev = MemoryRegion::new(0, SZ_1G);
88 // SAFETY: Taking addresses of kernel image sections to set up page table
89 // mappings. Not taking ownerhip of the memory.
90 let reg_text = unsafe { kimg_region(&text_begin, &text_end) };
91 let reg_rodata = unsafe { kimg_region(&rodata_begin, &rodata_end) };
92 let reg_data = unsafe { kimg_region(&data_begin, &boot_stack_end) };
93
David Brazdil6629b6e2022-07-09 22:48:49 +010094 debug!("Preparing kernel page table.");
David Brazdil66fc1202022-07-04 21:48:45 +010095 debug!(" dev: {}-{}", reg_dev.start(), reg_dev.end());
96 debug!(" text: {}-{}", reg_text.start(), reg_text.end());
97 debug!(" rodata: {}-{}", reg_rodata.start(), reg_rodata.end());
98 debug!(" data: {}-{}", reg_data.start(), reg_data.end());
99
David Brazdil6629b6e2022-07-09 22:48:49 +0100100 pgt.map_range(&reg_dev, PROT_DEV)?;
101 pgt.map_range(&reg_text, PROT_RX)?;
102 pgt.map_range(&reg_rodata, PROT_RO)?;
103 pgt.map_range(&reg_data, PROT_RW)?;
David Brazdil66fc1202022-07-04 21:48:45 +0100104
David Brazdil66fc1202022-07-04 21:48:45 +0100105 pgt.activate();
106 info!("Activated kernel page table.");
David Brazdilb6463c92022-07-11 15:50:43 +0100107 Ok(())
David Brazdil66fc1202022-07-04 21:48:45 +0100108}
109
110/// Entry point for Rialto.
111pub fn main(_a0: u64, _a1: u64, _a2: u64, _a3: u64) {
112 vmbase::logger::init(log::LevelFilter::Debug).unwrap();
113
114 info!("Welcome to Rialto!");
115 init_heap();
116
117 let mut pgt = IdMap::new(PT_ASID, PT_ROOT_LEVEL);
118 init_kernel_pgt(&mut pgt).unwrap();
David Brazdil66fc1202022-07-04 21:48:45 +0100119}
120
121extern "C" {
122 static text_begin: u8;
123 static text_end: u8;
124 static rodata_begin: u8;
125 static rodata_end: u8;
126 static data_begin: u8;
127 static boot_stack_end: u8;
128}
129
130main!(main);