semx_bsp/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
//! Rust bsp 定义
//!
//! 板子的 bsp 定义, 目前包括 cpu 数量定义, 内存范围定义, 控制台定义, 中断控制器定义.

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

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

    quote!(
        #[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!(
        #[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

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

        #[export_name = "__console_output"]
        #[doc(hidden)]
        pub unsafe 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;
        #[export_name = "__irqchip_name"]
        #[doc(hidden)]
        pub unsafe fn irqchip_name() -> String {
            String::from(#name.name())
        }

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

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

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

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

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

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

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

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

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

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

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