use std::{io::Write, path::PathBuf};
use quote::quote;
const MB: usize = 1024 * 1024;
const DEFAULT_KERNEL_STACK_SIZE: usize = 2 * MB;
fn main() {
println!("cargo::rustc-check-cfg=cfg(addr_bits, values(\"39\", \"48\", \"57\", \"64\"))");
let mut addr_bits = 48usize;
let mut page_levels = 4usize;
let mut page_size = 0x1000usize;
if std::env::var("CARGO_FEATURE_PAGE16K").is_ok() {
page_size = 0x4000;
}
let stack_size = DEFAULT_KERNEL_STACK_SIZE;
if std::env::var("CARGO_FEATURE_SV39").is_ok() {
addr_bits = 39;
page_levels = 3;
}
let mut addr_base: usize = !((1 << addr_bits) - 1);
let mut kernel_load_vaddr = addr_base + (1 << addr_bits) / 16 * 15 + 0x200000;
if std::env::var("CARGO_FEATURE_SPACE_LO").is_ok() {
addr_base = 0;
kernel_load_vaddr = (1 << addr_bits) / 16 * 15 + 0x200000;
}
let const_content = quote! {
pub const ADDR_BASE: usize = #addr_base;
pub const ADDR_BITS: usize = #addr_bits;
pub const PAGE_LEVELS: usize = #page_levels;
pub const KERNEL_LOAD_VADDR: usize = #kernel_load_vaddr;
pub const PAGE_SIZE: usize = #page_size;
pub const STACK_SIZE: usize = #stack_size;
};
let mut file =
std::fs::File::create(out_dir().join("constant.rs")).expect("constant.rs create failed");
let syntax_tree = syn::parse2(const_content).unwrap();
let formatted = prettyplease::unparse(&syntax_tree);
file.write_all(formatted.as_bytes()).unwrap();
println!("cargo:rerun-if-changed=memory.ld");
println!("cargo:rustc-link-search={}", out_dir().display());
let content = include_str!("memory.ld");
let content = content.replace("${VCODE}", &format!("{kernel_load_vaddr:#x}"));
let content = content.replace("${KERNAL_LOAD_VMA}", &format!("{kernel_load_vaddr:#x}"));
let content = content.replace("${PAGE_SIZE}", &format!("{page_size:#x}"));
let mut file = std::fs::File::create(out_dir().join("kmem_region.x"))
.expect("kmem_region.x create failed");
file.write_all(content.as_bytes())
.expect("kmem_region.x write failed");
}
fn out_dir() -> PathBuf {
PathBuf::from(std::env::var("OUT_DIR").unwrap())
}