forked from M-Labs/artiq-zynq
66 lines
1.6 KiB
Rust
66 lines
1.6 KiB
Rust
#![no_std]
|
|
#![no_main]
|
|
|
|
extern crate log;
|
|
|
|
use core::mem;
|
|
use log::{info, error};
|
|
use cstr_core::CStr;
|
|
|
|
use libboard_zynq::{
|
|
self as zynq, clocks::Clocks, clocks::source::{ClockSource, ArmPll, IoPll},
|
|
timer::GlobalTimer,
|
|
};
|
|
use libsupport_zynq::{boot, logger};
|
|
|
|
|
|
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) {
|
|
error!("LZMA error: {}", unsafe { CStr::from_ptr(message) }.to_str().unwrap());
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub fn main_core0() {
|
|
GlobalTimer::start();
|
|
let _ = logger::init();
|
|
log::set_max_level(log::LevelFilter::Debug);
|
|
info!("Simple Zynq Loader starting");
|
|
|
|
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::new();
|
|
|
|
let payload = include_bytes!(concat!(env!("OUT_DIR"), "/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 {
|
|
boot::Core1::start();
|
|
info!("executing payload");
|
|
unsafe {
|
|
(mem::transmute::<*mut u8, fn()>(ddr.ptr::<u8>()))();
|
|
}
|
|
}
|
|
|
|
loop {}
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub fn main_core1() {
|
|
unsafe {
|
|
(mem::transmute::<u32, fn()>(0x00100000))();
|
|
}
|
|
}
|