mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-08 04:56:43 +00:00
add some preliminary bits for the loader to detect suspend/resume
This commit is contained in:
parent
2df2e654dd
commit
805d7c79a2
3 changed files with 145 additions and 2 deletions
|
|
@ -6,6 +6,7 @@ edition = "2018"
|
|||
description = "Initial kernel loader for Xous"
|
||||
|
||||
[dependencies]
|
||||
utralib = {path = "../utralib"}
|
||||
|
||||
[dev-dependencies]
|
||||
lazy_static = "1.4.0"
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
mod args;
|
||||
use args::{KernelArgument, KernelArguments};
|
||||
|
||||
mod murmur3;
|
||||
|
||||
use core::num::NonZeroUsize;
|
||||
use core::{mem, ptr, slice};
|
||||
|
||||
|
|
@ -1072,8 +1074,22 @@ fn boot_sequence(args: KernelArguments, _signature: u32) -> ! {
|
|||
};
|
||||
read_initial_config(&mut cfg);
|
||||
|
||||
phase_1(&mut cfg);
|
||||
phase_2(&mut cfg);
|
||||
if !check_resume(&mut cfg) {
|
||||
phase_1(&mut cfg);
|
||||
phase_2(&mut cfg);
|
||||
} else {
|
||||
use utralib::generated::*;
|
||||
// setup for a resume
|
||||
let mut resume_csr = CSR::new(utra::susres::HW_SUSRES_BASE as *mut u32);
|
||||
// set the resume marker for the SUSRES server
|
||||
resume_csr.wfo(utra::susres::STATE_RESUME, 1);
|
||||
resume_csr.wfo(utra::susres::CONTROL_PAUSE, 1); // ensure that the ticktimer is paused before resuming
|
||||
|
||||
// set the resume marker for the early kernel init
|
||||
///////////TODO
|
||||
|
||||
// SATP restore is handled by the `start_kernel` assembly pre-amble
|
||||
}
|
||||
|
||||
println!("Font maps located as follows:");
|
||||
println!(" Hanzi @ {:08x}", fonts::hanzi::DATA_HANZI.as_ptr() as u32);
|
||||
|
|
@ -1110,6 +1126,45 @@ fn boot_sequence(args: KernelArguments, _signature: u32) -> ! {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_resume(cfg: &mut BootConfig) -> bool {
|
||||
use utralib::generated::*;
|
||||
const WORDS_PER_SECTOR: usize = 127;
|
||||
const NUM_SECTORS: usize = 8;
|
||||
const WORDS_PER_PAGE: usize = PAGE_SIZE / 4;
|
||||
|
||||
let suspend_marker = cfg.sram_start as usize + cfg.sram_size - PAGE_SIZE * 2;
|
||||
let marker: *mut[u32; WORDS_PER_PAGE] = suspend_marker as *mut[u32; WORDS_PER_PAGE];
|
||||
|
||||
let boot_seed = CSR::new(utra::seed::HW_SEED_BASE as *mut u32);
|
||||
let seed0 = boot_seed.r(utra::seed::SEED0);
|
||||
let seed1 = boot_seed.r(utra::seed::SEED1);
|
||||
let was_forced_suspend: bool = if unsafe{(*marker)[0]} != 0 { true } else { false };
|
||||
|
||||
let mut clean = true;
|
||||
let mut hashbuf: [u32; WORDS_PER_SECTOR] = [0; WORDS_PER_SECTOR];
|
||||
let mut index: usize = 0;
|
||||
for sector in 0..NUM_SECTORS {
|
||||
for i in 0..hashbuf.len() {
|
||||
hashbuf[i] = unsafe{(*marker)[index * (WORDS_PER_SECTOR + 1) + i]};
|
||||
}
|
||||
// sector 0 contains the boot seeds, which we replace with our own as read out from our FPGA before computing the hash
|
||||
if sector == 0 {
|
||||
hashbuf[1] = seed0;
|
||||
hashbuf[2] = seed1;
|
||||
}
|
||||
let hash = crate::murmur3::murmur3_32(&hashbuf, 0);
|
||||
if hash != unsafe{(*marker)[index * (WORDS_PER_SECTOR) + 1]} {
|
||||
clean = false;
|
||||
}
|
||||
}
|
||||
// zero out the clean suspend marker, so if something goes wrong during resume we don't try to resume again
|
||||
for i in 0..WORDS_PER_PAGE {
|
||||
unsafe{(*marker)[i] = 0;}
|
||||
}
|
||||
|
||||
clean
|
||||
}
|
||||
|
||||
fn phase_1(cfg: &mut BootConfig) {
|
||||
// Allocate space for the stack pointer.
|
||||
// The bootloader should have placed the stack pointer at the end of RAM
|
||||
|
|
|
|||
87
loader/src/murmur3.rs
Normal file
87
loader/src/murmur3.rs
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright (c) 2020 Stu Small
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0
|
||||
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
|
||||
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. All files in the project carrying such notice may not be copied,
|
||||
// modified, or distributed except according to those terms.
|
||||
|
||||
|
||||
// This murmur3 code was vendored in on April 28, 2021. We choose to vendor the code for this simple
|
||||
// non-cryptographic hash in to reduce the number of crate dependencies in the build system. See
|
||||
// https://github.com/betrusted-io/xous-core/issues/54 for more details on why.
|
||||
// It also allowed us to adapt the code for our specific no_std needs.
|
||||
|
||||
const C1: u32 = 0x85eb_ca6b;
|
||||
const C2: u32 = 0xc2b2_ae35;
|
||||
const R1: u32 = 16;
|
||||
const R2: u32 = 13;
|
||||
const M: u32 = 5;
|
||||
const N: u32 = 0xe654_6b64;
|
||||
|
||||
pub fn murmur3_32(source: &[u32], seed: u32) -> u32 {
|
||||
let mut processed = 0;
|
||||
let mut state = seed;
|
||||
|
||||
for &k in source.iter() {
|
||||
processed += 4;
|
||||
state ^= calc_k(k);
|
||||
state = state.rotate_left(R2);
|
||||
state = (state.wrapping_mul(M)).wrapping_add(N);
|
||||
}
|
||||
finish(state, processed)
|
||||
}
|
||||
|
||||
fn finish(state: u32, processed: u32) -> u32 {
|
||||
let mut hash = state;
|
||||
hash ^= processed as u32;
|
||||
hash ^= hash.wrapping_shr(R1);
|
||||
hash = hash.wrapping_mul(C1);
|
||||
hash ^= hash.wrapping_shr(R2);
|
||||
hash = hash.wrapping_mul(C2);
|
||||
hash ^= hash.wrapping_shr(R1);
|
||||
hash
|
||||
}
|
||||
|
||||
fn calc_k(k: u32) -> u32 {
|
||||
const C1: u32 = 0xcc9e_2d51;
|
||||
const C2: u32 = 0x1b87_3593;
|
||||
const R1: u32 = 15;
|
||||
k.wrapping_mul(C1).rotate_left(R1).wrapping_mul(C2)
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
struct Result {
|
||||
slice: &'static [u32],
|
||||
hash_32: u32,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_static_slices() {
|
||||
let tests = [
|
||||
Result {
|
||||
slice: &[0x34333231], //"1234",
|
||||
hash_32: 0x721c5dc3,
|
||||
},
|
||||
Result {
|
||||
slice: &[0x34333231, 0x38373635], // "12345678",
|
||||
hash_32: 0x91b313ce,
|
||||
},
|
||||
Result {
|
||||
slice: &[],
|
||||
hash_32: 0,
|
||||
},
|
||||
];
|
||||
|
||||
for test in &tests {
|
||||
assert_eq!(
|
||||
murmur3_32(test.slice, 0),
|
||||
test.hash_32,
|
||||
"Failed on slice {:x?}", test.slice
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue