#![no_std] #![no_main] #![feature(panic_info_message)] extern crate log; use core::mem; use log::{debug, info, error}; use cstr_core::CStr; use libcortex_a9::{ enable_fpu, l2c::enable_l2_cache, cache::{dcciall, iciallu, bpiall}, asm::{dsb, isb}, }; use libboard_zynq::{ self as zynq, println, clocks::Clocks, clocks::source::{ClockSource, ArmPll, IoPll}, stdio, logger, timer::GlobalTimer, }; use libsupport_zynq as _; extern "C" { fn unlzma_simple(buf: *const u8, in_len: i32, output: *mut u8, error: extern fn(*const u8)) -> i32; } extern fn lzma_error(message: *const u8) { let msg = unsafe {CStr::from_ptr(message)}.to_str(); if let Ok(msg) = msg { println!("LZMA error: {}", msg); } } #[panic_handler] fn panic(_: &core::panic::PanicInfo) -> ! { stdio::drop_uart(); println!("panicked!"); loop {} } #[no_mangle] pub fn main_core0() { GlobalTimer::start(); enable_fpu(); logger::init().unwrap(); log::set_max_level(log::LevelFilter::Debug); println!(r#" __________ __ / ___/__ / / / \__ \ / / / / ___/ / / /__/ /___ /____/ /____/_____/ (C) 2020 M-Labs "#); info!("Simple Zynq Loader starting..."); enable_l2_cache(); debug!("FPU enabled on Core0"); const CPU_FREQ: u32 = 800_000_000; ArmPll::setup(2 * CPU_FREQ); Clocks::set_cpu_freq(CPU_FREQ); IoPll::setup(1_000_000_000); libboard_zynq::stdio::drop_uart(); // reinitialize UART after clocking change let mut ddr = zynq::ddr::DdrRam::ddrram(); let payload = include_bytes!("../../../build/szl-payload.bin.lzma"); info!("decompressing payload"); let result = unsafe { unlzma_simple(payload.as_ptr(), payload.len() as i32, ddr.ptr(), lzma_error) }; if result < 0 { error!("decompression failed"); } else { // Flush data cache entries for all of L1 cache, including // Memory/Instruction Synchronization Barriers dcciall(); iciallu(); bpiall(); dsb(); isb(); // Start core0 only, for compatibility with FSBL. info!("executing payload"); unsafe { (mem::transmute::<*mut u8, fn()>(ddr.ptr::()))(); } } loop {} } #[no_mangle] pub fn main_core1() { panic!("core1 started but should not have"); }