소스 검색

delete arch/src/riscv64's old code

Heinz 7 달 전
부모
커밋
7dd53d9544

+ 0 - 69
arch/src/riscv64/config.rs

@@ -1,69 +0,0 @@
-/// mm
-pub mod mm {
-    pub const ROOT_PAGE_TABLE_PHYS_ADDR: usize = 0x8040_0000;
-    pub const PHYS_MAP_VIRT: usize = 0xffff_ffc0_0000_0000;
-    pub const KIMAGE_PHYS_BASE: usize = 0x8020_0000;
-    pub const KIMAGE_OFFSET: usize = 0xffff_ffff_0000_0000;
-    pub const MMIO_VIRT_BASE: usize = KIMAGE_OFFSET;
-    pub const KIMAGE_VIRT_BASE: usize = KIMAGE_OFFSET + KIMAGE_PHYS_BASE;
-    pub const PAGE_SIZE: usize = 1 << PAGE_SIZE_BITS;
-    pub const PAGE_SIZE_BITS: usize = 12;
-    // 127GB
-    pub const MEMORY_SIZE: usize = 0x1F_C000_0000;
-
-    pub const PTE_SIZE: usize = 8;
-    pub const PTES_PER_PAGE: usize = PAGE_SIZE / PTE_SIZE;
-    pub const ROOT_PAGE_TABLE_PFN: usize = ROOT_PAGE_TABLE_PHYS_ADDR >> 12;
-    pub const PAGE_TABLE_PHYS_END: usize = 0x8080_0000;
-
-    #[derive(Clone, Copy)]
-    pub enum PageSize {
-        _4KbPage = 4096,
-        _2MbPage = 2 * 1024 * 1024,
-        _1GbPage = 1 * 1024 * 1024 * 1024,
-    }
-}
-
-/// smp
-pub mod smp {
-    use spin::Once;
-
-    pub static NUM_HARTS: Once<usize> = Once::new();
-
-    pub fn set_num_harts(num: usize) {
-        NUM_HARTS.call_once(|| num);
-    }
-
-    pub fn get_num_harts() -> usize {
-        *NUM_HARTS.get().expect("NUM_HARTS should be initialized by now")
-    }
-}
-
-pub mod platform {
-    pub mod virt {
-        pub const PLIC_BASE: usize = 0x0C00_0000;
-
-        pub const PLIC_ENABLE_PER_HART_OFFSET: usize = 0x80; // 每个 Hart使能块 0x80 字节 (128 字节)
-
-        pub const PLIC_THRESHOLD_CLAIM_COMPLETE_PER_HART_OFFSET: usize = 0x1000; // 每个 Hart/上下文块 0x1000 字节 (4KB)
-
-        pub const PLIC_PRIORITY_OFFSET: usize = 0x0000_0000;
-        pub const PLIC_PENDING_OFFSET: usize = 0x0000_1000;
-        pub const PLIC_ENABLE_OFFSET: usize = 0x0000_2000; // Varies by context and mode (M/S/U)
-        pub const PLIC_THRESHOLD_OFFSET: usize = 0x0020_0000; // Varies by context and mode (M/S/U)
-        pub const PLIC_CLAIM_COMPLETE_OFFSET: usize = 0x0020_0004; // Varies by context and mode (M/S/U)
-
-        // PLIC Context IDs for S-mode (assuming hart 0's S-mode context is 1, hart 1's is 3, etc.)
-        // A common pattern is: context_id = hart_id * 2 + 1 (for S-mode)
-        pub const PLIC_S_MODE_CONTEXT_STRIDE: usize = 2;
-
-        // CLINT (Core Local Interruptor) memory-mapped registers
-        // Base address for CLINT on QEMU virt platform
-        pub const CLINT_BASE: usize = 0x200_0000;
-        pub const CLINT_MSIP_OFFSET: usize = 0x0000;      // Machine-mode Software Interrupt Pending (MSIP)
-        pub const CLINT_MTIMECMP_OFFSET: usize = 0x4000;  // Machine-mode Timer Compare (MTIMECMP)
-        pub const CLINT_MTIME_OFFSET: usize = 0xBFF8;
-        pub const CPU_FREQ_HZ: u64 = 10_000_000;
-    }
-}
-

+ 0 - 16
arch/src/riscv64/console.rs

@@ -1,16 +0,0 @@
-use sbi::legacy::{console_putchar, console_getchar};
-
-pub fn getchar() -> Option<u8> {
-    let c = console_getchar();
-    if c == Some(!0) {
-        None
-    } else {
-        c
-    }
-}
-
-fn write_str(s: &str) {
-    for c in s.chars() {
-        console_putchar(c as u8);
-    }
-}

+ 0 - 178
arch/src/riscv64/context.rs

@@ -1,178 +0,0 @@
-use core::arch::naked_asm;
-
-#[repr(C)]
-#[derive(Debug, Default)]
-pub struct TaskContext {
-    // s0-11
-    s: [u64; 12],
-    sp: u64,
-    ra: u64,
-    sstatus: u64,
-}
-
-impl TaskContext {
-    pub const fn new() -> Self {
-        Self {
-            s: [0; 12],
-            sp: 0,
-            ra: 0,
-            sstatus: 0,
-        }
-    }
-
-    pub fn ip(&mut self, ip: usize) {
-        self.ra = ip as u64;
-    }
-
-    pub fn entry_point(&mut self, entry: usize) {
-        self.ra = entry as u64;
-    }
-
-    pub fn sp(&mut self, sp: usize) {
-        self.sp = sp as u64;
-    }
-
-    pub fn sstatus(&mut self, status: usize) {
-        self.sstatus = status as u64;
-    }
-
-    pub fn call1(&mut self, func: unsafe extern "C" fn(usize) -> !, arg: [usize; 1]) {
-        self.entry_point(Self::do_call as usize);
-        self.s[0] = func as u64;
-        self.s[1] = arg[0] as u64;
-    }
-
-    pub fn call2(&mut self, func: unsafe extern "C" fn(usize, usize) -> !, arg: [usize; 2]) {
-        self.entry_point(Self::do_call as usize);
-        self.s[0] = func as u64;
-        self.s[1] = arg[0] as u64;
-        self.s[2] = arg[1] as u64;
-    }
-
-    pub fn call3(&mut self, func: unsafe extern "C" fn(usize, usize, usize) -> !, arg: [usize; 3]) {
-        self.entry_point(Self::do_call as usize);
-        self.s[0] = func as u64;
-        self.s[1] = arg[0] as u64;
-        self.s[2] = arg[1] as u64;
-        self.s[3] = arg[2] as u64;
-    }
-
-    pub fn call4(
-        &mut self,
-        func: unsafe extern "C" fn(usize, usize, usize, usize) -> !,
-        arg: [usize; 4],
-    ) {
-        self.entry_point(Self::do_call as usize);
-        self.s[0] = func as u64;
-        self.s[1] = arg[0] as u64;
-        self.s[2] = arg[1] as u64;
-        self.s[3] = arg[2] as u64;
-        self.s[4] = arg[3] as u64;
-    }
-
-    pub fn call5(
-        &mut self,
-        func: unsafe extern "C" fn(usize, usize, usize, usize, usize) -> !,
-        arg: [usize; 5],
-    ) {
-        self.entry_point(Self::do_call as usize);
-        self.s[0] = func as u64;
-        self.s[1] = arg[0] as u64;
-        self.s[2] = arg[1] as u64;
-        self.s[3] = arg[2] as u64;
-        self.s[4] = arg[3] as u64;
-    }
-
-    pub fn interrupt(&mut self, is_enabled: bool) {
-        // sstatus: SIE bit is bit 1
-        const SSTATUS_SIE_BIT: u64 = 1 << 1; // 0x2
-
-        if is_enabled {
-            self.sstatus |= SSTATUS_SIE_BIT;
-        } else {
-            self.sstatus &= !SSTATUS_SIE_BIT;
-        }
-    }
-
-    /// SPIE bit
-    pub fn interrupt_on_return(&mut self, will_enable: bool) {
-        const SSTATUS_SPIE_BIT: u64 = 1 << 5;
-        if will_enable {
-            self.sstatus |= SSTATUS_SPIE_BIT;
-        } else {
-            self.sstatus &= !SSTATUS_SPIE_BIT;
-        }
-    }
-
-    #[naked]
-    #[no_mangle]
-    pub unsafe extern "C" fn __task_context_switch(from: *mut Self, to: *const Self) {
-        // Input arguments `from` and `to` will be in `a0` (x10) and `a1` (x11).
-        naked_asm!(
-            // Save current task's callee-saved registers to `from` context
-            "sd   s0, 0(a0)",
-            "sd   s1, 8(a0)",
-            "sd   s2, 16(a0)",
-            "sd   s3, 24(a0)",
-            "sd   s4, 32(a0)",
-            "sd   s5, 40(a0)",
-            "sd   s6, 48(a0)",
-            "sd   s7, 56(a0)",
-            "sd   s8, 64(a0)",
-            "sd   s9, 72(a0)",
-            "sd  s10, 80(a0)",
-            "sd  s11, 88(a0)",
-            "sd   sp, 96(a0)",
-            "sd   ra, 104(a0)",
-            "csrr s0, sstatus",
-            "sd   s0, 112(a0)", // Store sstatus at offset 112
-
-            // Load next task's callee-saved registers from `to` context
-            "ld   s0, 0(a1)",
-            "ld   s1, 8(a1)",
-            "ld   s2, 16(a1)",
-            "ld   s3, 24(a1)",
-            "ld   s4, 32(a1)",
-            "ld   s5, 40(a1)",
-            "ld   s6, 48(a1)",
-            "ld   s7, 56(a1)",
-            "ld   s8, 64(a1)",
-            "ld   s9, 72(a1)",
-            "ld  s10, 80(a1)",
-            "ld  s11, 88(a1)",
-            "ld   sp, 96(a1)",
-            "ld   ra, 104(a1)",
-            "ld   t0, 112(a1)",
-            "csrw sstatus, t0",
-
-            "ret",
-        );
-    }
-
-    pub fn switch(from: &mut Self, to: &mut Self) {
-        unsafe {
-            TaskContext::__task_context_switch(from, to);
-        }
-    }
-
-    #[naked]
-    #[no_mangle]
-    /// Maximum of 5 arguments supported.
-    unsafe extern "C" fn do_call() -> ! {
-        naked_asm!(
-            // Move function pointer.
-            "mv   t0, s0",
-
-            // Move arguments.
-            "mv   a0, s1",
-            "mv   a1, s2",
-            "mv   a2, s3",
-            "mv   a3, s4",
-            "mv   a4, s5",
-
-            "mv   s0, zero", // Set s0 (fp) to 0.
-
-            "jr   t0", // Jump to t0.
-        );
-    }
-}

+ 0 - 67
arch/src/riscv64/entry/mod.rs

@@ -1,67 +0,0 @@
-mod page;
-
-use page::setup_kernel_page_table;
-
-use super::{
-    config::{self, mm::*},
-    fdt::get_num_harts,
-};
-
-use core::arch::naked_asm;
-
-#[link_section = ".bss.stack"]
-static mut BOOT_STACK: [u8; 4096 * 16] = [0; 4096 * 16];
-
-#[repr(C, align(4096))]
-struct BootPageTable([u64; PTES_PER_PAGE]);
-
-/// map 0x8000 0000 to itself and 0xffff ffff 8000 0000
-static mut BOOT_PAGE_TABLE: BootPageTable = {
-    let mut arr: [u64; PTES_PER_PAGE] = [0; PTES_PER_PAGE];
-    arr[2] = (0x80000 << 10) | 0xcf;
-    arr[510] = (0x80000 << 10) | 0xcf;
-    BootPageTable(arr)
-};
-
-extern "C" {
-    fn kernel_init();
-}
-
-/// bootstrap in rust
-#[naked]
-#[no_mangle]
-#[link_section = ".text.entry"]
-unsafe extern "C" fn _start(hart_id: usize, dtb_addr: usize) -> ! {
-    naked_asm!(
-        "
-            la    sp, {boot_stack}
-            la    t0, {page_table}
-            srli  t0, t0, 12
-            li    t1, 8 << 60
-            or    t0, t0, t1
-            csrw  satp, t0
-            sfence.vma
-            li   t2, {virt_ram_offset}
-            or   sp, sp, t2
-            la   t3, riscv64_start
-            or   t3, t3, t2
-            jalr t3                      // call riscv64_start
-        ",
-        boot_stack = sym BOOT_STACK,
-        page_table = sym BOOT_PAGE_TABLE,
-        virt_ram_offset = const KIMAGE_OFFSET,
-    )
-}
-
-/// TODO: 
-/// linker,现在VMA和LMA不对
-/// kernel_init不知道要干什么
-#[no_mangle]
-pub unsafe extern "C" fn riscv64_start(hart_id: usize, dtb_addr: usize) -> ! {
-    setup_kernel_page_table();
-    let num_harts = get_num_harts(dtb_addr);
-    config::smp::set_num_harts(num_harts);
-    unsafe { kernel_init() };
-
-    unreachable!();
-}

+ 0 - 238
arch/src/riscv64/entry/page.rs

@@ -1,238 +0,0 @@
-use super::super::{
-    config::mm::*,
-    mm::*,
-};
-
-use core::{
-    ptr::NonNull,
-    sync::atomic::AtomicUsize
-};
-use intrusive_list::{container_of, Link};
-use buddy_allocator::{BuddyAllocator, BuddyRawPage};
-use riscv::{asm::sfence_vma_all, register::satp};
-use eonix_mm::{
-    address::{Addr as _, AddrOps, PAddr, VAddr, VRange},
-    page_table::{PageAttribute, PagingMode, RawAttribute, PTE as _},
-    paging::{Page, PageAccess, PageAlloc, PageBlock, RawPage as RawPageTrait, PFN},
-};
-use spin::Mutex;
-
-static mut PAGES: [RawPage; 1024] = [const { RawPage::new() }; 1024];
-
-fn page(index: usize) -> &'static mut RawPage {
-    let page = unsafe { PAGES.as_mut_ptr().add(index) };
-    unsafe { &mut *page }
-}
-
-#[derive(Clone, Copy)]
-struct RawPageHandle(usize);
-
-impl From<PFN> for RawPageHandle {
-    fn from(pfn: PFN) -> Self {
-        assert!(usize::from(pfn) - ROOT_PAGE_TABLE_PFN < 1024, "PFN out of range");
-
-        Self(usize::from(pfn) - ROOT_PAGE_TABLE_PFN)
-    }
-}
-
-impl From<RawPageHandle> for PFN {
-    fn from(raw_page: RawPageHandle) -> Self {
-        PFN::from(raw_page.0 + ROOT_PAGE_TABLE_PFN)
-    }
-}
-
-impl RawPageTrait for RawPageHandle {
-    fn order(&self) -> u32 {
-        page(self.0).order
-    }
-
-    fn refcount(&self) -> &AtomicUsize {
-        &page(self.0).refcount
-    }
-
-    fn is_present(&self) -> bool {
-        self.0 < 1024
-    }
-}
-
-impl BuddyRawPage for RawPageHandle {
-    unsafe fn from_link(link: &mut Link) -> Self {
-        let page = container_of!(link, RawPage, link);
-        let page_index = page.as_ptr().offset_from_unsigned(PAGES.as_ptr());
-        assert!(page_index < 1024, "Page index out of range");
-
-        Self(page_index)
-    }
-
-    unsafe fn get_link(&self) -> &mut Link {
-        &mut page(self.0).link
-    }
-
-    fn set_order(&self, order: u32) {
-        page(self.0).order = order;
-    }
-
-    fn is_buddy(&self) -> bool {
-        page(self.0).buddy
-    }
-
-    fn is_free(&self) -> bool {
-        page(self.0).free
-    }
-
-    fn set_buddy(&self) {
-        page(self.0).buddy = true;
-    }
-
-    fn set_free(&self) {
-        page(self.0).free = true;
-    }
-
-    fn clear_buddy(&self) {
-        page(self.0).buddy = false;
-    }
-
-    fn clear_free(&self) {
-        page(self.0).free = false;
-    }
-}
-
-struct RawPage {
-    link: Link,
-    free: bool,
-    buddy: bool,
-    order: u32,
-    refcount: AtomicUsize,
-}
-
-impl RawPage {
-    const fn new() -> Self {
-        Self {
-            link: Link::new(),
-            free: false,
-            buddy: false,
-            order: 0,
-            refcount: AtomicUsize::new(0),
-        }
-    }
-}
-
-struct DirectPageAccess;
-
-impl PageAccess for DirectPageAccess {
-    unsafe fn get_ptr_for_pfn(pfn: PFN) -> NonNull<PageBlock> {
-        unsafe { NonNull::new_unchecked(PAddr::from(pfn).addr() as *mut _) }
-    }
-}
-
-static BUDDY: Mutex<BuddyAllocator<RawPageHandle>> = Mutex::new(BuddyAllocator::new());
-
-#[derive(Clone)]
-struct BuddyPageAlloc;
-
-impl PageAlloc for BuddyPageAlloc {
-    type RawPage = RawPageHandle;
-
-    fn alloc_order(&self, order: u32) -> Option<Self::RawPage> {
-        let retval = BUDDY.lock().alloc_order(order);
-        retval
-    }
-
-    unsafe fn dealloc(&self, raw_page: Self::RawPage) {
-        BUDDY.lock().dealloc(raw_page);
-    }
-
-    fn has_management_over(&self, page_ptr: Self::RawPage) -> bool {
-        BuddyAllocator::has_management_over(page_ptr)
-    }
-}
-
-type PageTable<'a> = eonix_mm::page_table::PageTable<'a, PagingModeSv39, BuddyPageAlloc, DirectPageAccess>;
-
-extern "C" {
-    fn _ekernel();
-}
-
-/// TODO:
-/// _ekernel现在还没有,需要在linker里加上
-/// 对kernel image添加更细的控制,或者不加也行
-fn map_area(page_table: &PageTable, attr: PageAttribute, range: VRange, phy_offest: usize, page_size: PageSize) {
-    let (pfn_size, levels) = match page_size {
-        PageSize::_4KbPage => (0x1, &PagingModeSv39::LEVELS[..=0]),
-        PageSize::_2MbPage => (0x200, &PagingModeSv39::LEVELS[..=1]),
-        PageSize::_1GbPage => (0x40000, &PagingModeSv39::LEVELS[..=2]),
-    };
-    for (idx, pte) in page_table
-        .iter_kernel_levels(range, levels)
-        .enumerate()
-    {
-        pte.set(PFN::from(idx * pfn_size + phy_offest), PageAttribute64::from_page_attr(attr));
-    }
-}
-
-/// Map physical memory after ekernel, about 0x8040 0000-0x20_7fff_fff about 128GB
-/// to add a 0xffff ffc0 0000 0000 offest
-/// first use 4KB page, then 2MB page, last 1GB page
-fn map_free_physical_memory(attr: PageAttribute, page_table: &PageTable) {
-    let ekernel = _ekernel as usize - KIMAGE_OFFSET;
-
-    let start = PAddr::from(ekernel).ceil_to(PageSize::_4KbPage as usize);
-    let end = PAddr::from(ekernel).ceil_to(PageSize::_2MbPage as usize);
-    let size_4kb = end - start;
-    let range = VRange::from(VAddr::from(PHYS_MAP_VIRT + start.addr())).grow(size_4kb);
-    let pfn_start = start.addr() >> PAGE_SIZE_BITS;
-    map_area(page_table, attr, range, pfn_start, PageSize::_4KbPage);
-
-    let start = end;
-    let end = start.ceil_to(PageSize::_1GbPage as usize);
-    let size_2mb = end - start;
-    let range = VRange::from(VAddr::from(PHYS_MAP_VIRT + start.addr())).grow(size_2mb);
-    let pfn_start = start.addr() >> PAGE_SIZE_BITS;
-    map_area(page_table, attr, range, pfn_start, PageSize::_2MbPage);
-
-    let start = end;
-    let size_1gb = MEMORY_SIZE;
-    let range = VRange::from(VAddr::from(PHYS_MAP_VIRT + start.addr())).grow(size_1gb);
-    let pfn_start = start.addr() >> PAGE_SIZE_BITS;
-    map_area(page_table, attr, range, pfn_start, PageSize::_1GbPage);
-}
-
-pub fn setup_kernel_page_table() {
-    let attr = PageAttribute::WRITE
-        | PageAttribute::READ
-        | PageAttribute::EXECUTE
-        | PageAttribute::GLOBAL
-        | PageAttribute::PRESENT;
-
-    BUDDY.lock().create_pages(PAddr::from(ROOT_PAGE_TABLE_PHYS_ADDR), PAddr::from(PAGE_TABLE_PHYS_END));
-
-    let root_table_page = Page::alloc_in(BuddyPageAlloc);
-    let page_table = PageTable::new_in(&root_table_page, BuddyPageAlloc);
-
-    // Map 0x00000000-0x7fffffff 2GB MMIO,
-    // to 0xffff ffff 0000 0000 to 0xffff ffff 7ffff ffff, use 1GB page
-    map_area(&page_table,
-        attr,
-        VRange::from(VAddr::from(MMIO_VIRT_BASE)).grow(0x2000_0000),
-        0,
-        PageSize::_1GbPage);
-    
-    map_free_physical_memory(attr, &page_table);
-
-    // Map 2 MB kernel image
-    for (idx, pte) in page_table
-        .iter_kernel(VRange::from(VAddr::from(KIMAGE_VIRT_BASE)).grow(0x20_0000))
-        .enumerate()
-    {
-        pte.set(PFN::from(idx + 0x80200), PageAttribute64::from_page_attr(attr));
-    }
-
-    unsafe {
-        satp::set(
-            satp::Mode::Sv39,
-            0,
-            usize::from(PFN::from(page_table.addr())),
-        );
-    }
-    sfence_vma_all();
-}

+ 0 - 99
arch/src/riscv64/fdt.rs

@@ -1,99 +0,0 @@
-extern crate alloc;
-
-use alloc::{string::String, vec::Vec};
-
-#[derive(Debug, Clone)]
-pub struct HartInfo {
-    pub hart_id: usize,
-    pub compatible: Option<String>,
-}
-
-#[derive(Debug)]
-pub struct CpuManager {
-    pub num_harts: usize,
-    pub harts: Vec<HartInfo>,
-    pub boot_hart_id: usize,
-}
-
-impl CpuManager {
-    pub fn from_fdt(dtb_addr: usize, boot_hart_id: usize) -> Self {
-        let fdt = unsafe {
-            fdt::Fdt::from_ptr(dtb_addr as *const u8)
-                .expect("Failed to parse device tree from dtb_addr")
-        };
-
-        let mut harts_info = Vec::new();
-        let mut num_harts = 0;
-
-        if let Some(cpus_node) = fdt.find_node("/cpus") {
-            for cpu_node in cpus_node.children() {
-                let mut is_riscv_cpu = false;
-                let compatible_string: Option<String> = 
-                    if let Some(compatible_prop) = cpu_node
-                        .properties()
-                        .find(|p| p.name == "compatible")
-                    {
-                        if let Some(s) = compatible_prop.as_str() {
-                            if s.starts_with("riscv,") {
-                                is_riscv_cpu = true;
-                            }
-                            Some(String::from(s))
-                        } else {
-                            None
-                        }
-                    } else {
-                        None
-                    };
-
-                if is_riscv_cpu {
-                    let hart_id = if let Some(hart_id_prop) = cpu_node
-                        .properties()
-                        .find(|p| p.name == "hartid")
-                    {
-                        hart_id_prop.as_usize()
-                            .expect("hartid property in CPU node is not a valid integer")
-                    } else if let Some(reg_prop) = cpu_node
-                        .properties()
-                        .find(|p| p.name == "reg")
-                    {
-                        reg_prop.as_usize()
-                            .expect("reg property in CPU node is not a valid integer for hartid")
-                    } else {
-                        panic!("CPU node {:?} does not have a 'hartid' or 'reg' property required for its ID", cpu_node.name);
-                    };
-
-                    let hart_info = HartInfo {
-                        hart_id,
-                        compatible: compatible_string,
-                    };
-                    harts_info.push(hart_info);
-                    num_harts += 1;
-                }
-            }
-        } else {
-            panic!("Device Tree does not contain a /cpus node!");
-        }
-
-        harts_info.sort_by_key(|h| h.hart_id);
-
-        Self {
-            num_harts,
-            harts: harts_info,
-            boot_hart_id,
-        }
-    }
-}
-
-pub fn get_num_harts(dtb_addr: usize) -> usize {
-    let fdt = unsafe {
-        fdt::Fdt::from_ptr(dtb_addr as *const u8)
-            .expect("Failed to parse device tree from dtb_addr")
-    };
-    let dtb_cpus = fdt.cpus();
-    let mut num_harts = 0;
-
-    for _cpu in dtb_cpus {
-        num_harts += 1;
-    }
-    num_harts
-}

+ 0 - 145
arch/src/riscv64/init.rs

@@ -1,145 +0,0 @@
-use core::pin::Pin;
-use riscv::register::{
-    mhartid,
-    sscratch,
-    sstatus
-};
-use sbi::PhysicalAddress;
-
-/// TODO:
-/// 中断handler
-/// 
-
-use super::{config::smp::get_num_harts, enable_sse, setup_kernel_satp, setup_kernel_trap, InterruptControl};
-
-/// RISC-V Hart
-pub struct CPU {
-    hart_id: usize,
-    interrupt: InterruptControl,
-}
-
-impl CPU {
-    pub fn new() -> Self {
-        let hart_id = read_hart_id();
-        Self {
-            hart_id: hart_id,
-            interrupt: InterruptControl::new(hart_id),
-        }
-    }
-
-    /// Load CPU specific configurations for the current Hart.
-    ///
-    /// # Safety
-    /// This function performs low-level hardware initialization and should
-    /// only be called once per Hart during its boot sequence.
-    pub unsafe fn init(self: Pin<&mut Self>) {
-        enable_sse();
-        let self_mut = self.get_unchecked_mut();
-
-        sscratch::write(self_mut.hart_id as usize);
-
-        setup_kernel_trap();
-
-        // CLINT, 10_000 ms
-        self_mut.interrupt.setup_timer(10_000);
-
-        // Supervisor Mode Status Register (sstatus)
-        // SUM (Supervisor User Memory access): support S-mode access user memory
-        // MXR (Make Executable Readable)
-        // SIE (Supervisor Interrupt Enable): enable S-mode interrupt
-        let mut current_sstatus = sstatus::read();
-        current_sstatus.set_spp(sstatus::SPP::Supervisor);
-        current_sstatus.set_sum(true);
-        current_sstatus.set_mxr(true);
-        current_sstatus.set_sie(true);
-        sstatus::write(current_sstatus);
-
-        // setup kernel page table and flush tlb
-        setup_kernel_satp();
-    }
-
-    /// Boot all other hart.
-    pub unsafe fn bootstrap_cpus(&self) {
-        extern "C" {
-        fn ap_boot_entry();
-        }
-        let total_harts = get_num_harts();
-
-        let ap_entry_point = PhysicalAddress::new(ap_boot_entry as usize);
-
-        for i in 1..total_harts {
-            sbi::hsm::hart_start(i, ap_entry_point, 0)
-                .expect("Failed to start secondary hart via SBI");
-        }
-    }
-
-    pub fn cpuid(&self) -> usize {
-        self.hart_id
-    }
-}
-
-fn read_hart_id() -> usize {
-    mhartid::read()
-}
-
-#[macro_export]
-macro_rules! define_smp_bootstrap {
-    ($cpu_count:literal, $ap_entry:ident, $alloc_kstack:tt) => {
-        #[no_mangle]
-        static BOOT_SEMAPHORE: core::sync::atomic::AtomicU64 =
-            core::sync::atomic::AtomicU64::new(0);
-        #[no_mangle]
-        static BOOT_STACK: core::sync::atomic::AtomicU64 =
-            core::sync::atomic::AtomicU64::new(0);
-
-        #[no_mangle]
-        static CPU_COUNT: core::sync::atomic::AtomicU64 =
-            core::sync::atomic::AtomicU64::new(0);
-
-        core::arch::global_asm!(
-            r#"
-        .section .text.ap_boot
-        .globl ap_boot_entry
-
-        ap_boot_entry:
-            csrr a0, mhartid
-
-        1:
-            lw t0, AP_BOOT_STACK.addr
-            beqz t0, 1b
-            li t1, 0
-            sw t1, AP_BOOT_STACK.addr
-            mv sp, t0
-
-        2:
-            lw t0, AP_BOOT_SEMAPHORE.addr
-            beqz t0, 2b
-
-            li t1, 0
-            sw t1, AP_BOOT_SEMAPHORE.addr
-
-            li t0, 1
-            amoswap.w.aq rl t0, a0, ONLINE_HART_COUNT.addr
-
-            call $ap_entry
-            j .
-            "#,
-            BOOT_SEMAPHORE = sym BOOT_SEMAPHORE,
-            BOOT_STACK = sym BOOT_STACK,
-            CPU_COUNT = sym CPU_COUNT,
-            AP_ENTRY = sym $ap_entry,
-        );
-
-        pub unsafe fn wait_cpus_online() {
-            use core::sync::atomic::Ordering;
-            while CPU_COUNT.load(Ordering::Acquire) != $cpu_count - 1 {
-                if BOOT_STACK.load(Ordering::Acquire) == 0 {
-                    let stack_bottom = $alloc_kstack as u64;
-                    BOOT_STACK.store(stack_bottom, Ordering::Release);
-                }
-                $crate::pause();
-            }
-        }
-    };
-}
-

+ 0 - 62
arch/src/riscv64/interrupt/clint.rs

@@ -1,62 +0,0 @@
-use super::super::config::platform::virt::*;
-use core::ptr;
-
-use sbi::{
-    ipi::send_ipi,
-    timer::set_timer,
-    HartMask,
-    SbiError
-};
-use riscv::register::mie;
-
-/// CLINT (Core Local Interruptor) driver
-/// This struct now owns the base address and hart_id.
-pub struct ClintDriver {
-    base_addr: usize,
-    hart_id: usize,
-}
-
-impl ClintDriver {
-    pub fn new(base_addr: usize, hart_id: usize) -> Self {
-        let driver = ClintDriver { base_addr, hart_id };
-
-        driver.clear_soft_interrupt_pending(hart_id);
-
-        // Enable Supervisor-mode Software Interrupts (SSIE)
-        // and Supervisor-mode Timer Interrupts (STIE) in the `mie` CSR.
-        unsafe {
-            mie::set_ssoft(); // Enable S-mode Software Interrupts
-            mie::set_stimer(); // Enable S-mode Timer Interrupts
-        }
-
-        driver
-    }
-
-    /// Reads the current value of the global MTIME (Machine Timer) counter.
-    pub fn get_time(&self) -> u64 {
-        unsafe {
-            // MTIME is a 64-bit counter at CLINT_BASE + CLINT_MTIME_OFFSET
-            ptr::read_volatile((self.base_addr + CLINT_MTIME_OFFSET) as *mut u64)
-        }
-    }
-
-    /// Sets the next timer interrupt trigger point using SBI.
-    pub fn set_timer(&self, time_value: u64) -> Result<(), SbiError> {
-        set_timer(time_value)
-    }
-
-    /// Sends an Inter-Processor Interrupt (IPI) to the specified Hart(s).
-    pub fn send_ipi(&self, hart_id_mask: usize) -> Result<(), SbiError> {
-        // This utilizes the SBI `send_ipi` call.
-        send_ipi(HartMask::from(hart_id_mask))
-    }
-
-    /// Clears the software interrupt pending bit for the specified Hart.
-    pub fn clear_soft_interrupt_pending(&self, hart_id: usize) {
-        unsafe {
-            // MSIP registers are typically located at CLINT_BASE + 4 * hart_id.
-            // Writing 0 to the register clears the pending bit.
-            ptr::write_volatile((self.base_addr + CLINT_MSIP_OFFSET + hart_id * 4) as *mut u32, 0);
-        }
-    }
-}

+ 0 - 319
arch/src/riscv64/interrupt/context.rs

@@ -1,319 +0,0 @@
-use core::arch::asm;
-use riscv::{
-    interrupt::{Exception, Interrupt, Trap}, register::{
-        scause, sie, sstatus::{self, Sstatus, SPP}, stval
-    }, ExceptionNumber, InterruptNumber
-};
-
-/// Floating-point registers context.
-#[repr(C)]
-#[derive(Debug, Clone, Copy, Default)]
-pub struct FpuRegisters {
-    pub f: [u64; 32],
-    pub fcsr: u32,
-}
-
-/// Saved CPU context when a trap (interrupt or exception) occurs on RISC-V 64.
-#[repr(C)]
-#[derive(Debug, Clone, Copy)]
-pub struct TrapContext {
-    pub x: [usize; 32],
-
-    // CSRs
-    pub sstatus: Sstatus, // sstatus CSR value. Contains privilege mode, interrupt enable, FPU state.
-    pub sepc: usize,    // sepc (Supervisor Exception Program Counter). Program counter at trap.
-    
-    pub kernel_sp: usize,
-    pub kernel_ra: usize,
-    pub kernel_s: [usize; 12],
-    pub kernel_fp: usize,
-    pub kernel_tp: usize,
-
-    // may need to save
-    // FPU
-    // pub fpu_regs: FpuRegisters,
-}
-
-impl FpuRegisters {
-    pub fn new() -> Self {
-        unsafe { core::mem::zeroed() }
-    }
-
-    /// Save reg -> mem
-    pub fn save(&mut self) {
-        unsafe {
-            let base_ptr: *mut u64 = self.f.as_mut_ptr();
-            let fcsr_ptr: *mut u32 = &mut self.fcsr;
-            let mut _fcsr_val: u32 = 0;
-            asm!(
-            "fsd f0,  (0 * 8)({base})",
-            "fsd f1,  (1 * 8)({base})",
-            "fsd f2,  (2 * 8)({base})",
-            "fsd f3,  (3 * 8)({base})",
-            "fsd f4,  (4 * 8)({base})",
-            "fsd f5,  (5 * 8)({base})",
-            "fsd f6,  (6 * 8)({base})",
-            "fsd f7,  (7 * 8)({base})",
-            "fsd f8,  (8 * 8)({base})",
-            "fsd f9,  (9 * 8)({base})",
-            "fsd f10, (10 * 8)({base})",
-            "fsd f11, (11 * 8)({base})",
-            "fsd f12, (12 * 8)({base})",
-            "fsd f13, (13 * 8)({base})",
-            "fsd f14, (14 * 8)({base})",
-            "fsd f15, (15 * 8)({base})",
-            "fsd f16, (16 * 8)({base})",
-            "fsd f17, (17 * 8)({base})",
-            "fsd f18, (18 * 8)({base})",
-            "fsd f19, (19 * 8)({base})",
-            "fsd f20, (20 * 8)({base})",
-            "fsd f21, (21 * 8)({base})",
-            "fsd f22, (22 * 8)({base})",
-            "fsd f23, (23 * 8)({base})",
-            "fsd f24, (24 * 8)({base})",
-            "fsd f25, (25 * 8)({base})",
-            "fsd f26, (26 * 8)({base})",
-            "fsd f27, (27 * 8)({base})",
-            "fsd f28, (28 * 8)({base})",
-            "fsd f29, (29 * 8)({base})",
-            "fsd f30, (30 * 8)({base})",
-            "fsd f31, (31 * 8)({base})",
-            "csrr {fcsr_val}, fcsr", // Read fcsr into fcsr_val (which is in a general-purpose register)
-            "sw {fcsr_val}, 0({fcsr_ptr})",
-            base = in(reg) base_ptr,
-            fcsr_val = out(reg) _fcsr_val,
-            fcsr_ptr = in(reg) fcsr_ptr,
-            options(nostack, nomem, preserves_flags));
-        }
-    }
-
-    pub fn restore(&mut self) {
-        let base_ptr: *const u64 = self.f.as_ptr();
-        let fcsr_ptr: *const u32 = &self.fcsr;
-        let mut _fcsr_val: u64;
-
-        unsafe {
-            asm!(
-            "fld f0,  (0 * 8)({base})",
-            "fld f1,  (1 * 8)({base})",
-            "fld f2,  (2 * 8)({base})",
-            "fld f3,  (3 * 8)({base})",
-            "fld f4,  (4 * 8)({base})",
-            "fld f5,  (5 * 8)({base})",
-            "fld f6,  (6 * 8)({base})",
-            "fld f7,  (7 * 8)({base})",
-            "fld f8,  (8 * 8)({base})",
-            "fld f9,  (9 * 8)({base})",
-            "fld f10, (10 * 8)({base})",
-            "fld f11, (11 * 8)({base})",
-            "fld f12, (12 * 8)({base})",
-            "fld f13, (13 * 8)({base})",
-            "fld f14, (14 * 8)({base})",
-            "fld f15, (15 * 8)({base})",
-            "fld f16, (16 * 8)({base})",
-            "fld f17, (17 * 8)({base})",
-            "fld f18, (18 * 8)({base})",
-            "fld f19, (19 * 8)({base})",
-            "fld f20, (20 * 8)({base})",
-            "fld f21, (21 * 8)({base})",
-            "fld f22, (22 * 8)({base})",
-            "fld f23, (23 * 8)({base})",
-            "fld f24, (24 * 8)({base})",
-            "fld f25, (25 * 8)({base})",
-            "fld f26, (26 * 8)({base})",
-            "fld f27, (27 * 8)({base})",
-            "fld f28, (28 * 8)({base})",
-            "fld f29, (29 * 8)({base})",
-            "fld f30, (30 * 8)({base})",
-            "fld f31, (31 * 8)({base})",
-            "lw {fcsr_val}, 0({fcsr_ptr})", // Load from memory (fcsr_ptr)
-            "csrw fcsr, {fcsr_val}",
-            base = in(reg) base_ptr,
-            fcsr_val = out(reg) _fcsr_val,
-            fcsr_ptr = in(reg) fcsr_ptr,
-            options(nostack, nomem, preserves_flags));
-        }
-    }
-}
-
-
-/// TODO: will be displaced after origin's branch be mergered.
-use bitflags::bitflags;
-bitflags! {
-    #[derive(Debug)]
-    pub struct PageFaultErrorCode: u32 {
-        const NonPresent = 1;
-        const Read = 2;
-        const Write = 4;
-        const InstructionFetch = 8;
-        const UserAccess = 16;
-    }
-}
-
-#[derive(Debug)]
-pub enum Fault {
-    InvalidOp,
-    BadAccess,
-    PageFault(PageFaultErrorCode),
-    Unknown(usize),
-}
-
-pub enum TrapType {
-    Syscall { no: usize, args: [usize; 6] },
-    Fault(Fault),
-    Irq(usize),
-    Timer,
-}
-
-impl TrapContext {
-    /// TODO: temporarily all zero, may change in future
-    pub fn new() -> Self {
-        Self {
-            x: [0; 32],
-            sstatus: sstatus::read(),
-            sepc: 0,
-            kernel_sp: 0,
-            kernel_ra: 0,
-            kernel_s: [0; 12],
-            kernel_fp: 0,
-            kernel_tp: 0
-        }
-    }
-
-    fn syscall_no(&self) -> usize {
-        self.x[17]
-    }
-
-    fn syscall_args(&self) -> [usize; 6] {
-        [
-            self.x[10],
-            self.x[11],
-            self.x[12],
-            self.x[13],
-            self.x[14],
-            self.x[15],
-        ]
-    }
-
-    pub fn trap_type(&self) -> TrapType {
-        let scause = scause::read();
-        let cause = scause.cause();
-        match cause {
-            Trap::Interrupt(i) => {
-                match Interrupt::from_number(i).unwrap() {
-                    Interrupt::SupervisorTimer => TrapType::Timer,
-                    Interrupt::SupervisorExternal => TrapType::Irq(0),
-                    // soft interrupt
-                    _ => TrapType::Fault(Fault::Unknown(i)),
-                }
-            }
-            Trap::Exception(e) => {
-                match Exception::from_number(e).unwrap() {
-                    Exception::InstructionMisaligned |
-                    Exception::LoadMisaligned |
-                    Exception::InstructionFault |
-                    Exception::LoadFault |
-                    Exception::StoreFault |
-                    Exception::StoreMisaligned => {
-                        TrapType::Fault(Fault::BadAccess)
-                    },
-                    Exception::IllegalInstruction => {
-                        TrapType::Fault(Fault::InvalidOp)
-                    }
-                    Exception::UserEnvCall => {
-                        TrapType::Syscall { 
-                            no: self.syscall_no(),
-                            args: self.syscall_args()
-                        }
-                    },
-                    Exception::InstructionPageFault |
-                    Exception::LoadPageFault |
-                    Exception::StorePageFault => {
-                        let e = Exception::from_number(e).unwrap();
-                        TrapType::Fault(Fault::PageFault(get_page_fault_error_code(e)))
-                    },
-                    // breakpoint and supervisor env call
-                    _ => TrapType::Fault(Fault::Unknown(e)),
-                }
-            },
-        }
-    }
-
-    pub fn get_program_counter(&self) -> usize {
-        self.sepc
-    }
-
-    pub fn get_stack_pointer(&self) -> usize {
-        self.x[2]
-    }
-
-    pub fn set_program_counter(&mut self, pc: usize) {
-        self.sepc = pc;
-    }
-
-    pub fn set_stack_pointer(&mut self, sp: usize) {
-        self.x[2] = sp;
-    }
-
-    pub fn is_interrupt_enabled(&self) -> bool {
-        self.sstatus.sie()
-    }
-
-    /// TODO: may need more precise control
-    pub fn set_interrupt_enabled(&mut self, enabled: bool) {
-        if enabled {
-            self.sstatus.set_sie(enabled);
-            unsafe { 
-                sie::set_sext();
-                sie::set_ssoft();
-                sie::set_stimer();
-            };
-        } else {
-            self.sstatus.set_sie(enabled);
-            unsafe { 
-                sie::clear_sext();
-                sie::clear_ssoft();
-                sie::clear_stimer();
-            };
-        }
-    }
-
-    pub fn is_user_mode(&self) -> bool {
-        self.sstatus.spp() == SPP::User
-    }
-
-    pub fn set_user_mode(&mut self, user: bool) {
-        match user {
-            true => self.sstatus.set_spp(SPP::User),
-            false => self.sstatus.set_spp(SPP::Supervisor),
-        }
-    }
-
-    pub fn set_user_return_value(&mut self, retval: usize) {
-        self.sepc = retval;
-    }
-}
-
-/// TODO: get PageFaultErrorCode also need check pagetable
-fn get_page_fault_error_code(exception_type: Exception) -> PageFaultErrorCode {
-    let scause_val = stval::read();
-    let mut error_code = PageFaultErrorCode::empty();
-
-    match exception_type {
-        Exception::InstructionPageFault => {
-            error_code |= PageFaultErrorCode::InstructionFetch;
-            error_code |= PageFaultErrorCode::Read;
-        }
-        Exception::LoadPageFault => {
-            error_code |= PageFaultErrorCode::Read;
-        }
-        Exception::StorePageFault => {
-            error_code |= PageFaultErrorCode::Write;
-        }
-        _ => {
-            unreachable!();
-        }
-    }
-    // TODO: here need check pagetable to confirm NonPresent and UserAccess
-    error_code
-}

+ 0 - 161
arch/src/riscv64/interrupt/mod.rs

@@ -1,161 +0,0 @@
-mod plic;
-mod clint;
-mod context;
-mod trap;
-
-use plic::*;
-use clint::*;
-use context::*;
-use trap::*;
-
-/// TODO:
-/// 切换回到user的入口函数
-/// percpu
-/// user?
-
-use riscv::{
-    asm::sfence_vma_all,
-    register::{
-        sstatus::{self, Sstatus},
-        stvec::{self, Stvec}
-    }
-};
-use sbi::SbiError;
-use core::arch::global_asm;
-
-use super::platform::virt::*;
-
-global_asm!(include_str!("trap.S"));
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub struct IrqState(usize);
-
-impl IrqState {
-    #[inline]
-    pub fn save() -> Self {
-        let sstatus_val = sstatus::read().bits();
-
-        unsafe {
-            sstatus::clear_sie();
-        }
-
-        IrqState(sstatus_val)
-    }
-
-    #[inline]
-    pub fn restore(self) {
-        let Self(state) = self;
-        unsafe {
-            sstatus::write(Sstatus::from_bits(state));
-        }
-    }
-
-    #[inline]
-    pub fn was_enabled(&self) -> bool {
-        (self.0 & (1 << 1)) != 0
-    }
-}
-
-#[inline]
-pub fn disable_interrupts() {
-    unsafe {
-        sstatus::clear_sie();
-    }
-}
-
-#[inline]
-pub fn enable_interrupts() {
-    unsafe {
-        sstatus::set_sie();
-    }
-}
-
-/// Architecture-specific interrupt control block.
-pub struct InterruptControl {
-    hart_id: usize,
-    plic: PlicDriver,
-    clint: ClintDriver,
-}
-
-impl InterruptControl {
-    /// # Safety
-    /// should be called only once.
-    pub(crate) fn new(hart_id: usize) -> Self {
-        // Initialize PLICDriver for this Hart
-        let plic = PlicDriver::new(PLIC_BASE, hart_id);
-
-        // Initialize ClintDriver for this Hart
-        let clint = ClintDriver::new(CLINT_BASE, hart_id);
-
-        Self {
-            hart_id,
-            plic: plic,
-            clint: clint,
-        }
-    }
-
-    /// Configures the CLINT timer for a periodic interrupt.
-    ///
-    /// # Arguments
-    /// * `interval_us`: The desired interval between timer interrupts in microseconds.
-    pub fn setup_timer(&self, interval_us: u64) {
-        let current_time = self.clint.get_time();
-        // Calculate ticks per microsecond based on CPU_FREQ_HZ
-        let ticks_per_us = CPU_FREQ_HZ / 1_000_000;
-        let ticks = interval_us * ticks_per_us;
-
-        let next_timer_at = current_time.checked_add(ticks).unwrap_or(u64::MAX);
-
-        if let Err(e) = self.clint.set_timer(next_timer_at) {
-            panic!("Failed to set CLINT timer: {:?}", e);
-        }
-    }
-
-    /// Sends an Inter-Processor Interrupt (IPI) to target Harts.
-    pub fn send_ipi(&self, target_hart_mask: usize) -> Result<(), SbiError> {
-        self.clint.send_ipi(target_hart_mask)
-    }
-
-    /// Handles the "End Of Interrupt" (EOI) for the most recently claimed
-    /// external interrupt.
-    pub fn end_of_external_interrupt(&self, irq_id: u32) {
-        self.plic.complete_interrupt(irq_id);
-    }
-
-    /// Clears the pending software interrupt for the current Hart.
-    pub fn clear_soft_interrupt_pending(&self) {
-        self.clint.clear_soft_interrupt_pending(self.hart_id);
-    }
-
-    pub fn plic_enable_interrupt(&self, irq_id: u32) {
-        self.plic.enable_interrupt(irq_id);
-    }
-
-    pub fn plic_set_priority(&self, irq_id: u32, priority: u32) {
-        self.plic.set_priority(irq_id, priority);
-    }
-
-    pub fn plic_claim_interrupt(&self) -> u32 {
-        self.plic.claim_interrupt()
-    }
-}
-
-extern "C" {
-    fn trap_from_kernel();
-    fn trap_from_user();
-}
-
-fn setup_trap_handler(trap_entry_addr: usize) {
-    unsafe {
-        stvec::write(Stvec::from_bits(trap_entry_addr));
-    }
-    sfence_vma_all();
-}
-
-pub fn setup_kernel_trap() {
-    setup_trap_handler(trap_from_kernel as usize);
-}
-
-pub fn setup_user_trap() {
-    setup_trap_handler(trap_from_user as usize);
-}

+ 0 - 137
arch/src/riscv64/interrupt/plic.rs

@@ -1,137 +0,0 @@
-use core::ptr::{read_volatile, write_volatile};
-
-use super::super::config::platform::virt::*;
-
-use riscv::register::mie;
-
-pub struct PlicDriver {
-    base_addr: usize,
-    hart_id: usize,
-}
-
-impl PlicDriver {
-    pub fn new(base_addr: usize, hart_id: usize) -> Self {
-        let driver = PlicDriver { base_addr, hart_id };
-
-        let s_context_id = driver.s_context_id();
-
-        driver.set_priority_threshold(0);
-
-        let enable_reg_base_for_context = driver.enable_addr(s_context_id);
-        // PLIC enable bits are grouped into 32-bit registers.
-        // Assuming 32 registers for up to 1024 IRQs, but 32 is common for a few hundred.
-        for i in 0..(driver.max_irq_num() / 32 + 1) {
-            let reg_addr = (enable_reg_base_for_context as usize + (i as usize) * 4) as *mut u32;
-            unsafe {
-                (reg_addr as *mut u32).write_volatile(0);
-            }
-        }
-
-        unsafe {
-            mie::set_sext();
-        }
-
-        driver.set_priority(10, 1);
-        driver.enable_interrupt(10);
-
-        // TODO: may need more set_priority
-        // driver.set_priority(UART_IRQ_ID, 1);
-        // driver.enable_interrupt(UART_IRQ_ID);
-        // driver.set_priority(VIRTIO_BLOCK_IRQ_ID, 1);
-        // driver.enable_interrupt(VIRTIO_BLOCK_IRQ_ID);
-
-        driver
-    }
-
-    fn s_context_id(&self) -> usize {
-        self.hart_id * PLIC_S_MODE_CONTEXT_STRIDE + 1
-    }
-
-    fn priority_addr(&self, irq_id: u32) -> *mut u32 {
-        (self.base_addr + PLIC_PRIORITY_OFFSET + (irq_id as usize) * 4) as *mut u32
-    }
-
-    fn pending_addr(&self) -> *mut u32 {
-        (self.base_addr + PLIC_PENDING_OFFSET) as *mut u32
-    }
-
-    fn enable_addr(&self, context_id: usize) -> *mut u32 {
-        // PLIC enable bits are typically organized as 32-bit banks.
-        // The offset for each context's enable registers.
-        // A common stride for context enable blocks is 0x80 (128 bytes).
-        (self.base_addr + PLIC_ENABLE_OFFSET + context_id * PLIC_ENABLE_PER_HART_OFFSET) as *mut u32
-    }
-
-    fn threshold_addr(&self, context_id: usize) -> *mut u32 {
-        // A common stride for context threshold/claim/complete registers is 0x1000 (4KB).
-        (self.base_addr + PLIC_THRESHOLD_OFFSET + context_id * PLIC_THRESHOLD_CLAIM_COMPLETE_PER_HART_OFFSET) as *mut u32
-    }
-
-    fn claim_complete_addr(&self, context_id: usize) -> *mut u32 {
-        (self.base_addr + PLIC_CLAIM_COMPLETE_OFFSET + context_id * PLIC_THRESHOLD_CLAIM_COMPLETE_PER_HART_OFFSET) as *mut u32
-    }
-
-    pub fn set_priority(&self, irq_id: u32, priority: u32) {
-        unsafe {
-            write_volatile(self.priority_addr(irq_id), priority);
-        }
-    }
-
-    pub fn get_priority(&self, irq_id: u32) -> u32 {
-        unsafe { read_volatile(self.priority_addr(irq_id)) }
-    }
-
-    pub fn enable_interrupt(&self, irq_id: u32) {
-        let context_id = self.s_context_id();
-        let enable_reg_offset_in_bank = (irq_id / 32) as usize * 4;
-        let bit_index_in_reg = irq_id % 32;
-
-        let enable_reg_addr = (self.enable_addr(context_id) as usize + enable_reg_offset_in_bank) as *mut u32;
-        let bit_mask = 1 << bit_index_in_reg;
-        unsafe {
-            let old = read_volatile(enable_reg_addr);
-            write_volatile(enable_reg_addr, old | bit_mask);
-        }
-    }
-
-    pub fn disable_interrupt(&self, irq_id: u32) {
-        let context_id = self.s_context_id();
-        let enable_reg_offset_in_bank = (irq_id / 32) as usize * 4;
-        let bit_index_in_reg = irq_id % 32;
-
-        let enable_reg_addr = (self.enable_addr(context_id) as usize + enable_reg_offset_in_bank) as *mut u32;
-        let bit_mask = 1 << bit_index_in_reg;
-        unsafe {
-            let old = read_volatile(enable_reg_addr);
-            write_volatile(enable_reg_addr, old & !bit_mask);
-        }
-    }
-
-    pub fn set_priority_threshold(&self, threshold: u32) {
-        let context_id = self.s_context_id();
-        unsafe {
-            write_volatile(self.threshold_addr(context_id), threshold);
-        }
-    }
-
-    pub fn get_priority_threshold(&self) -> u32 {
-        let context_id = self.s_context_id();
-        unsafe { read_volatile(self.threshold_addr(context_id)) }
-    }
-
-    pub fn claim_interrupt(&self) -> u32 {
-        let context_id = self.s_context_id();
-        unsafe { read_volatile(self.claim_complete_addr(context_id)) }
-    }
-
-    pub fn complete_interrupt(&self, irq_id: u32) {
-        let context_id = self.s_context_id();
-        unsafe {
-            write_volatile(self.claim_complete_addr(context_id), irq_id);
-        }
-    }
-
-    pub fn max_irq_num(&self) -> u32 {
-        127
-    }
-}

+ 0 - 139
arch/src/riscv64/interrupt/trap.S

@@ -1,139 +0,0 @@
-.altmacro
-.macro SAVE_GP n
-    sd x\n, \n*8(sp)
-.endm
-.macro LOAD_GP n
-    ld x\n, \n*8(sp)
-.endm
-
-.section .text
-    .globl trap_from_kernel
-    .globl trap_from_user
-    .globl return_to_user
-    .align 2
-
-# just like a function call
-trap_from_kernel:
-    # save s*
-    addi sp, sp, -17*8
-    sd  ra,  1*8(sp)
-    sd  t0,  2*8(sp)
-    sd  t1,  3*8(sp)
-    sd  t2,  4*8(sp)
-    sd  t3,  5*8(sp)
-    sd  t4,  6*8(sp)
-    sd  t5,  7*8(sp)
-    sd  t6,  8*8(sp)
-    sd  a0,  9*8(sp)
-    sd  a1, 10*8(sp)
-    sd  a2, 11*8(sp)
-    sd  a3, 12*8(sp)
-    sd  a4, 13*8(sp)
-    sd  a5, 14*8(sp)
-    sd  a6, 15*8(sp)
-    sd  a7, 16*8(sp)
-
-    call kernel_trap_entry
-
-    # restore s*
-    ld  ra,  1*8(sp)
-    ld  t0,  2*8(sp)
-    ld  t1,  3*8(sp)
-    ld  t2,  4*8(sp)
-    ld  t3,  5*8(sp)
-    ld  t4,  6*8(sp)
-    ld  t5,  7*8(sp)
-    ld  t6,  8*8(sp)
-    ld  a0,  9*8(sp)
-    ld  a1, 10*8(sp)
-    ld  a2, 11*8(sp)
-    ld  a3, 12*8(sp)
-    ld  a4, 13*8(sp)
-    ld  a5, 14*8(sp)
-    ld  a6, 15*8(sp)
-    ld  a7, 16*8(sp)
-    addi sp, sp, 17*8
-
-    sret
-
-trap_from_user:
-    # swap sp and sscratch(previously stored user TrapContext's address in return_to_user)
-    csrrw sp, sscratch, sp
-
-    sd x1, 1*8(sp)
-    .set n, 3
-    .rept 29
-        SAVE_GP %n
-        .set n, n+1
-    .endr
-
-    csrr t0, sstatus
-    csrr t1, sepc
-    sd t0, 32*8(sp)     # save sstatus into the TrapContext
-    sd t1, 33*8(sp)     # save sepc into the TrapContext
-
-    csrr t2, sscratch
-    sd t2, 2*8(sp)      # save user stack pointer into the TrapContext
-
-    ld ra, 35*8(sp)
-    ld s0, 36*8(sp)
-    ld s1, 37*8(sp)
-    ld s2, 38*8(sp)
-    ld s3, 39*8(sp)
-    ld s4, 40*8(sp)
-    ld s5, 41*8(sp)
-    ld s6, 42*8(sp)
-    ld s7, 43*8(sp)
-    ld s8, 44*8(sp)
-    ld s9, 45*8(sp)
-    ld s10, 46*8(sp)
-    ld s11, 47*8(sp)
-
-    ld fp, 48*8(sp)
-    ld tp, 49*8(sp)
-
-    ld sp, 34*8(sp)
-    ret
-
-# a0: pointer to TrapContext in user space (constant)
-return_to_user:
-    # sscratch store the TrapContext's address
-    csrw sscratch, a0
-
-    # offset in TrapContext's order
-    sd sp, 34*8(a0)
-    sd ra, 35*8(a0)
-    sd s0, 36*8(a0)
-    sd s1, 37*8(a0) 
-    sd s2, 38*8(a0)
-    sd s3, 39*8(a0)
-    sd s4, 40*8(a0)
-    sd s5, 41*8(a0)
-    sd s6, 42*8(a0)
-    sd s7, 43*8(a0)
-    sd s8, 44*8(a0)
-    sd s9, 45*8(a0)
-    sd s10, 46*8(a0)
-    sd s11, 47*8(a0)
-    sd fp, 48*8(a0)
-    sd tp, 49*8(a0)
-
-    mv sp, a0
-    # now sp points to TrapContext in kernel space
-
-    # restore sstatus and sepc
-    ld t0, 32*8(sp)
-    ld t1, 33*8(sp)
-    csrw sstatus, t0
-    csrw sepc, t1
-
-    # save x* expect x0 and sp
-    ld x1, 1*8(sp)
-    .set n, 3
-    .rept 29
-        LOAD_GP %n
-        .set n, n+1
-    .endr
-    ld sp, 2*8(sp)
-
-    sret

+ 0 - 32
arch/src/riscv64/interrupt/trap.rs

@@ -1,32 +0,0 @@
-use super::setup_kernel_trap;
-
-use riscv::register::{scause, sepc, stval};
-
-/// TODO:
-/// kernel_trap_entry, 暂时不知道要干什么,大概是处理一下原因,然后跳到default handler
-/// user_trap_entry, 大概是一样的
-/// trap_return, 估计不是在这里写,还不太清楚
-
-#[no_mangle]
-pub fn kernel_trap_entry() {
-    let stval = stval::read();
-    let scause = scause::read();
-    let sepc = sepc::read();
-    let cause = scause.cause();
-
-    match scause.cause() {
-        scause::Trap::Interrupt(_) => todo!(),
-        scause::Trap::Exception(_) => todo!(),
-    }
-}
-
-#[no_mangle]
-pub fn user_trap_entry() {
-    setup_kernel_trap();
-
-}
-
-#[no_mangle]
-pub fn trap_return() {
-
-}

+ 0 - 170
arch/src/riscv64/kernel.ld

@@ -1,170 +0,0 @@
-OUTPUT_FORMAT(riscv)
-ENTRY(_start)
-
-RAM = 0x80200000;
-
-MEMORY
-{
-    KBSS          (w)  : org = 0xffffffff00200000, len = 2M
-    KIMAGE        (wx) : org = 0xffffffff80200000, len = 2M
-    KPERCPU       (w)  : org = 0x0000000000000000, len = 128K
-}
-
-SECTIONS
-{
-    .text : AT(RAM)
-    {
-        TEXT_START = .;
-        *(.text.entry)
-        *(.text)
-        *(.text*)
-
-        . = ALIGN(0x1000);
-        TEXT_END = .;
-    } > KIMAGE
-
-    TEXT_PAGES = (TEXT_END - TEXT_START) / 0x1000;
-
-    .rodata :
-        AT(LOADADDR(.text) + SIZEOF(.text))
-    {
-        RODATA_START = .;
-        *(.rodata)
-        *(.rodata*)
-
-        . = ALIGN(16);
-        start_ctors = .;
-        KEEP(*(.init_array));
-        KEEP(*(SORT_BY_INIT_PRIORITY(.init_array*)));
-        KEEP(*(.ctors));
-        KEEP(*(SORT_BY_INIT_PRIORITY(.ctors*)));
-        end_ctors = .;
-
-        . = ALIGN(16);
-        _fix_start = .;
-        KEEP(*(.fix));
-        _fix_end = .;
-
-        . = ALIGN(16);
-        BSS_ADDR = .;
-        QUAD(ABSOLUTE(BSS_START));
-        BSS_LENGTH = .;
-        QUAD(BSS_END - BSS_START);
-        FIX_START = .;
-        QUAD(ABSOLUTE(_fix_start));
-        FIX_END = .;
-        QUAD(ABSOLUTE(_fix_end));
-        PERCPU_PAGES = .;
-        QUAD(_PERCPU_PAGES);
-
-        . = ALIGN(0x1000);
-        RODATA_END = .;
-    } > KIMAGE
-
-    RODATA_PAGES = (RODATA_END - RODATA_START) / 0x1000;
-
-    .data : AT(LOADADDR(.rodata) + SIZEOF(.rodata))
-    {
-        DATA_START = .;
-        *(.data)
-        *(.data*)
-
-        *(.got)
-        *(.got.plt)
-
-        . = . + 4;
-        . = ALIGN(0x1000) - 4;
-        LONG(KERNEL_MAGIC);
-        DATA_END = .;
-    } > KIMAGE
-
-    DATA_PAGES = (DATA_END - DATA_START) / 0x1000;
-
-    _PERCPU_DATA_START = .;
-    .percpu 0 : AT(LOADADDR(.data) + SIZEOF(.data))
-    {
-        PERCPU_START = .;
-        QUAD(0); /* Reserved for x86 percpu pointer */
-        QUAD(0);
-
-        *(.percpu .percpu*)
-
-        . = ALIGN(0x1000);
-        PERCPU_END = .;
-    } > KPERCPU
-    _PERCPU_LENGTH = PERCPU_END - PERCPU_START;
-
-    _PERCPU_PAGES = _PERCPU_LENGTH / 0x1000;
-
-    .bss :
-    {
-        BSS_STACK = .;
-        *(.bss.stack)
-        BSS_START = .;
-        *(.bss)
-        *(.bss*)
-
-        . = ALIGN(0x1000);
-        BSS_END = .;
-    } > KBSS
-
-    KIMAGE_PAGES = TEXT_PAGES + RODATA_PAGES + _PERCPU_PAGES + DATA_PAGES;
-    BSS_PAGES = (BSS_END - BSS_START) / 0x1000;
-    KERNEL_MAGIC = 0x01145140;
-
-    KIMAGE_32K_COUNT = (KIMAGE_PAGES * 0x1000 + 32 * 1024 - 1) / (32 * 1024);
-
-    .eh_frame :
-        AT(LOADADDR(.percpu) + SIZEOF(.percpu))
-    {
-        KEEP(*(.eh_frame*))
-        . = ALIGN(0x1000);
-    } > KIMAGE
-
-    /* Stabs debugging sections.  */
-    .stab          0 : { KEEP(*(.stab)); }
-    .stabstr       0 : { KEEP(*(.stabstr)); }
-    .stab.excl     0 : { KEEP(*(.stab.excl)); }
-    .stab.exclstr  0 : { KEEP(*(.stab.exclstr)); }
-    .stab.index    0 : { KEEP(*(.stab.index)); }
-    .stab.indexstr 0 : { KEEP(*(.stab.indexstr)); }
-    .comment       0 : { KEEP(*(.comment)); }
-    /* DWARF debug sections.
-       Symbols in the DWARF debugging sections are relative to the beginning
-       of the section so we begin them at 0.  */
-    /* DWARF 1 */
-    .debug          0 : { KEEP(*(.debug)); }
-    .line           0 : { KEEP(*(.line)); }
-    /* GNU DWARF 1 extensions */
-    .debug_srcinfo  0 : { KEEP(*(.debug_srcinfo)); }
-    .debug_sfnames  0 : { KEEP(*(.debug_sfnames)); }
-    /* DWARF 1.1 and DWARF 2 */
-    .debug_aranges  0 : { KEEP(*(.debug_aranges)); }
-    .debug_pubnames 0 : { KEEP(*(.debug_pubnames)); }
-    /* DWARF 2 */
-    .debug_info     0 : { KEEP(*(.debug_info)); }
-    .debug_abbrev   0 : { KEEP(*(.debug_abbrev)); }
-    .debug_line     0 : { KEEP(*(.debug_line)); }
-    .debug_frame    0 : { KEEP(*(.debug_frame)); }
-    .debug_str      0 : { KEEP(*(.debug_str)); }
-    .debug_loc      0 : { KEEP(*(.debug_loc)); }
-    .debug_macinfo  0 : { KEEP(*(.debug_macinfo)); }
-    /* SGI/MIPS DWARF 2 extensions */
-    .debug_weaknames 0 : { KEEP(*(.debug_weaknames)); }
-    .debug_funcnames 0 : { KEEP(*(.debug_funcnames)); }
-    .debug_typenames 0 : { KEEP(*(.debug_typenames)); }
-    .debug_varnames  0 : { KEEP(*(.debug_varnames)); }
-
-    /* DWARF Other */
-    .debug_ranges  0 : { KEEP(*(.debug_ranges)); }
-    .debug_line_str 0 : { KEEP(*(.debug_line_str)); }
-    /* Rust stuff */
-
-    /DISCARD/ :
-    {
-        *(.fini_array*)
-        *(.note*)
-        *(.dtors*)
-        *(.debug_gdb_scripts*)
-    }
-}

+ 0 - 13
arch/src/riscv64/memory.txt

@@ -1,13 +0,0 @@
-physical memory:
-
-0x0000 0000 - 0x8000 0000  2GB MMIO
-0x8000 0000 - 0x8020 0000  2MB SBI
-0x8020 0000 - 0x8040 0000  2MB kernel image (maybe)
-free memory after kernel image
-
-
-kernel virtual address space:
-
-0xffff ffc0 0000 0000 - 0xffff ffdf ffff ffff  128GB physical memory
-0xffff ffff 0000 0000 - 0xffff ffff 7fff ffff    2GB MMIO
-0xffff ffff 8020 0000 - 0xffff ffff 803f ffff    2MB kernel image

+ 0 - 214
arch/src/riscv64/mm.rs

@@ -1,214 +0,0 @@
-use core::{marker::PhantomData, ptr::NonNull};
-use eonix_mm::{
-    page_table::{
-        PageAttribute, PageTableLevel, PagingMode, RawAttribute, RawPageTable, TableAttribute, PTE,
-    },
-    paging::{PageBlock, PFN},
-};
-use riscv::{asm::sfence_vma_all, register::satp};
-
-use super::config::mm::ROOT_PAGE_TABLE_PFN;
-
-pub const PAGE_TABLE_BASE: PFN = PFN::from_val(ROOT_PAGE_TABLE_PFN);
-
-pub const PA_V: u64 = 0b1 << 0;
-pub const PA_R: u64 = 0b1 << 1;
-pub const PA_W: u64 = 0b1 << 2;
-pub const PA_X: u64 = 0b1 << 3;
-pub const PA_U: u64 = 0b1 << 4;
-pub const PA_G: u64 = 0b1 << 5;
-pub const PA_A: u64 = 0b1 << 6;
-pub const PA_D: u64 = 0b1 << 7;
-
-// in RSW
-pub const PA_COW: u64 = 0b1 << 8;
-pub const PA_MMAP: u64 = 0b1 << 9;
-
-#[allow(dead_code)]
-pub const PA_SHIFT: u64 = 10;
-// Bit 0-9 (V, R, W, X, U, G, A, D, RSW)
-#[allow(dead_code)]
-pub const PA_FLAGS_MASK: u64 = 0x3FF; // 0b11_1111_1111
-
-#[repr(transparent)]
-#[derive(Clone, Copy)]
-pub struct PTE64(pub u64);
-
-#[derive(Clone, Copy)]
-pub struct PageAttribute64(u64);
-
-pub struct RawPageTableSv39<'a>(NonNull<PTE64>, PhantomData<&'a ()>);
-
-pub struct PagingModeSv39;
-
-impl PTE for PTE64 {
-    type Attr = PageAttribute64;
-
-    fn set(&mut self, pfn: PFN, attr: Self::Attr) {
-        self.0 = (usize::from(pfn) << PA_SHIFT) as u64 | attr.0;
-    }
-
-    fn get(&self) -> (PFN, Self::Attr) {
-        let pfn = PFN::from(self.0 as usize >> PA_SHIFT);
-        let attr = PageAttribute64(self.0 & PA_FLAGS_MASK);
-        (pfn, attr)
-    }
-}
-
-impl PagingMode for PagingModeSv39 {
-    type Entry = PTE64;
-    type RawTable<'a> = RawPageTableSv39<'a>;
-    const LEVELS: &'static [PageTableLevel] = &[
-        PageTableLevel::new(30, 9),
-        PageTableLevel::new(21, 9),
-        PageTableLevel::new(12, 9),
-    ];
-    const KERNEL_ROOT_TABLE_PFN: PFN = PAGE_TABLE_BASE;
-}
-
-impl<'a> RawPageTable<'a> for RawPageTableSv39<'a> {
-    type Entry = PTE64;
-
-    fn index(&self, index: u16) -> &'a Self::Entry {
-        unsafe { self.0.add(index as usize).as_ref() }
-    }
-
-    fn index_mut(&mut self, index: u16) -> &'a mut Self::Entry {
-        unsafe { self.0.add(index as usize).as_mut() }
-    }
-
-    unsafe fn from_ptr(ptr: NonNull<PageBlock>) -> Self {
-        Self(ptr.cast(), PhantomData)
-    }
-}
-
-impl RawAttribute for PageAttribute64 {
-    fn null() -> Self {
-        Self(0)
-    }
-
-    fn as_table_attr(self) -> Option<TableAttribute> {
-        let mut table_attr = TableAttribute::empty();
-
-        if self.0 & (PA_R | PA_W | PA_X) != 0 {
-            panic!("Encountered a huge page while parsing table attributes");
-        }
-
-        if self.0 & PA_V != 0 {
-            table_attr |= TableAttribute::PRESENT;
-        }
-        if self.0 & PA_G != 0 {
-            table_attr |= TableAttribute::GLOBAL;
-        }
-        if self.0 & PA_U != 0 {
-            table_attr |= TableAttribute::USER;
-        }
-        if self.0 & PA_A != 0 {
-            table_attr |= TableAttribute::ACCESSED;
-        }
-
-        Some(table_attr)
-    }
-
-    fn as_page_attr(self) -> Option<PageAttribute> {
-        let mut page_attr = PageAttribute::empty();
-
-        if self.0 & (PA_R | PA_W | PA_X) == 0 {
-            panic!("Invalid page attribute combination");
-        }
-
-        if self.0 & PA_V != 0 {
-            page_attr |= PageAttribute::PRESENT;
-        }
-
-        if self.0 & PA_R != 0 {
-            page_attr |= PageAttribute::READ;
-        }
-
-        if self.0 & PA_W != 0 {
-            page_attr |= PageAttribute::WRITE;
-        }
-
-        if self.0 & PA_X != 0 {
-            page_attr |= PageAttribute::EXECUTE;
-        }
-
-        if self.0 & PA_U != 0 {
-            page_attr |= PageAttribute::USER;
-        }
-
-        if self.0 & PA_A != 0 {
-            page_attr |= PageAttribute::ACCESSED;
-        }
-
-        if self.0 & PA_D != 0 {
-            page_attr |= PageAttribute::DIRTY;
-        }
-
-        if self.0 & PA_G != 0 {
-            page_attr |= PageAttribute::GLOBAL;
-        }
-
-        if self.0 & PA_COW != 0 {
-            page_attr |= PageAttribute::COPY_ON_WRITE;
-        }
-
-        if self.0 & PA_MMAP != 0 {
-            page_attr |= PageAttribute::MAPPED;
-        }
-
-        /*if self.0 & PA_ANON != 0 {
-            page_attr |= PageAttribute::ANONYMOUS;
-        }*/
-
-        Some(page_attr)
-    }
-
-    fn from_table_attr(table_attr: TableAttribute) -> Self {
-        let mut raw_attr = 0;
-
-        for attr in table_attr.iter() {
-            match attr {
-                TableAttribute::PRESENT => raw_attr |= PA_V,
-                TableAttribute::GLOBAL => raw_attr |= PA_G,
-                TableAttribute::USER => raw_attr |= PA_U,
-                TableAttribute::ACCESSED => raw_attr |= PA_A,
-                _ => unreachable!("Invalid table attribute"),
-            }
-        }
-
-        Self(raw_attr)
-    }
-
-    fn from_page_attr(page_attr: PageAttribute) -> Self {
-        let mut raw_attr = 0;
-
-        for attr in page_attr.iter() {
-            match attr {
-                PageAttribute::PRESENT => raw_attr |= PA_V,
-                PageAttribute::READ => raw_attr |= PA_R,
-                PageAttribute::WRITE => raw_attr |= PA_W,
-                PageAttribute::EXECUTE => raw_attr |= PA_X,
-                PageAttribute::USER => raw_attr |= PA_U,
-                PageAttribute::ACCESSED => raw_attr |= PA_A,
-                PageAttribute::DIRTY => raw_attr |= PA_D,
-                PageAttribute::GLOBAL => raw_attr |= PA_G,
-                PageAttribute::COPY_ON_WRITE => raw_attr |= PA_COW,
-                PageAttribute::MAPPED => raw_attr |= PA_MMAP,
-                PageAttribute::ANONYMOUS => {},
-                _ => unreachable!("Invalid page attribute"),
-            }
-        }
-
-        Self(raw_attr)
-    }
-}
-
-pub type DefaultPagingMode = PagingModeSv39;
-
-pub fn setup_kernel_satp() {
-    unsafe {
-        satp::set(satp::Mode::Sv48, 0, PFN::from(ROOT_PAGE_TABLE_PFN).into());
-    }
-    sfence_vma_all();
-}