99 lines
2.8 KiB
Rust
99 lines
2.8 KiB
Rust
use std::{
|
|
env, fs,
|
|
io::{self, Write},
|
|
path::{Path, PathBuf},
|
|
process::Command,
|
|
};
|
|
|
|
use abi_generator::{
|
|
abi::{ty::TypeWidth, AbiBuilder},
|
|
syntax::UnwrapFancy,
|
|
TargetEnv,
|
|
};
|
|
|
|
fn build_x86_64() {
|
|
const DEFAULT_8086_AS: &str = "nasm";
|
|
const AP_BOOTSTRAP_S: &str = "src/arch/x86_64/boot/ap_boot.S";
|
|
|
|
println!("cargo:rerun-if-changed={}", AP_BOOTSTRAP_S);
|
|
|
|
let out_dir = env::var("OUT_DIR").unwrap();
|
|
let assembler = env::var("AS8086").unwrap_or(DEFAULT_8086_AS.to_owned());
|
|
|
|
let ap_bootstrap_out = PathBuf::from(out_dir).join("__x86_64_ap_boot.bin");
|
|
|
|
// Assemble the code
|
|
let output = Command::new(assembler.as_str())
|
|
.args([
|
|
"-fbin",
|
|
"-o",
|
|
ap_bootstrap_out.to_str().unwrap(),
|
|
AP_BOOTSTRAP_S,
|
|
])
|
|
.output()
|
|
.unwrap();
|
|
|
|
if !output.status.success() {
|
|
io::stderr().write_all(&output.stderr).ok();
|
|
panic!("{}: could not assemble {}", assembler, AP_BOOTSTRAP_S);
|
|
}
|
|
}
|
|
|
|
fn load_abi_definitions<P: AsRef<Path>>(path: P) -> String {
|
|
let mut content = String::new();
|
|
for file in fs::read_dir(path).unwrap() {
|
|
let file = file.unwrap();
|
|
if file.path().extension().map(|x| x == "abi").unwrap_or(false) {
|
|
println!("cargo:rerun-if-changed={}", file.path().display());
|
|
content.extend(fs::read_to_string(file.path()));
|
|
}
|
|
}
|
|
content
|
|
}
|
|
|
|
fn generate_syscall_dispatcher<A: AsRef<Path>, P: AsRef<Path>>(
|
|
target_is_64bit: bool,
|
|
abi_path: A,
|
|
out_dir: P,
|
|
) {
|
|
let target_env = if target_is_64bit {
|
|
TargetEnv {
|
|
thin_pointer_width: TypeWidth::U64,
|
|
fat_pointer_width: TypeWidth::U128,
|
|
}
|
|
} else {
|
|
TargetEnv {
|
|
thin_pointer_width: TypeWidth::U32,
|
|
fat_pointer_width: TypeWidth::U64,
|
|
}
|
|
};
|
|
let abi = load_abi_definitions(abi_path);
|
|
let abi: AbiBuilder = AbiBuilder::from_string(&abi, target_env).unwrap_fancy(&abi);
|
|
|
|
let generated_dispatcher = out_dir.as_ref().join("generated_dispatcher.rs");
|
|
let file = prettyplease::unparse(
|
|
&abi.emit_syscall_dispatcher("handle_syscall", "imp")
|
|
.expect("Could not generate syscall dispatcher"),
|
|
);
|
|
|
|
fs::write(generated_dispatcher, file.as_bytes()).unwrap();
|
|
}
|
|
|
|
fn main() {
|
|
let out_dir = env::var("OUT_DIR").unwrap();
|
|
let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
|
|
let target_is_64bit = env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap() == "64";
|
|
|
|
generate_syscall_dispatcher(target_is_64bit, "../lib/abi/def", out_dir);
|
|
|
|
println!("cargo:rerun-if-changed=build.rs");
|
|
|
|
match arch.as_str() {
|
|
"x86" => (),
|
|
"x86_64" => build_x86_64(),
|
|
"aarch64" => (),
|
|
"riscv64" => (),
|
|
_ => panic!("Unknown target arch: {:?}", arch),
|
|
}
|
|
}
|