// Licensed under the Apache-2.0 license
// SPDX-License-Identifier: Apache-2.0

//! Entry point for ASPEED AST10x0 target.
#![no_std]
#![no_main]

use arch_arm_cortex_m::Arch;

#[cfg(feature = "jtag-halt")]
use core::ptr::{self, addr_of};

#[cfg(feature = "jtag-halt")]
/// Enable ARM JTAG pins via SCU pinmux and halt waiting for a debugger.
///
/// # Safety
/// Caller must have exclusive early-boot ownership of SCU MMIO and must have
/// already unlocked SCU write protection (write `0x1688_A8A8` to `SCU000`);
/// otherwise the `SCU41C` pinmux write is silently dropped.
unsafe fn jtag_init() {
    // Enable JTAG pins via SCU pinmux - must happen very early
    // Scu::steal() is safe here: it's a zero-sized type with no RAM allocation
    let scu = unsafe { ast1060_pac::Scu::steal() };

    // SCU41C: Multi-function Pin Control - enable ARM JTAG pins
    scu.scu41c().modify(|_, w| {
        w.enbl_armtmsfn_pin()
            .bit(true)
            .enbl_armtckfn_pin()
            .bit(true)
            .enbl_armtrstfn_pin()
            .bit(true)
            .enbl_armtdifn_pin()
            .bit(true)
            .enbl_armtdofn_pin()
            .bit(true)
    });

    // Halt here waiting for JTAG debugger
    // Break with JTAG and set HALT to 0 to continue
    static mut HALT: u32 = 1;
    loop {
        let val = unsafe { ptr::read_volatile(addr_of!(HALT)) };
        if val == 0 {
            break;
        }
    }
}
/// Configure and enable the AST10x0 instruction/data cache.
///
/// Sequence: disable cache, program the cacheable area, invalidate, re-enable.
///
/// # Safety
/// Caller must have exclusive early-boot ownership of SCU MMIO and must have
/// already unlocked SCU write protection.
unsafe fn init_cache() {
    // SAFETY: see function-level safety contract.
    let scu = unsafe { &*ast1060_pac::Scu::ptr() };

    // Disable cache.
    scu.scua58().write(|w| unsafe { w.bits(0) });

    // Configure cache area.
    scu.scua50().write(|w| unsafe { w.bits(0x000f_ffff) });

    // Invalidate cache.
    scu.scua54().write(|w| unsafe { w.bits(0x8660_0000) });

    // Re-enable cache.
    scu.scua58().write(|w| unsafe { w.bits(1) });
}

// Pre-kernel hardware initialization
/// Runs before RAM is initialized, before main()
#[cortex_m_rt::pre_init]
unsafe fn pre_init() {
    // SAFETY: pre-init has exclusive early-boot ownership of SCU MMIO.
    let scu = unsafe { &*ast1060_pac::Scu::ptr() };

    // Unlock SCU write-protected registers.
    scu.scu000().write(|w| unsafe { w.bits(0x1688_A8A8) });

    #[cfg(feature = "jtag-halt")]
    jtag_init();

    // SAFETY: SCU is unlocked above; pre-init has exclusive ownership.
    unsafe { init_cache() };
}

#[unsafe(no_mangle)]
#[allow(non_snake_case)]
pub extern "C" fn pw_assert_HandleFailure() -> ! {
    use kernel::Arch as _;
    Arch::panic();
}

// ── Interrupt Handler Stubs ──
// These are required by the ast1060-pac's __INTERRUPTS vector table.

macro_rules! default_handler {
    ($($name:ident),*) => {
        $(
            #[unsafe(no_mangle)]
            pub extern "C" fn $name() {
                // Default: infinite loop
                loop {}
            }
        )*
    };
}

// Default stub handlers for peripherals not yet implemented
default_handler!(
    fmc, gpio, hace, i2c, i2c1, i2c2, i2c3, i2c4, i2c5, i2c6, i2c7, i2c8, i2c9, i2c10, i2c11,
    i2c12, i2c13, i2cfilter, i3c, i3c1, i3c2, i3c3, scu, sgpiom, spi, spi1, spipf1, spipf2, spipf3,
    timer1, timer2, timer3, timer4, timer5, timer6, timer7, uart, uartdma, wdt
);

mod console_backend {
    unsafe extern "Rust" {
        pub fn console_backend_write_all(buf: &[u8]) -> pw_status::Result<()>;
    }
}

#[cortex_m_rt::entry]
fn main() -> ! {
    kernel::static_init_state!(static mut INIT_STATE: InitKernelState<Arch>);
    #[allow(static_mut_refs)]
    unsafe {
        // Initialize UART console
        let _ = console_backend::console_backend_write_all(b"\r\nHello World!\r\n");
        let _ = console_backend::console_backend_write_all(b"ast1060 pigweed fw is running!\r\n");

        kernel::main(Arch, &mut INIT_STATE)
    };
}
