//! 系统 BSP 配置项定义
//!
//! 定义微内核运行所必须的板级硬件配置 trait 和数据结构，
//! 包括控制台、中断控制器、时钟源、内存布局和多核信息。

#![no_std]
#![allow(unsafe_code)]

use core::fmt;

use clocksource::{SetNextEventFunc, SetStateStoppedFunc};
use irqchip::{IrqType, IrqchipIrqState, Result};
use moa_cpumask::{CpuId, Cpumask};
use smp::SmpDefine;

pub mod clocksource;
pub mod console;
pub mod irqchip;
pub mod smp;

/// 系统 BSP 定义
///
/// BSP 实现方需提供控制台、中断控制器、时钟源的具体类型，
/// 并通过关联常量配置硬件参数。
pub trait BspDefine {
    /// 控制台实现类型
    type Console: console::ConsoleImpl;
    /// 中断控制器实现类型
    type Irqchip: irqchip::IrqchipImpl;
    /// 时钟源实现类型
    type Clock: clocksource::ClockImpl;

    /// 多核信息
    const DEFINE_SMP: SmpDefine;

    /// 控制台实例
    const DEFINE_CONSOLE: Self::Console;

    /// 中断控制器实例
    const DEFINE_IRQCHIP: Self::Irqchip;

    /// 时钟源实例
    const DEFINE_CLOCK: Self::Clock;

    /// 系统启动前期调用，用于板级硬件早期初始化
    fn early_init(&self) {}

    /// 系统启动后期调用，完成最终板级初始化和加载 APP
    fn late_init(&self);

    /// 从核启动后期调用
    fn secondary_init(&self) {}
}

// ---------------------------------------------------------------------------
// BSP 符号合约：由 moa_rt_macros 生成，内核侧通过此声明调用
// ---------------------------------------------------------------------------

unsafe extern "Rust" {
    /// 系统启动早期调用，不能使用串口内存分配等功能
    pub fn bsp_early_init();
    /// 系统启动后期调用，可以使用内核大部分功能，需要在这里完成 APP 加载
    pub fn bsp_late_init();
    /// 系统从核启动调用
    pub fn bsp_secondary_init();

    /// 多核信息定义
    pub fn bsp_smp_define() -> &'static SmpDefine;

    /// 控制台初始化
    pub fn bsp_console_init();
    /// 控制台输出
    pub fn bsp_console_output(args: fmt::Arguments<'_>);

    /// 中断控制器名字
    pub fn bsp_irqchip_name() -> &'static str;
    /// 中断控制器支持的最大中断数量
    pub fn bsp_irqchip_irqs_max() -> usize;
    /// 中断控制器应答中断
    pub fn bsp_irqchip_irq_ack(hwirq: u32);
    /// 中断控制器结束中断
    pub fn bsp_irqchip_irq_eoi(hwirq: u32);
    /// 中断控制器禁用一个中断
    pub fn bsp_irqchip_irq_disable(hwirq: u32);
    /// 中断控制器激活一个中断
    pub fn bsp_irqchip_irq_enable(hwirq: u32);
    /// 中断控制器设置中断亲和性
    pub fn bsp_irqchip_irq_set_affinity(hwirq: u32, cpumask: &Cpumask) -> Result<()>;
    /// 中断控制器设置中断类型
    pub fn bsp_irqchip_irq_set_type(hwirq: u32, irq_type: IrqType) -> Result<()>;
    /// 中断控制器获取控制器状态
    pub fn bsp_irqchip_irq_get_irqchip_state(hwirq: u32, which: IrqchipIrqState) -> Result<bool>;
    /// 中断控制器设置控制器状态
    pub fn bsp_irqchip_irq_set_irqchip_state(
        hwirq: u32,
        which: IrqchipIrqState,
        state: bool,
    ) -> Result<()>;
    /// 中断控制器向一个处理器发送 IPI 中断
    pub fn bsp_irqchip_ipi_send_single(hwirq: u32, cpu: CpuId);
    /// 中断控制器向一组处理器发送 IPI 中断
    pub fn bsp_irqchip_ipi_send_mask(hwirq: u32, cpumask: &Cpumask);
    /// 中断控制器硬中断处理函数入口
    pub fn bsp_irqchip_irq_handler();
    /// 中断控制器初始化
    pub fn bsp_irqchip_irq_init();
    /// 中断控制器处理器接口初始化
    pub fn bsp_irqchip_irq_init_cpu();

    /// 时钟系统初始化
    pub fn bsp_clock_init();
    /// 时钟系统初始化处理器
    pub fn bsp_clock_init_cpu();
    /// 获取设置下一个时钟事件回调
    pub fn bsp_clock_get_set_next_event() -> SetNextEventFunc;
    /// 获取停止当前时钟事件回调
    pub fn bsp_clock_get_set_state_stopped() -> SetStateStoppedFunc;
    /// 时钟事件源频率
    pub fn bsp_clock_rate() -> usize;
    /// 时钟事件源最小 tick
    pub fn bsp_clock_min_delta() -> u64;
    /// 时钟事件源最大 tick
    pub fn bsp_clock_max_delta() -> u64;
}
