semx_bsp 0.1.7

对应硬件板级定义
Documentation
//! Rust bsp 定义
//!
//! 板子的 bsp 定义, 目前包括 cpu 数量定义, 内存范围定义, 控制台定义, 中断控制器定义.

use proc_macro::TokenStream;
use proc_macro2::{Ident, Span};
use quote::quote;
use syn::{ItemStatic, parse_macro_input};

/// 定义 cpu 数量
#[proc_macro_attribute]
pub fn define_cpus(_: TokenStream, input: TokenStream) -> TokenStream {
    let f = parse_macro_input!(input as ItemStatic);

    quote!(
        #[unsafe(export_name = "__NR_CPUS")]
        #f
    )
    .into()
}

/// 定义内存范围
#[proc_macro_attribute]
pub fn define_memrange(_: TokenStream, input: TokenStream) -> TokenStream {
    let f = parse_macro_input!(input as ItemStatic);

    quote!(
        #[unsafe(export_name = "__MEMRANGE")]
        #f
    )
    .into()
}

/// 定义控制台
#[proc_macro_attribute]
pub fn define_console(_: TokenStream, input: TokenStream) -> TokenStream {
    let f = parse_macro_input!(input as ItemStatic);

    let name = Ident::new(&format!("{}", f.ident), Span::call_site());

    quote!(
        #f

        #[unsafe(export_name = "__console_init")]
        #[doc(hidden)]
        pub fn console_init() {
            let mut lock = #name.lock_irq_save();
            use seminix::drivers::console::ConsoleImpl;
            lock.init();
        }

        #[unsafe(export_name = "__console_output")]
        #[doc(hidden)]
        pub fn console_output(args: core::fmt::Arguments<'_>) {
            let mut lock = #name.lock_irq_save();
            use core::fmt::Write;
            lock.write_fmt(args).unwrap();
        }
    )
    .into()
}

/// 定义中断控制器
#[proc_macro_attribute]
pub fn define_irqchip(_: TokenStream, input: TokenStream) -> TokenStream {
    let f = parse_macro_input!(input as ItemStatic);

    let name = Ident::new(&format!("{}", f.ident), Span::call_site());

    quote!(
        #f

        extern crate alloc;
        use alloc::string::String;
        use seminix::irq::IrqchipImpl;
        #[unsafe(export_name = "__irqchip_name")]
        #[doc(hidden)]
        pub fn irqchip_name() -> String {
            String::from(#name.name())
        }

        #[unsafe(export_name = "__irq_disable")]
        #[doc(hidden)]
        pub fn irq_disable(hwirq: u32) {
            #name.irq_disable(hwirq);
        }

        #[unsafe(export_name = "__irq_enable")]
        #[doc(hidden)]
        pub fn irq_enable(hwirq: u32) {
            #name.irq_enable(hwirq);
        }

        #[unsafe(export_name = "__irq_set_type")]
        #[doc(hidden)]
        pub fn irq_set_type(hwirq: u32, irq_type: seminix::irq::IrqType) -> seminix::irq::Result<()> {
            #name.irq_set_type(hwirq, irq_type)
        }

        #[unsafe(export_name = "__irq_set_affinity")]
        #[doc(hidden)]
        pub fn irq_set_affinity(hwirq: u32, cpumask: usize) -> seminix::irq::Result<()> {
            #name.irq_set_affinity(hwirq, cpumask)
        }

        #[unsafe(export_name = "__irq_get_irqchip_state")]
        #[doc(hidden)]
        pub fn irq_get_irqchip_state(hwirq: u32, which: &seminix::irq::IrqchipIrqState) -> seminix::irq::Result<bool> {
            #name.irq_get_irqchip_state(hwirq, which)
        }

        #[unsafe(export_name = "__irq_set_irqchip_state")]
        #[doc(hidden)]
        pub fn __irq_set_irqchip_state(hwirq: u32, which: &seminix::irq::IrqchipIrqState, state: bool) -> seminix::irq::Result<()> {
            #name.irq_set_irqchip_state(hwirq, which, state)
        }

        #[unsafe(export_name = "__send_ipi")]
        #[doc(hidden)]
        pub fn send_ipi(hwirq: u32, cpumask: usize) {
            #name.send_ipi(hwirq, cpumask);
        }

        #[unsafe(export_name = "__send_ipi_one")]
        #[doc(hidden)]
        pub fn send_ipi_one(hwirq: u32, cpu: usize) {
            #name.send_ipi_one(hwirq, cpu);
        }

        #[unsafe(export_name = "__handle_irqchip_irq")]
        #[doc(hidden)]
        pub fn handle_irqchip_irq() {
            #name.handle_irq();
        }

        #[unsafe(export_name = "__irq_init")]
        #[doc(hidden)]
        pub fn irq_init() {
            #name.init();
        }

        #[unsafe(export_name = "__irq_init_cpu")]
        #[doc(hidden)]
        pub fn irq_init_cpu() {
            #name.init_cpu();
        }
    )
    .into()
}