mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-07-11 07:03:23 +00:00
feat: la64 boot (#1132)
* la64能够进入到kernel_main * ci: 添加为ubuntu编译qemu-loongarch64的脚本 * feat: la64能输出hello world * la64 安装gcc && 配置github ci * chore: 更新CI工作流和构建脚本中的Docker镜像版本至v1.10 Signed-off-by: longjin <longjin@DragonOS.org>
This commit is contained in:
.github/workflows
.vscode
Makefilebuild-scripts/kernel_build/src
dadk-manifest.tomlenv.mkkernel
Cargo.lockCargo.tomlMakefileenv.mk
crates
kprobe
src
arch
loongarch64
src
tools
.gitignoreBUILD_CONTAINER_VERSIONbootstrap.shbuild_gcc_toolchain.shbuild_in_docker.shchange_rust_src.shcheck_arch.shconfigure_network.shdocker-entrypoint.shdump_kernel.shgrub_auto_install.shinit_rust_toolchain.shinstall_cross_gcc.sh
qemu
run-qemu.shwrite_disk_image.shuser
@ -10,17 +10,20 @@ LIB_FILES := $(foreach DIR,$(DIR_LIB),$(addprefix $(DIR)/,$(lib_patterns)))
|
||||
|
||||
# unwind/backtrace related
|
||||
UNWIND_ENABLE ?= yes
|
||||
|
||||
ifeq ($(ARCH), loongarch64)
|
||||
UNWIND_ENABLE = no
|
||||
endif
|
||||
|
||||
CFLAGS_UNWIND =
|
||||
LDFLAGS_UNWIND =
|
||||
RUSTFLAGS_UNWIND =
|
||||
ifeq ($(UNWIND_ENABLE), yes)
|
||||
CFLAGS_UNWIND = -funwind-tables
|
||||
LDFLAGS_UNWIND = --eh-frame-hdr
|
||||
RUSTFLAGS_UNWIND = -Cforce-unwind-tables -Clink-arg=-Wl,eh_frame.ld -Cpanic=unwind
|
||||
RUSTFLAGS += -Cforce-unwind-tables -Clink-arg=-Wl,eh_frame.ld -Cpanic=unwind
|
||||
endif
|
||||
|
||||
RUSTFLAGS += $(RUSTFLAGS_UNWIND)
|
||||
|
||||
CFLAGS = $(GLOBAL_CFLAGS) -fno-pie $(CFLAGS_UNWIND) -I $(shell pwd) -I $(shell pwd)/include
|
||||
|
||||
ifeq ($(ARCH), x86_64)
|
||||
@ -48,6 +51,10 @@ ifeq ($(ARCH), x86_64)
|
||||
$(MAKE) __link_x86_64_kernel
|
||||
else ifeq ($(ARCH), riscv64)
|
||||
$(MAKE) __link_riscv64_kernel
|
||||
else ifeq ($(ARCH), loongarch64)
|
||||
$(MAKE) __link_loongarch64_kernel
|
||||
else
|
||||
$(error Unknown ARCH: $(ARCH))
|
||||
endif
|
||||
|
||||
@echo "Kernel Build Done."
|
||||
@ -113,6 +120,32 @@ else
|
||||
endif
|
||||
rm kernel
|
||||
|
||||
|
||||
__link_loongarch64_kernel:
|
||||
@echo "Linking kernel..."
|
||||
$(LD) -b elf64-loongarch -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/loongarch64-unknown-none/release/libdragonos_kernel.a -T arch/loongarch64/link.ld --no-relax
|
||||
# 生成kallsyms
|
||||
current_dir=$(pwd)
|
||||
|
||||
@dbg='debug';for x in $$dbg; do \
|
||||
cd $$x;\
|
||||
$(MAKE) generate_kallsyms kernel_root_path="$(shell pwd)"||exit 1;\
|
||||
cd ..;\
|
||||
done
|
||||
|
||||
# 重新链接
|
||||
@echo "Re-Linking kernel..."
|
||||
@echo $(shell find . -name "*.o")
|
||||
$(LD) -b elf64-loongarch -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/loongarch64-unknown-none/release/libdragonos_kernel.a ./debug/kallsyms.o -T arch/loongarch64/link.ld --no-relax
|
||||
@echo "Generating kernel ELF file..."
|
||||
# 生成内核文件
|
||||
ifeq ($(UNWIND_ENABLE), yes)
|
||||
$(OBJCOPY) -I elf64-loongarch -O elf64-loongarch kernel ../../bin/kernel/kernel.elf
|
||||
else
|
||||
$(OBJCOPY) -I elf64-loongarch -O elf64-loongarch -R ".eh_frame" kernel ../../bin/kernel/kernel.elf
|
||||
endif
|
||||
rm kernel
|
||||
|
||||
__dragon_stub:
|
||||
@echo "Linking dragon_stub..."
|
||||
@mkdir -p $(ROOT_PATH)/bin/sysroot
|
||||
|
14
kernel/src/arch/loongarch64/asm/bitops.rs
Normal file
14
kernel/src/arch/loongarch64/asm/bitops.rs
Normal file
@ -0,0 +1,14 @@
|
||||
/// 寻找u64中的第一个0所在的位(从第0位开始寻找)
|
||||
///
|
||||
/// 注意:如果x中没有0,那么结果将是未定义的。请确保传入的x至少存在1个0
|
||||
///
|
||||
/// # 参数
|
||||
/// * `x` - 目标u64
|
||||
///
|
||||
/// # 返回值
|
||||
/// 第一个(最低有效位)0位的位号(0..63)
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub fn ffz(x: u64) -> i32 {
|
||||
(!x).trailing_zeros() as i32
|
||||
}
|
98
kernel/src/arch/loongarch64/asm/boot.rs
Normal file
98
kernel/src/arch/loongarch64/asm/boot.rs
Normal file
@ -0,0 +1,98 @@
|
||||
///
|
||||
/// The earliest entry point for the primary CPU.
|
||||
///
|
||||
/// 这些代码拷贝、修改自 polyhal (https://github.com/Byte-OS/polyhal.git)
|
||||
use crate::arch::{cpu::current_cpu_id, init::boot::kernel_main};
|
||||
|
||||
const QEMU_DTB_PADDR: usize = 0x100000;
|
||||
|
||||
/// The earliest entry point for the primary CPU.
|
||||
///
|
||||
/// We can't use bl to jump to higher address, so we use jirl to jump to higher address.
|
||||
#[naked]
|
||||
#[no_mangle]
|
||||
#[link_section = ".text.entry"]
|
||||
unsafe extern "C" fn _start() -> ! {
|
||||
core::arch::naked_asm!("
|
||||
|
||||
ori $t0, $zero, 0x1 # CSR_DMW1_PLV0
|
||||
lu52i.d $t0, $t0, -2048 # UC, PLV0, 0x8000 xxxx xxxx xxxx
|
||||
csrwr $t0, 0x180 # LOONGARCH_CSR_DMWIN0
|
||||
ori $t0, $zero, 0x11 # CSR_DMW1_MAT | CSR_DMW1_PLV0
|
||||
lu52i.d $t0, $t0, -1792 # CA, PLV0, 0x9000 xxxx xxxx xxxx
|
||||
csrwr $t0, 0x181 # LOONGARCH_CSR_DMWIN1
|
||||
|
||||
# Goto 1 if hart is not 0
|
||||
csrrd $t1, 0x20 # read cpu from csr
|
||||
bnez $t1, 1f
|
||||
|
||||
# Enable PG
|
||||
li.w $t0, 0xb0 # PLV=0, IE=0, PG=1
|
||||
csrwr $t0, 0x0 # LOONGARCH_CSR_CRMD
|
||||
li.w $t0, 0x00 # PLV=0, PIE=0, PWE=0
|
||||
csrwr $t0, 0x1 # LOONGARCH_CSR_PRMD
|
||||
li.w $t0, 0x00 # FPE=0, SXE=0, ASXE=0, BTE=0
|
||||
csrwr $t0, 0x2 # LOONGARCH_CSR_EUEN
|
||||
|
||||
|
||||
la.global $sp, {boot_stack}
|
||||
li.d $t0, {boot_stack_size}
|
||||
add.d $sp, $sp, $t0 # setup boot stack
|
||||
csrrd $a0, 0x20 # cpuid
|
||||
la.global $t0, {entry}
|
||||
jirl $zero,$t0,0
|
||||
1:
|
||||
li.w $s0, {MBUF0}
|
||||
iocsrrd.d $t0, $s0
|
||||
la.global $t1, {sec_entry}
|
||||
bne $t0, $t1, 1b
|
||||
jirl $zero, $t1, 0
|
||||
",
|
||||
boot_stack_size = const size_of_val(&crate::arch::process::BSP_IDLE_STACK_SPACE),
|
||||
boot_stack = sym crate::arch::process::BSP_IDLE_STACK_SPACE,
|
||||
MBUF0 = const loongArch64::consts::LOONGARCH_CSR_MAIL_BUF0,
|
||||
entry = sym rust_tmp_main,
|
||||
sec_entry = sym _start_secondary,
|
||||
)
|
||||
}
|
||||
|
||||
/// The earliest entry point for the primary CPU.
|
||||
///
|
||||
/// We can't use bl to jump to higher address, so we use jirl to jump to higher address.
|
||||
#[naked]
|
||||
#[no_mangle]
|
||||
#[link_section = ".text.entry"]
|
||||
pub(crate) unsafe extern "C" fn _start_secondary() -> ! {
|
||||
core::arch::naked_asm!(
|
||||
"
|
||||
ori $t0, $zero, 0x1 # CSR_DMW1_PLV0
|
||||
lu52i.d $t0, $t0, -2048 # UC, PLV0, 0x8000 xxxx xxxx xxxx
|
||||
csrwr $t0, 0x180 # LOONGARCH_CSR_DMWIN0
|
||||
ori $t0, $zero, 0x11 # CSR_DMW1_MAT | CSR_DMW1_PLV0
|
||||
lu52i.d $t0, $t0, -1792 # CA, PLV0, 0x9000 xxxx xxxx xxxx
|
||||
csrwr $t0, 0x181 # LOONGARCH_CSR_DMWIN1
|
||||
|
||||
li.w $t0, {MBUF1}
|
||||
iocsrrd.d $sp, $t0
|
||||
|
||||
csrrd $a0, 0x20 # cpuid
|
||||
la.global $t0, {entry}
|
||||
|
||||
jirl $zero,$t0,0
|
||||
",
|
||||
MBUF1 = const loongArch64::consts::LOONGARCH_CSR_MAIL_BUF1,
|
||||
entry = sym _rust_secondary_main,
|
||||
)
|
||||
}
|
||||
|
||||
/// Rust temporary entry point
|
||||
///
|
||||
/// This function will be called after assembly boot stage.
|
||||
fn rust_tmp_main(hart_id: usize) {
|
||||
unsafe { kernel_main(hart_id, QEMU_DTB_PADDR) };
|
||||
}
|
||||
|
||||
/// The entry point for the second core.
|
||||
pub(crate) extern "C" fn _rust_secondary_main() {
|
||||
unsafe { kernel_main(current_cpu_id().data() as usize, QEMU_DTB_PADDR) }
|
||||
}
|
2
kernel/src/arch/loongarch64/asm/mod.rs
Normal file
2
kernel/src/arch/loongarch64/asm/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod bitops;
|
||||
pub mod boot;
|
15
kernel/src/arch/loongarch64/cpu.rs
Normal file
15
kernel/src/arch/loongarch64/cpu.rs
Normal file
@ -0,0 +1,15 @@
|
||||
use crate::smp::cpu::ProcessorId;
|
||||
|
||||
/// 重置cpu
|
||||
pub unsafe fn cpu_reset() -> ! {
|
||||
log::warn!("cpu_reset on loongarch64 platform was not implemented!");
|
||||
loop {
|
||||
unsafe { loongArch64::asm::idle() };
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取当前cpu的id
|
||||
#[inline]
|
||||
pub fn current_cpu_id() -> ProcessorId {
|
||||
ProcessorId::new(loongArch64::register::cpuid::read().core_id() as u32)
|
||||
}
|
10
kernel/src/arch/loongarch64/elf.rs
Normal file
10
kernel/src/arch/loongarch64/elf.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use crate::{arch::MMArch, libs::elf::ElfArch, mm::MemoryManagementArch};
|
||||
|
||||
#[derive(Debug, Clone, Copy, Hash)]
|
||||
pub struct LoongArch64ElfArch;
|
||||
|
||||
impl ElfArch for LoongArch64ElfArch {
|
||||
const ELF_ET_DYN_BASE: usize = MMArch::USER_END_VADDR.data() / 3 * 2;
|
||||
|
||||
const ELF_PAGE_SIZE: usize = MMArch::PAGE_SIZE;
|
||||
}
|
1
kernel/src/arch/loongarch64/include/asm/asm.h
Normal file
1
kernel/src/arch/loongarch64/include/asm/asm.h
Normal file
@ -0,0 +1 @@
|
||||
#pragma once
|
54
kernel/src/arch/loongarch64/init/boot.rs
Normal file
54
kernel/src/arch/loongarch64/init/boot.rs
Normal file
@ -0,0 +1,54 @@
|
||||
use loongArch64::register::{ecfg, eentry};
|
||||
|
||||
use crate::{init::init::start_kernel, mm::PhysAddr};
|
||||
|
||||
static mut BOOT_HARTID: u32 = 0;
|
||||
static mut BOOT_FDT_PADDR: PhysAddr = PhysAddr::new(0);
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn kernel_main(hartid: usize, fdt_paddr: usize) -> ! {
|
||||
clear_bss();
|
||||
|
||||
let fdt_paddr = PhysAddr::new(fdt_paddr);
|
||||
|
||||
unsafe {
|
||||
BOOT_HARTID = hartid as u32;
|
||||
BOOT_FDT_PADDR = fdt_paddr;
|
||||
}
|
||||
setup_trap_vector();
|
||||
start_kernel();
|
||||
}
|
||||
|
||||
/// 设置中断、异常处理函数
|
||||
fn setup_trap_vector() {
|
||||
// todo!();
|
||||
// let ptr = handle_exception as *const () as usize;
|
||||
// ecfg::set_vs(0);
|
||||
// eentry::set_eentry(handle_exception as usize);
|
||||
}
|
||||
|
||||
/// Clear the bss section
|
||||
fn clear_bss() {
|
||||
extern "C" {
|
||||
fn _bss();
|
||||
fn _ebss();
|
||||
}
|
||||
unsafe {
|
||||
let bss_start = _bss as *mut u8;
|
||||
let bss_end = _ebss as *mut u8;
|
||||
let bss_size = bss_end as usize - bss_start as usize;
|
||||
|
||||
// Clear in chunks of u128 for efficiency
|
||||
let u128_count = bss_size / core::mem::size_of::<u128>();
|
||||
let u128_slice = core::slice::from_raw_parts_mut(bss_start as *mut u128, u128_count);
|
||||
u128_slice.fill(0);
|
||||
|
||||
// Clear any remaining bytes
|
||||
let remaining_bytes = bss_size % core::mem::size_of::<u128>();
|
||||
if remaining_bytes > 0 {
|
||||
let remaining_start = bss_start.add(u128_count * core::mem::size_of::<u128>());
|
||||
let remaining_slice = core::slice::from_raw_parts_mut(remaining_start, remaining_bytes);
|
||||
remaining_slice.fill(0);
|
||||
}
|
||||
}
|
||||
}
|
24
kernel/src/arch/loongarch64/init/mod.rs
Normal file
24
kernel/src/arch/loongarch64/init/mod.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use system_error::SystemError;
|
||||
pub mod boot;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ArchBootParams {}
|
||||
|
||||
impl ArchBootParams {
|
||||
pub const DEFAULT: Self = ArchBootParams {};
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn early_setup_arch() -> Result<(), SystemError> {
|
||||
todo!("la64:early_setup_arch");
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn setup_arch() -> Result<(), SystemError> {
|
||||
todo!("la64:setup_arch");
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn setup_arch_post() -> Result<(), SystemError> {
|
||||
todo!("la64:setup_arch_post");
|
||||
}
|
6
kernel/src/arch/loongarch64/interrupt/ipi.rs
Normal file
6
kernel/src/arch/loongarch64/interrupt/ipi.rs
Normal file
@ -0,0 +1,6 @@
|
||||
use crate::exception::ipi::{IpiKind, IpiTarget};
|
||||
|
||||
#[inline(always)]
|
||||
pub fn send_ipi(kind: IpiKind, target: IpiTarget) {
|
||||
todo!("la64: send_ipi")
|
||||
}
|
123
kernel/src/arch/loongarch64/interrupt/mod.rs
Normal file
123
kernel/src/arch/loongarch64/interrupt/mod.rs
Normal file
@ -0,0 +1,123 @@
|
||||
pub mod ipi;
|
||||
|
||||
use core::any::Any;
|
||||
|
||||
use kprobe::ProbeArgs;
|
||||
use loongArch64::register::CpuMode;
|
||||
|
||||
use crate::exception::{InterruptArch, IrqFlags, IrqFlagsGuard, IrqNumber};
|
||||
|
||||
pub struct LoongArch64InterruptArch;
|
||||
|
||||
impl InterruptArch for LoongArch64InterruptArch {
|
||||
unsafe fn arch_irq_init() -> Result<(), system_error::SystemError> {
|
||||
todo!("arch_irq_init() not implemented for LoongArch64InterruptArch")
|
||||
}
|
||||
|
||||
unsafe fn interrupt_enable() {
|
||||
loongArch64::register::crmd::set_ie(true);
|
||||
}
|
||||
|
||||
unsafe fn interrupt_disable() {
|
||||
loongArch64::register::crmd::set_ie(false);
|
||||
}
|
||||
|
||||
fn is_irq_enabled() -> bool {
|
||||
loongArch64::register::crmd::read().ie()
|
||||
}
|
||||
|
||||
unsafe fn save_and_disable_irq() -> IrqFlagsGuard {
|
||||
let ie = loongArch64::register::crmd::read().ie();
|
||||
loongArch64::register::crmd::set_ie(false);
|
||||
IrqFlagsGuard::new(IrqFlags::new(if ie { 1 } else { 0 }))
|
||||
}
|
||||
|
||||
unsafe fn restore_irq(flags: IrqFlags) {
|
||||
loongArch64::register::crmd::set_ie(flags.flags() == 1);
|
||||
}
|
||||
|
||||
fn probe_total_irq_num() -> u32 {
|
||||
todo!("probe_total_irq_num() not implemented for LoongArch64InterruptArch")
|
||||
}
|
||||
|
||||
fn ack_bad_irq(irq: IrqNumber) {
|
||||
todo!("ack_bad_irq() not implemented for LoongArch64InterruptArch")
|
||||
}
|
||||
}
|
||||
|
||||
/// 中断栈帧结构体
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct TrapFrame {
|
||||
pub r0: usize, // 0*8
|
||||
pub ra: usize, // 1*8
|
||||
pub tp: usize, // 2*8
|
||||
pub usp: usize, // 3*8 (user stack pointer)
|
||||
pub a0: usize, // 4*8
|
||||
pub a1: usize, // 5*8
|
||||
pub a2: usize, // 6*8
|
||||
pub a3: usize, // 7*8
|
||||
pub a4: usize, // 8*8
|
||||
pub a5: usize, // 9*8
|
||||
pub a6: usize, // 10*8
|
||||
pub a7: usize, // 11*8
|
||||
pub t0: usize, // 12*8
|
||||
pub t1: usize, // 13*8
|
||||
pub t2: usize, // 14*8
|
||||
pub t3: usize, // 15*8
|
||||
pub t4: usize, // 16*8
|
||||
pub t5: usize, // 17*8
|
||||
pub t6: usize, // 18*8
|
||||
pub t7: usize, // 19*8
|
||||
pub t8: usize, // 20*8
|
||||
pub r21: usize, // 21*8
|
||||
pub fp: usize, // 22*8
|
||||
pub s0: usize, // 23*8
|
||||
pub s1: usize, // 24*8
|
||||
pub s2: usize, // 25*8
|
||||
pub s3: usize, // 26*8
|
||||
pub s4: usize, // 27*8
|
||||
pub s5: usize, // 28*8
|
||||
pub s6: usize, // 29*8
|
||||
pub s7: usize, // 30*8
|
||||
pub s8: usize, // 31*8
|
||||
/// original syscall arg0
|
||||
pub orig_a0: usize,
|
||||
|
||||
pub csr_era: usize,
|
||||
pub csr_badvaddr: usize,
|
||||
pub csr_crmd: usize,
|
||||
pub csr_prmd: usize,
|
||||
pub csr_euen: usize,
|
||||
pub csr_ecfg: usize,
|
||||
pub csr_estat: usize,
|
||||
}
|
||||
|
||||
impl TrapFrame {
|
||||
/// 中断栈帧结构体的大小
|
||||
pub const SIZE: usize = core::mem::size_of::<TrapFrame>();
|
||||
|
||||
/// 判断当前中断是否来自用户模式
|
||||
pub fn is_from_user(&self) -> bool {
|
||||
loongArch64::register::crmd::Crmd::from(self.csr_crmd).plv() == CpuMode::Ring3
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub const fn new() -> Self {
|
||||
let x = core::mem::MaybeUninit::<Self>::zeroed();
|
||||
unsafe { x.assume_init() }
|
||||
}
|
||||
}
|
||||
|
||||
impl ProbeArgs for TrapFrame {
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
fn break_address(&self) -> usize {
|
||||
todo!("TrapFrame::break_address()")
|
||||
}
|
||||
|
||||
fn debug_address(&self) -> usize {
|
||||
todo!("TrapFrame::debug_address()")
|
||||
}
|
||||
}
|
1
kernel/src/arch/loongarch64/ipc/mod.rs
Normal file
1
kernel/src/arch/loongarch64/ipc/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod signal;
|
64
kernel/src/arch/loongarch64/ipc/signal.rs
Normal file
64
kernel/src/arch/loongarch64/ipc/signal.rs
Normal file
@ -0,0 +1,64 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
pub use crate::ipc::generic_signal::AtomicGenericSignal as AtomicSignal;
|
||||
pub use crate::ipc::generic_signal::GenericSigChildCode as SigChildCode;
|
||||
pub use crate::ipc::generic_signal::GenericSigSet as SigSet;
|
||||
pub use crate::ipc::generic_signal::GenericSignal as Signal;
|
||||
pub use crate::ipc::generic_signal::GENERIC_MAX_SIG_NUM as MAX_SIG_NUM;
|
||||
pub use crate::ipc::generic_signal::GENERIC_STACK_ALIGN as STACK_ALIGN;
|
||||
|
||||
pub use crate::ipc::generic_signal::GenericSigFlags as SigFlags;
|
||||
|
||||
use crate::ipc::signal_types::SignalArch;
|
||||
|
||||
pub struct LoongArch64SignalArch;
|
||||
|
||||
impl SignalArch for LoongArch64SignalArch {
|
||||
// TODO: 为LoongArch64实现信号处理
|
||||
// 注意,la64现在在中断/系统调用返回用户态时,没有进入 irqentry_exit() 函数,
|
||||
// 到时候实现信号处理时,需要修改中断/系统调用返回用户态的代码,进入 irqentry_exit() 函数
|
||||
unsafe fn do_signal_or_restart(_frame: &mut TrapFrame) {
|
||||
todo!("la64:do_signal_or_restart")
|
||||
}
|
||||
|
||||
fn sys_rt_sigreturn(_trap_frame: &mut TrapFrame) -> u64 {
|
||||
todo!("la64:sys_rt_sigreturn")
|
||||
}
|
||||
}
|
||||
|
||||
/// siginfo中的si_code的可选值
|
||||
/// 请注意,当这个值小于0时,表示siginfo来自用户态,否则来自内核态
|
||||
#[derive(Copy, Debug, Clone)]
|
||||
#[repr(i32)]
|
||||
pub enum SigCode {
|
||||
/// sent by kill, sigsend, raise
|
||||
User = 0,
|
||||
/// sent by kernel from somewhere
|
||||
Kernel = 0x80,
|
||||
/// 通过sigqueue发送
|
||||
Queue = -1,
|
||||
/// 定时器过期时发送
|
||||
Timer = -2,
|
||||
/// 当实时消息队列的状态发生改变时发送
|
||||
Mesgq = -3,
|
||||
/// 当异步IO完成时发送
|
||||
AsyncIO = -4,
|
||||
/// sent by queued SIGIO
|
||||
SigIO = -5,
|
||||
}
|
||||
|
||||
impl SigCode {
|
||||
/// 为SigCode这个枚举类型实现从i32转换到枚举类型的转换函数
|
||||
#[allow(dead_code)]
|
||||
pub fn from_i32(x: i32) -> SigCode {
|
||||
match x {
|
||||
0 => Self::User,
|
||||
0x80 => Self::Kernel,
|
||||
-1 => Self::Queue,
|
||||
-2 => Self::Timer,
|
||||
-3 => Self::Mesgq,
|
||||
-4 => Self::AsyncIO,
|
||||
-5 => Self::SigIO,
|
||||
_ => panic!("signal code not valid"),
|
||||
}
|
||||
}
|
||||
}
|
19
kernel/src/arch/loongarch64/kprobe.rs
Normal file
19
kernel/src/arch/loongarch64/kprobe.rs
Normal file
@ -0,0 +1,19 @@
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
|
||||
pub fn setup_single_step(frame: &mut TrapFrame, step_addr: usize) {
|
||||
todo!("la64: setup_single_step")
|
||||
}
|
||||
|
||||
pub fn clear_single_step(frame: &mut TrapFrame, return_addr: usize) {
|
||||
todo!("la64: clear_single_step")
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct KProbeContext {}
|
||||
|
||||
impl From<&TrapFrame> for KProbeContext {
|
||||
fn from(trap_frame: &TrapFrame) -> Self {
|
||||
todo!("from trap frame to kprobe context");
|
||||
}
|
||||
}
|
104
kernel/src/arch/loongarch64/link.ld
Normal file
104
kernel/src/arch/loongarch64/link.ld
Normal file
@ -0,0 +1,104 @@
|
||||
OUTPUT_FORMAT(
|
||||
"elf64-loongarch",
|
||||
"elf64-loongarch",
|
||||
"elf64-loongarch"
|
||||
)
|
||||
|
||||
OUTPUT_ARCH(loongarch)
|
||||
ENTRY(_start)
|
||||
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
KERNEL_VMA = 0x9000000000200000;
|
||||
. = KERNEL_VMA;
|
||||
. = ALIGN(4096);
|
||||
boot_text_start_pa = .;
|
||||
.boot.text :
|
||||
{
|
||||
KEEP(*(.bootstrap))
|
||||
*(.bootstrap)
|
||||
*(.bootstrap.*)
|
||||
. = ALIGN(4096);
|
||||
*(.initial_pgtable_section)
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
|
||||
|
||||
. = ALIGN(4096);
|
||||
text_start_pa = .;
|
||||
__executable_start = .;
|
||||
.text (text_start_pa):
|
||||
{
|
||||
_text = .;
|
||||
|
||||
/* any files' .text */
|
||||
*(.text)
|
||||
|
||||
/* any files' .text.*, for example: rust .text._ZN* */
|
||||
*(.text.*)
|
||||
|
||||
_etext = .;
|
||||
__etext = .;
|
||||
}
|
||||
. = ALIGN(32768);
|
||||
data_start_pa = .;
|
||||
.data (data_start_pa):
|
||||
{
|
||||
_data = .;
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.got.plt)
|
||||
*(.got)
|
||||
_edata = .;
|
||||
}
|
||||
|
||||
. = ALIGN(32768);
|
||||
|
||||
rodata_start_pa = .;
|
||||
.rodata (rodata_start_pa):
|
||||
{
|
||||
_rodata = .;
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.gcc_except_table .gcc_except_table.*)
|
||||
_erodata = .;
|
||||
}
|
||||
|
||||
. = ALIGN(32768);
|
||||
|
||||
init_proc_union_start_pa = .;
|
||||
.data.init_proc_union (init_proc_union_start_pa):
|
||||
{ *(.data.init_proc_union) }
|
||||
|
||||
. = ALIGN(32768);
|
||||
bss_start_pa = .;
|
||||
.bss (bss_start_pa):
|
||||
{
|
||||
_bss = .;
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
_ebss = .;
|
||||
}
|
||||
|
||||
eh_frame = .;
|
||||
.eh_frame (eh_frame):
|
||||
{
|
||||
__eh_frame_hdr_start = .;
|
||||
*(.eh_frame_hdr)
|
||||
__eh_frame_hdr_end = .;
|
||||
__eh_frame_start = .;
|
||||
*(.eh_frame)
|
||||
*(.rela.eh_frame)
|
||||
__eh_frame_end = .;
|
||||
}
|
||||
|
||||
_end = .;
|
||||
|
||||
/DISCARD/ : {
|
||||
/* *(.eh_frame) */
|
||||
|
||||
}
|
||||
}
|
21
kernel/src/arch/loongarch64/loongarch64-unknown-none.json
Normal file
21
kernel/src/arch/loongarch64/loongarch64-unknown-none.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"arch": "loongarch64",
|
||||
"code-model": "medium",
|
||||
"crt-objects-fallback": "false",
|
||||
"data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
|
||||
"features": "+f,+d",
|
||||
"linker": "rust-lld",
|
||||
"linker-flavor": "gnu-lld",
|
||||
"llvm-abiname": "lp64d",
|
||||
"llvm-target": "loongarch64-unknown-none",
|
||||
"max-atomic-width": 64,
|
||||
"metadata": {
|
||||
"description": "Freestanding/bare-metal LoongArch64",
|
||||
"host_tools": false,
|
||||
"std": false,
|
||||
"tier": 2
|
||||
},
|
||||
"panic-strategy": "abort",
|
||||
"relocation-model": "static",
|
||||
"target-pointer-width": "64"
|
||||
}
|
7
kernel/src/arch/loongarch64/mm/bump.rs
Normal file
7
kernel/src/arch/loongarch64/mm/bump.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use crate::mm::{allocator::bump::BumpAllocator, MemoryManagementArch, PhysMemoryArea};
|
||||
|
||||
impl<MMA: MemoryManagementArch> BumpAllocator<MMA> {
|
||||
pub unsafe fn arch_remain_areas(_ret_areas: &mut [PhysMemoryArea], res_count: usize) -> usize {
|
||||
todo!("la64: arch_remain_areas")
|
||||
}
|
||||
}
|
207
kernel/src/arch/loongarch64/mm/mod.rs
Normal file
207
kernel/src/arch/loongarch64/mm/mod.rs
Normal file
@ -0,0 +1,207 @@
|
||||
pub mod bump;
|
||||
|
||||
use crate::mm::{
|
||||
allocator::page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage},
|
||||
page::EntryFlags,
|
||||
MemoryManagementArch, PhysAddr, VirtAddr, VmFlags,
|
||||
};
|
||||
|
||||
use crate::arch::MMArch;
|
||||
|
||||
pub type PageMapper = crate::mm::page::PageMapper<LoongArch64MMArch, LockedFrameAllocator>;
|
||||
|
||||
/// LoongArch64的内存管理架构结构体
|
||||
#[derive(Debug, Clone, Copy, Hash)]
|
||||
pub struct LoongArch64MMArch;
|
||||
|
||||
impl MemoryManagementArch for LoongArch64MMArch {
|
||||
const PAGE_FAULT_ENABLED: bool = false;
|
||||
|
||||
const PAGE_SHIFT: usize = 0;
|
||||
|
||||
const PAGE_ENTRY_SHIFT: usize = 0;
|
||||
|
||||
const PAGE_LEVELS: usize = 0;
|
||||
|
||||
const ENTRY_ADDRESS_SHIFT: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_DEFAULT_PAGE: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_DEFAULT_TABLE: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_PRESENT: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_READONLY: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_WRITEABLE: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_READWRITE: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_USER: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_WRITE_THROUGH: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_CACHE_DISABLE: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_NO_EXEC: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_EXEC: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_DIRTY: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_ACCESSED: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_HUGE_PAGE: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_GLOBAL: usize = 0;
|
||||
|
||||
const PHYS_OFFSET: usize = 0x9000_0000_0000_0000;
|
||||
|
||||
const KERNEL_LINK_OFFSET: usize = 0;
|
||||
|
||||
const USER_END_VADDR: crate::mm::VirtAddr = VirtAddr::new(0);
|
||||
|
||||
const USER_BRK_START: crate::mm::VirtAddr = VirtAddr::new(0);
|
||||
|
||||
const USER_STACK_START: crate::mm::VirtAddr = VirtAddr::new(0);
|
||||
|
||||
const FIXMAP_START_VADDR: crate::mm::VirtAddr = VirtAddr::new(0);
|
||||
|
||||
const FIXMAP_SIZE: usize = 0;
|
||||
|
||||
const MMIO_BASE: crate::mm::VirtAddr = VirtAddr::new(0);
|
||||
|
||||
const MMIO_SIZE: usize = 0;
|
||||
|
||||
const PAGE_NONE: usize = 0;
|
||||
|
||||
const PAGE_SHARED: usize = 0;
|
||||
|
||||
const PAGE_SHARED_EXEC: usize = 0;
|
||||
|
||||
const PAGE_COPY_NOEXEC: usize = 0;
|
||||
|
||||
const PAGE_COPY_EXEC: usize = 0;
|
||||
|
||||
const PAGE_COPY: usize = 0;
|
||||
|
||||
const PAGE_READONLY: usize = 0;
|
||||
|
||||
const PAGE_READONLY_EXEC: usize = 0;
|
||||
|
||||
const PAGE_READ: usize = 0;
|
||||
|
||||
const PAGE_READ_EXEC: usize = 0;
|
||||
|
||||
const PAGE_WRITE: usize = 0;
|
||||
|
||||
const PAGE_WRITE_EXEC: usize = 0;
|
||||
|
||||
const PAGE_EXEC: usize = 0;
|
||||
|
||||
const PROTECTION_MAP: [crate::mm::page::EntryFlags<Self>; 16] = protection_map();
|
||||
|
||||
unsafe fn init() {
|
||||
todo!()
|
||||
}
|
||||
|
||||
unsafe fn invalidate_page(address: crate::mm::VirtAddr) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
unsafe fn invalidate_all() {
|
||||
todo!()
|
||||
}
|
||||
|
||||
unsafe fn table(table_kind: crate::mm::PageTableKind) -> crate::mm::PhysAddr {
|
||||
todo!()
|
||||
}
|
||||
|
||||
unsafe fn set_table(table_kind: crate::mm::PageTableKind, table: crate::mm::PhysAddr) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn virt_is_valid(virt: crate::mm::VirtAddr) -> bool {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn initial_page_table() -> crate::mm::PhysAddr {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn setup_new_usermapper() -> Result<crate::mm::ucontext::UserMapper, system_error::SystemError>
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn make_entry(paddr: crate::mm::PhysAddr, page_flags: usize) -> usize {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取内核地址默认的页面标志
|
||||
pub unsafe fn kernel_page_flags<A: MemoryManagementArch>(_virt: VirtAddr) -> EntryFlags<A> {
|
||||
EntryFlags::from_data(LoongArch64MMArch::ENTRY_FLAG_DEFAULT_PAGE)
|
||||
.set_user(false)
|
||||
.set_execute(true)
|
||||
}
|
||||
|
||||
/// 全局的页帧分配器
|
||||
#[derive(Debug, Clone, Copy, Hash)]
|
||||
pub struct LockedFrameAllocator;
|
||||
|
||||
impl FrameAllocator for LockedFrameAllocator {
|
||||
unsafe fn allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> {
|
||||
todo!("LockedFrameAllocator::allocate")
|
||||
}
|
||||
|
||||
unsafe fn free(&mut self, address: PhysAddr, count: PageFrameCount) {
|
||||
todo!("LockedFrameAllocator::free")
|
||||
}
|
||||
|
||||
unsafe fn usage(&self) -> PageFrameUsage {
|
||||
todo!("LockedFrameAllocator::usage")
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取保护标志的映射表
|
||||
///
|
||||
///
|
||||
/// ## 返回值
|
||||
/// - `[usize; 16]`: 长度为16的映射表
|
||||
const fn protection_map() -> [EntryFlags<MMArch>; 16] {
|
||||
let mut map = [unsafe { EntryFlags::from_data(0) }; 16];
|
||||
unsafe {
|
||||
map[VmFlags::VM_NONE.bits()] = EntryFlags::from_data(MMArch::PAGE_NONE);
|
||||
map[VmFlags::VM_READ.bits()] = EntryFlags::from_data(MMArch::PAGE_READONLY);
|
||||
map[VmFlags::VM_WRITE.bits()] = EntryFlags::from_data(MMArch::PAGE_COPY);
|
||||
map[VmFlags::VM_WRITE.bits() | VmFlags::VM_READ.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_COPY);
|
||||
map[VmFlags::VM_EXEC.bits()] = EntryFlags::from_data(MMArch::PAGE_READONLY_EXEC);
|
||||
map[VmFlags::VM_EXEC.bits() | VmFlags::VM_READ.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_READONLY_EXEC);
|
||||
map[VmFlags::VM_EXEC.bits() | VmFlags::VM_WRITE.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_COPY_EXEC);
|
||||
map[VmFlags::VM_EXEC.bits() | VmFlags::VM_WRITE.bits() | VmFlags::VM_READ.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_COPY_EXEC);
|
||||
map[VmFlags::VM_SHARED.bits()] = EntryFlags::from_data(MMArch::PAGE_NONE);
|
||||
map[VmFlags::VM_SHARED.bits() | VmFlags::VM_READ.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_READONLY);
|
||||
map[VmFlags::VM_SHARED.bits() | VmFlags::VM_WRITE.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_SHARED);
|
||||
map[VmFlags::VM_SHARED.bits() | VmFlags::VM_WRITE.bits() | VmFlags::VM_READ.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_SHARED);
|
||||
map[VmFlags::VM_SHARED.bits() | VmFlags::VM_EXEC.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_READONLY_EXEC);
|
||||
map[VmFlags::VM_SHARED.bits() | VmFlags::VM_EXEC.bits() | VmFlags::VM_READ.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_READONLY_EXEC);
|
||||
map[VmFlags::VM_SHARED.bits() | VmFlags::VM_EXEC.bits() | VmFlags::VM_WRITE.bits()] =
|
||||
EntryFlags::from_data(MMArch::PAGE_SHARED_EXEC);
|
||||
map[VmFlags::VM_SHARED.bits()
|
||||
| VmFlags::VM_EXEC.bits()
|
||||
| VmFlags::VM_WRITE.bits()
|
||||
| VmFlags::VM_READ.bits()] = EntryFlags::from_data(MMArch::PAGE_SHARED_EXEC);
|
||||
}
|
||||
|
||||
map
|
||||
}
|
30
kernel/src/arch/loongarch64/mod.rs
Normal file
30
kernel/src/arch/loongarch64/mod.rs
Normal file
@ -0,0 +1,30 @@
|
||||
pub mod asm;
|
||||
pub mod cpu;
|
||||
pub mod elf;
|
||||
pub mod init;
|
||||
pub mod interrupt;
|
||||
pub mod ipc;
|
||||
pub mod kprobe;
|
||||
pub mod mm;
|
||||
pub mod msi;
|
||||
pub mod pci;
|
||||
pub mod pio;
|
||||
pub mod process;
|
||||
pub mod rand;
|
||||
pub mod sched;
|
||||
pub mod smp;
|
||||
pub mod syscall;
|
||||
pub mod time;
|
||||
|
||||
pub use self::elf::LoongArch64ElfArch as CurrentElfArch;
|
||||
pub use self::interrupt::LoongArch64InterruptArch as CurrentIrqArch;
|
||||
pub use self::ipc::signal::LoongArch64SignalArch as CurrentSignalArch;
|
||||
pub use self::mm::LoongArch64MMArch as MMArch;
|
||||
pub use self::pci::LoongArch64PciArch as PciArch;
|
||||
pub use self::pio::LoongArch64PortIOArch as CurrentPortIOArch;
|
||||
pub use self::sched::LoongArch64SchedArch as CurrentSchedArch;
|
||||
pub use self::smp::LoongArch64SMPArch as CurrentSMPArch;
|
||||
pub use self::time::LoongArch64TimeArch as CurrentTimeArch;
|
||||
|
||||
pub fn panic_pre_work() {}
|
||||
pub fn panic_post_work() {}
|
24
kernel/src/arch/loongarch64/msi.rs
Normal file
24
kernel/src/arch/loongarch64/msi.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use crate::driver::pci::pci_irq::TriggerMode;
|
||||
|
||||
/// 获得MSI Message Address
|
||||
///
|
||||
/// # 参数
|
||||
/// - `processor`: 目标CPU ID号
|
||||
///
|
||||
/// # 返回值
|
||||
/// MSI Message Address
|
||||
pub fn arch_msi_message_address(_processor: u16) -> u32 {
|
||||
unimplemented!("loongarch64::arch_msi_message_address()")
|
||||
}
|
||||
/// 获得MSI Message Data
|
||||
///
|
||||
/// # 参数
|
||||
/// - `vector`: 分配的中断向量号
|
||||
/// - `processor`: 目标CPU ID号
|
||||
/// - `trigger`: 申请中断的触发模式,MSI默认为边沿触发
|
||||
///
|
||||
/// # 返回值
|
||||
/// MSI Message Address
|
||||
pub fn arch_msi_message_data(_vector: u16, _processor: u16, _trigger: TriggerMode) -> u32 {
|
||||
unimplemented!("loongarch64::arch_msi_message_data()")
|
||||
}
|
20
kernel/src/arch/loongarch64/pci/mod.rs
Normal file
20
kernel/src/arch/loongarch64/pci/mod.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use crate::{
|
||||
arch::TraitPciArch,
|
||||
driver::pci::pci::{BusDeviceFunction, PciAddr},
|
||||
mm::PhysAddr,
|
||||
};
|
||||
|
||||
pub struct LoongArch64PciArch;
|
||||
impl TraitPciArch for LoongArch64PciArch {
|
||||
fn read_config(_bus_device_function: &BusDeviceFunction, _offset: u8) -> u32 {
|
||||
unimplemented!("LoongArch64PciArch::read_config")
|
||||
}
|
||||
|
||||
fn write_config(_bus_device_function: &BusDeviceFunction, _offset: u8, _data: u32) {
|
||||
unimplemented!("LoongArch64PciArch pci_root_0().write_config")
|
||||
}
|
||||
|
||||
fn address_pci_to_physical(pci_address: PciAddr) -> crate::mm::PhysAddr {
|
||||
return PhysAddr::new(pci_address.data());
|
||||
}
|
||||
}
|
35
kernel/src/arch/loongarch64/pio.rs
Normal file
35
kernel/src/arch/loongarch64/pio.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use crate::arch::io::PortIOArch;
|
||||
|
||||
pub struct LoongArch64PortIOArch;
|
||||
|
||||
impl PortIOArch for LoongArch64PortIOArch {
|
||||
#[inline(always)]
|
||||
unsafe fn in8(_port: u16) -> u8 {
|
||||
unimplemented!("LoongArch64PortIOArch::in8")
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn in16(_port: u16) -> u16 {
|
||||
unimplemented!("LoongArch64PortIOArch::in16")
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn in32(_port: u16) -> u32 {
|
||||
unimplemented!("LoongArch64PortIOArch::in32")
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn out8(_port: u16, _data: u8) {
|
||||
unimplemented!("LoongArch64PortIOArch::out8")
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn out16(_port: u16, _data: u16) {
|
||||
unimplemented!("LoongArch64PortIOArch::out16")
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn out32(_port: u16, _data: u32) {
|
||||
unimplemented!("LoongArch64PortIOArch::out32")
|
||||
}
|
||||
}
|
31
kernel/src/arch/loongarch64/process/idle.rs
Normal file
31
kernel/src/arch/loongarch64/process/idle.rs
Normal file
@ -0,0 +1,31 @@
|
||||
use core::hint::spin_loop;
|
||||
|
||||
use log::error;
|
||||
|
||||
use crate::{
|
||||
arch::CurrentIrqArch,
|
||||
exception::InterruptArch,
|
||||
process::{ProcessFlags, ProcessManager},
|
||||
sched::{SchedMode, __schedule},
|
||||
};
|
||||
|
||||
impl ProcessManager {
|
||||
/// 每个核的idle进程
|
||||
pub fn arch_idle_func() -> ! {
|
||||
loop {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
if pcb.flags().contains(ProcessFlags::NEED_SCHEDULE) {
|
||||
__schedule(SchedMode::SM_NONE);
|
||||
}
|
||||
if CurrentIrqArch::is_irq_enabled() {
|
||||
todo!("la64: arch_idle_func");
|
||||
// unsafe {
|
||||
// x86::halt();
|
||||
// }
|
||||
} else {
|
||||
error!("Idle process should not be scheduled with IRQs disabled.");
|
||||
spin_loop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
kernel/src/arch/loongarch64/process/kthread.rs
Normal file
27
kernel/src/arch/loongarch64/process/kthread.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use system_error::SystemError;
|
||||
|
||||
use alloc::sync::Arc;
|
||||
|
||||
use crate::process::{
|
||||
fork::CloneFlags,
|
||||
kthread::{KernelThreadCreateInfo, KernelThreadMechanism},
|
||||
Pid,
|
||||
};
|
||||
|
||||
impl KernelThreadMechanism {
|
||||
/// 伪造trapframe,创建内核线程
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 返回创建的内核线程的pid
|
||||
pub fn __inner_create(
|
||||
info: &Arc<KernelThreadCreateInfo>,
|
||||
clone_flags: CloneFlags,
|
||||
) -> Result<Pid, SystemError> {
|
||||
// WARNING: If create failed, we must drop the info manually or it will cause memory leak. (refcount will not decrease when create failed)
|
||||
let create_info: *const KernelThreadCreateInfo =
|
||||
KernelThreadCreateInfo::generate_unsafe_arc_ptr(info.clone());
|
||||
|
||||
todo!("la64:__inner_create()")
|
||||
}
|
||||
}
|
90
kernel/src/arch/loongarch64/process/mod.rs
Normal file
90
kernel/src/arch/loongarch64/process/mod.rs
Normal file
@ -0,0 +1,90 @@
|
||||
use alloc::sync::Arc;
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
arch::CurrentIrqArch,
|
||||
exception::InterruptArch,
|
||||
mm::VirtAddr,
|
||||
process::{fork::KernelCloneArgs, KernelStack, ProcessControlBlock, ProcessManager},
|
||||
};
|
||||
|
||||
use super::interrupt::TrapFrame;
|
||||
|
||||
pub mod idle;
|
||||
pub mod kthread;
|
||||
pub mod syscall;
|
||||
|
||||
#[repr(align(32768))]
|
||||
pub union InitProcUnion {
|
||||
/// 用于存放idle进程的内核栈
|
||||
idle_stack: [u8; 32768],
|
||||
}
|
||||
|
||||
#[link_section = ".data.init_proc_union"]
|
||||
#[no_mangle]
|
||||
pub(super) static BSP_IDLE_STACK_SPACE: InitProcUnion = InitProcUnion {
|
||||
idle_stack: [0; 32768],
|
||||
};
|
||||
|
||||
pub unsafe fn arch_switch_to_user(trap_frame: TrapFrame) -> ! {
|
||||
// 以下代码不能发生中断
|
||||
CurrentIrqArch::interrupt_disable();
|
||||
|
||||
todo!("la64: arch_switch_to_user")
|
||||
}
|
||||
|
||||
/// PCB中与架构相关的信息
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[allow(dead_code)]
|
||||
#[repr(C)]
|
||||
pub struct ArchPCBInfo {}
|
||||
|
||||
impl ArchPCBInfo {
|
||||
/// 创建一个新的ArchPCBInfo
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `kstack`:内核栈的引用
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 返回一个新的ArchPCBInfo
|
||||
pub fn new(kstack: &KernelStack) -> Self {
|
||||
todo!("la64: ArchPCBInfo::new")
|
||||
}
|
||||
}
|
||||
|
||||
impl ProcessControlBlock {
|
||||
/// 获取当前进程的pcb
|
||||
pub fn arch_current_pcb() -> Arc<Self> {
|
||||
todo!("la64: arch_current_pcb")
|
||||
}
|
||||
}
|
||||
|
||||
impl ProcessManager {
|
||||
pub fn arch_init() {
|
||||
// do nothing
|
||||
}
|
||||
/// fork的过程中复制线程
|
||||
///
|
||||
/// 由于这个过程与具体的架构相关,所以放在这里
|
||||
pub fn copy_thread(
|
||||
current_pcb: &Arc<ProcessControlBlock>,
|
||||
new_pcb: &Arc<ProcessControlBlock>,
|
||||
clone_args: &KernelCloneArgs,
|
||||
current_trapframe: &TrapFrame,
|
||||
) -> Result<(), SystemError> {
|
||||
todo!("la64: copy_thread")
|
||||
}
|
||||
|
||||
/// 切换进程
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `prev`:上一个进程的pcb
|
||||
/// - `next`:下一个进程的pcb
|
||||
pub unsafe fn switch_process(prev: Arc<ProcessControlBlock>, next: Arc<ProcessControlBlock>) {
|
||||
assert!(!CurrentIrqArch::is_irq_enabled());
|
||||
todo!("la64: switch_process");
|
||||
}
|
||||
}
|
28
kernel/src/arch/loongarch64/process/syscall.rs
Normal file
28
kernel/src/arch/loongarch64/process/syscall.rs
Normal file
@ -0,0 +1,28 @@
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
arch::interrupt::TrapFrame,
|
||||
mm::VirtAddr,
|
||||
process::{
|
||||
exec::{BinaryLoaderResult, ExecParam},
|
||||
ProcessManager,
|
||||
},
|
||||
syscall::Syscall,
|
||||
};
|
||||
|
||||
impl Syscall {
|
||||
pub fn arch_do_execve(
|
||||
regs: &mut TrapFrame,
|
||||
param: &ExecParam,
|
||||
load_result: &BinaryLoaderResult,
|
||||
user_sp: VirtAddr,
|
||||
argv_ptr: VirtAddr,
|
||||
) -> Result<(), SystemError> {
|
||||
todo!("la64:arch_do_execve not unimplemented");
|
||||
}
|
||||
|
||||
/// ## 用于控制和查询与体系结构相关的进程特定选项
|
||||
pub fn arch_prctl(option: usize, arg2: usize) -> Result<usize, SystemError> {
|
||||
todo!("la64:arch_prctl")
|
||||
}
|
||||
}
|
5
kernel/src/arch/loongarch64/rand.rs
Normal file
5
kernel/src/arch/loongarch64/rand.rs
Normal file
@ -0,0 +1,5 @@
|
||||
use crate::libs::rand::soft_rand;
|
||||
|
||||
pub fn rand() -> usize {
|
||||
return soft_rand();
|
||||
}
|
17
kernel/src/arch/loongarch64/sched.rs
Normal file
17
kernel/src/arch/loongarch64/sched.rs
Normal file
@ -0,0 +1,17 @@
|
||||
use crate::sched::SchedArch;
|
||||
|
||||
pub struct LoongArch64SchedArch;
|
||||
|
||||
impl SchedArch for LoongArch64SchedArch {
|
||||
fn enable_sched_local() {
|
||||
todo!("LoongArch64::enable_sched_local")
|
||||
}
|
||||
|
||||
fn disable_sched_local() {
|
||||
todo!("LoongArch64::disable_sched_local")
|
||||
}
|
||||
|
||||
fn initial_setup_sched_local() {
|
||||
todo!("LoongArch64::initial_setup_sched_local")
|
||||
}
|
||||
}
|
29
kernel/src/arch/loongarch64/smp/mod.rs
Normal file
29
kernel/src/arch/loongarch64/smp/mod.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use log::warn;
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::smp::{
|
||||
cpu::{CpuHpCpuState, ProcessorId, SmpCpuManager},
|
||||
SMPArch,
|
||||
};
|
||||
|
||||
pub struct LoongArch64SMPArch;
|
||||
|
||||
impl SMPArch for LoongArch64SMPArch {
|
||||
#[inline(never)]
|
||||
fn prepare_cpus() -> Result<(), SystemError> {
|
||||
warn!("LoongArch64SMPArch::prepare_cpus() is not implemented");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn start_cpu(_cpu_id: ProcessorId, _hp_state: &CpuHpCpuState) -> Result<(), SystemError> {
|
||||
warn!("LoongArch64SMPArch::start_cpu() is not implemented");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl SmpCpuManager {
|
||||
pub fn arch_init(_boot_cpu: ProcessorId) {
|
||||
// todo: 读取所有可用的CPU
|
||||
todo!("la64:SmpCpuManager::arch_init()")
|
||||
}
|
||||
}
|
8
kernel/src/arch/loongarch64/syscall/mod.rs
Normal file
8
kernel/src/arch/loongarch64/syscall/mod.rs
Normal file
@ -0,0 +1,8 @@
|
||||
use system_error::SystemError;
|
||||
|
||||
pub mod nr;
|
||||
|
||||
/// 系统调用初始化
|
||||
pub fn arch_syscall_init() -> Result<(), SystemError> {
|
||||
todo!("la64:arch_syscall_init");
|
||||
}
|
307
kernel/src/arch/loongarch64/syscall/nr.rs
Normal file
307
kernel/src/arch/loongarch64/syscall/nr.rs
Normal file
@ -0,0 +1,307 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
pub const SYS_IO_SETUP: usize = 0;
|
||||
pub const SYS_IO_DESTROY: usize = 1;
|
||||
pub const SYS_IO_SUBMIT: usize = 2;
|
||||
pub const SYS_IO_CANCEL: usize = 3;
|
||||
pub const SYS_IO_GETEVENTS: usize = 4;
|
||||
pub const SYS_SETXATTR: usize = 5;
|
||||
pub const SYS_LSETXATTR: usize = 6;
|
||||
pub const SYS_FSETXATTR: usize = 7;
|
||||
pub const SYS_GETXATTR: usize = 8;
|
||||
pub const SYS_LGETXATTR: usize = 9;
|
||||
pub const SYS_FGETXATTR: usize = 10;
|
||||
pub const SYS_LISTXATTR: usize = 11;
|
||||
pub const SYS_LLISTXATTR: usize = 12;
|
||||
pub const SYS_FLISTXATTR: usize = 13;
|
||||
pub const SYS_REMOVEXATTR: usize = 14;
|
||||
pub const SYS_LREMOVEXATTR: usize = 15;
|
||||
pub const SYS_FREMOVEXATTR: usize = 16;
|
||||
pub const SYS_GETCWD: usize = 17;
|
||||
pub const SYS_LOOKUP_DCOOKIE: usize = 18;
|
||||
pub const SYS_EVENTFD2: usize = 19;
|
||||
pub const SYS_EPOLL_CREATE1: usize = 20;
|
||||
pub const SYS_EPOLL_CTL: usize = 21;
|
||||
pub const SYS_EPOLL_PWAIT: usize = 22;
|
||||
pub const SYS_DUP: usize = 23;
|
||||
pub const SYS_DUP3: usize = 24;
|
||||
pub const SYS_FCNTL: usize = 25;
|
||||
pub const SYS_INOTIFY_INIT1: usize = 26;
|
||||
pub const SYS_INOTIFY_ADD_WATCH: usize = 27;
|
||||
pub const SYS_INOTIFY_RM_WATCH: usize = 28;
|
||||
pub const SYS_IOCTL: usize = 29;
|
||||
pub const SYS_IOPRIO_SET: usize = 30;
|
||||
pub const SYS_IOPRIO_GET: usize = 31;
|
||||
pub const SYS_FLOCK: usize = 32;
|
||||
pub const SYS_MKNODAT: usize = 33;
|
||||
pub const SYS_MKDIRAT: usize = 34;
|
||||
pub const SYS_UNLINKAT: usize = 35;
|
||||
pub const SYS_SYMLINKAT: usize = 36;
|
||||
pub const SYS_LINKAT: usize = 37;
|
||||
pub const SYS_UMOUNT2: usize = 39;
|
||||
pub const SYS_MOUNT: usize = 40;
|
||||
pub const SYS_PIVOT_ROOT: usize = 41;
|
||||
pub const SYS_NFSSERVCTL: usize = 42;
|
||||
pub const SYS_STATFS: usize = 43;
|
||||
pub const SYS_FSTATFS: usize = 44;
|
||||
pub const SYS_TRUNCATE: usize = 45;
|
||||
pub const SYS_FTRUNCATE: usize = 46;
|
||||
pub const SYS_FALLOCATE: usize = 47;
|
||||
pub const SYS_FACCESSAT: usize = 48;
|
||||
pub const SYS_CHDIR: usize = 49;
|
||||
pub const SYS_FCHDIR: usize = 50;
|
||||
pub const SYS_CHROOT: usize = 51;
|
||||
pub const SYS_FCHMOD: usize = 52;
|
||||
pub const SYS_FCHMODAT: usize = 53;
|
||||
pub const SYS_FCHOWNAT: usize = 54;
|
||||
pub const SYS_FCHOWN: usize = 55;
|
||||
pub const SYS_OPENAT: usize = 56;
|
||||
pub const SYS_CLOSE: usize = 57;
|
||||
pub const SYS_VHANGUP: usize = 58;
|
||||
pub const SYS_PIPE2: usize = 59;
|
||||
pub const SYS_QUOTACTL: usize = 60;
|
||||
pub const SYS_GETDENTS64: usize = 61;
|
||||
pub const SYS_LSEEK: usize = 62;
|
||||
pub const SYS_READ: usize = 63;
|
||||
pub const SYS_WRITE: usize = 64;
|
||||
pub const SYS_READV: usize = 65;
|
||||
pub const SYS_WRITEV: usize = 66;
|
||||
pub const SYS_PREAD64: usize = 67;
|
||||
pub const SYS_PWRITE64: usize = 68;
|
||||
pub const SYS_PREADV: usize = 69;
|
||||
pub const SYS_PWRITEV: usize = 70;
|
||||
pub const SYS_SENDFILE: usize = 71;
|
||||
pub const SYS_PSELECT6: usize = 72;
|
||||
pub const SYS_PPOLL: usize = 73;
|
||||
pub const SYS_SIGNALFD4: usize = 74;
|
||||
pub const SYS_VMSPLICE: usize = 75;
|
||||
pub const SYS_SPLICE: usize = 76;
|
||||
pub const SYS_TEE: usize = 77;
|
||||
pub const SYS_READLINKAT: usize = 78;
|
||||
pub const SYS_SYNC: usize = 81;
|
||||
pub const SYS_FSYNC: usize = 82;
|
||||
pub const SYS_FDATASYNC: usize = 83;
|
||||
pub const SYS_SYNC_FILE_RANGE: usize = 84;
|
||||
pub const SYS_TIMERFD_CREATE: usize = 85;
|
||||
pub const SYS_TIMERFD_SETTIME: usize = 86;
|
||||
pub const SYS_TIMERFD_GETTIME: usize = 87;
|
||||
pub const SYS_UTIMENSAT: usize = 88;
|
||||
pub const SYS_ACCT: usize = 89;
|
||||
pub const SYS_CAPGET: usize = 90;
|
||||
pub const SYS_CAPSET: usize = 91;
|
||||
pub const SYS_PERSONALITY: usize = 92;
|
||||
pub const SYS_EXIT: usize = 93;
|
||||
pub const SYS_EXIT_GROUP: usize = 94;
|
||||
pub const SYS_WAITID: usize = 95;
|
||||
pub const SYS_SET_TID_ADDRESS: usize = 96;
|
||||
pub const SYS_UNSHARE: usize = 97;
|
||||
pub const SYS_FUTEX: usize = 98;
|
||||
pub const SYS_SET_ROBUST_LIST: usize = 99;
|
||||
pub const SYS_GET_ROBUST_LIST: usize = 100;
|
||||
pub const SYS_NANOSLEEP: usize = 101;
|
||||
pub const SYS_GETITIMER: usize = 102;
|
||||
pub const SYS_SETITIMER: usize = 103;
|
||||
pub const SYS_KEXEC_LOAD: usize = 104;
|
||||
pub const SYS_INIT_MODULE: usize = 105;
|
||||
pub const SYS_DELETE_MODULE: usize = 106;
|
||||
pub const SYS_TIMER_CREATE: usize = 107;
|
||||
pub const SYS_TIMER_GETTIME: usize = 108;
|
||||
pub const SYS_TIMER_GETOVERRUN: usize = 109;
|
||||
pub const SYS_TIMER_SETTIME: usize = 110;
|
||||
pub const SYS_TIMER_DELETE: usize = 111;
|
||||
pub const SYS_CLOCK_SETTIME: usize = 112;
|
||||
pub const SYS_CLOCK_GETTIME: usize = 113;
|
||||
pub const SYS_CLOCK_GETRES: usize = 114;
|
||||
pub const SYS_CLOCK_NANOSLEEP: usize = 115;
|
||||
pub const SYS_SYSLOG: usize = 116;
|
||||
pub const SYS_PTRACE: usize = 117;
|
||||
pub const SYS_SCHED_SETPARAM: usize = 118;
|
||||
pub const SYS_SCHED_SETSCHEDULER: usize = 119;
|
||||
pub const SYS_SCHED_GETSCHEDULER: usize = 120;
|
||||
pub const SYS_SCHED_GETPARAM: usize = 121;
|
||||
pub const SYS_SCHED_SETAFFINITY: usize = 122;
|
||||
pub const SYS_SCHED_GETAFFINITY: usize = 123;
|
||||
pub const SYS_SCHED_YIELD: usize = 124;
|
||||
pub const SYS_SCHED_GET_PRIORITY_MAX: usize = 125;
|
||||
pub const SYS_SCHED_GET_PRIORITY_MIN: usize = 126;
|
||||
pub const SYS_SCHED_RR_GET_INTERVAL: usize = 127;
|
||||
pub const SYS_RESTART_SYSCALL: usize = 128;
|
||||
pub const SYS_KILL: usize = 129;
|
||||
pub const SYS_TKILL: usize = 130;
|
||||
pub const SYS_TGKILL: usize = 131;
|
||||
pub const SYS_SIGALTSTACK: usize = 132;
|
||||
pub const SYS_RT_SIGSUSPEND: usize = 133;
|
||||
pub const SYS_RT_SIGACTION: usize = 134;
|
||||
pub const SYS_RT_SIGPROCMASK: usize = 135;
|
||||
pub const SYS_RT_SIGPENDING: usize = 136;
|
||||
pub const SYS_RT_SIGTIMEDWAIT: usize = 137;
|
||||
pub const SYS_RT_SIGQUEUEINFO: usize = 138;
|
||||
pub const SYS_RT_SIGRETURN: usize = 139;
|
||||
pub const SYS_SETPRIORITY: usize = 140;
|
||||
pub const SYS_GETPRIORITY: usize = 141;
|
||||
pub const SYS_REBOOT: usize = 142;
|
||||
pub const SYS_SETREGID: usize = 143;
|
||||
pub const SYS_SETGID: usize = 144;
|
||||
pub const SYS_SETREUID: usize = 145;
|
||||
pub const SYS_SETUID: usize = 146;
|
||||
pub const SYS_SETRESUID: usize = 147;
|
||||
pub const SYS_GETRESUID: usize = 148;
|
||||
pub const SYS_SETRESGID: usize = 149;
|
||||
pub const SYS_GETRESGID: usize = 150;
|
||||
pub const SYS_SETFSUID: usize = 151;
|
||||
pub const SYS_SETFSGID: usize = 152;
|
||||
pub const SYS_TIMES: usize = 153;
|
||||
pub const SYS_SETPGID: usize = 154;
|
||||
pub const SYS_GETPGID: usize = 155;
|
||||
pub const SYS_GETSID: usize = 156;
|
||||
pub const SYS_SETSID: usize = 157;
|
||||
pub const SYS_GETGROUPS: usize = 158;
|
||||
pub const SYS_SETGROUPS: usize = 159;
|
||||
pub const SYS_UNAME: usize = 160;
|
||||
pub const SYS_SETHOSTNAME: usize = 161;
|
||||
pub const SYS_SETDOMAINNAME: usize = 162;
|
||||
pub const SYS_GETRUSAGE: usize = 165;
|
||||
pub const SYS_UMASK: usize = 166;
|
||||
pub const SYS_PRCTL: usize = 167;
|
||||
pub const SYS_GETCPU: usize = 168;
|
||||
pub const SYS_GETTIMEOFDAY: usize = 169;
|
||||
pub const SYS_SETTIMEOFDAY: usize = 170;
|
||||
pub const SYS_ADJTIMEX: usize = 171;
|
||||
pub const SYS_GETPID: usize = 172;
|
||||
pub const SYS_GETPPID: usize = 173;
|
||||
pub const SYS_GETUID: usize = 174;
|
||||
pub const SYS_GETEUID: usize = 175;
|
||||
pub const SYS_GETGID: usize = 176;
|
||||
pub const SYS_GETEGID: usize = 177;
|
||||
pub const SYS_GETTID: usize = 178;
|
||||
pub const SYS_SYSINFO: usize = 179;
|
||||
pub const SYS_MQ_OPEN: usize = 180;
|
||||
pub const SYS_MQ_UNLINK: usize = 181;
|
||||
pub const SYS_MQ_TIMEDSEND: usize = 182;
|
||||
pub const SYS_MQ_TIMEDRECEIVE: usize = 183;
|
||||
pub const SYS_MQ_NOTIFY: usize = 184;
|
||||
pub const SYS_MQ_GETSETATTR: usize = 185;
|
||||
pub const SYS_MSGGET: usize = 186;
|
||||
pub const SYS_MSGCTL: usize = 187;
|
||||
pub const SYS_MSGRCV: usize = 188;
|
||||
pub const SYS_MSGSND: usize = 189;
|
||||
pub const SYS_SEMGET: usize = 190;
|
||||
pub const SYS_SEMCTL: usize = 191;
|
||||
pub const SYS_SEMTIMEDOP: usize = 192;
|
||||
pub const SYS_SEMOP: usize = 193;
|
||||
pub const SYS_SHMGET: usize = 194;
|
||||
pub const SYS_SHMCTL: usize = 195;
|
||||
pub const SYS_SHMAT: usize = 196;
|
||||
pub const SYS_SHMDT: usize = 197;
|
||||
pub const SYS_SOCKET: usize = 198;
|
||||
pub const SYS_SOCKETPAIR: usize = 199;
|
||||
pub const SYS_BIND: usize = 200;
|
||||
pub const SYS_LISTEN: usize = 201;
|
||||
pub const SYS_ACCEPT: usize = 202;
|
||||
pub const SYS_CONNECT: usize = 203;
|
||||
pub const SYS_GETSOCKNAME: usize = 204;
|
||||
pub const SYS_GETPEERNAME: usize = 205;
|
||||
pub const SYS_SENDTO: usize = 206;
|
||||
pub const SYS_RECVFROM: usize = 207;
|
||||
pub const SYS_SETSOCKOPT: usize = 208;
|
||||
pub const SYS_GETSOCKOPT: usize = 209;
|
||||
pub const SYS_SHUTDOWN: usize = 210;
|
||||
pub const SYS_SENDMSG: usize = 211;
|
||||
pub const SYS_RECVMSG: usize = 212;
|
||||
pub const SYS_READAHEAD: usize = 213;
|
||||
pub const SYS_BRK: usize = 214;
|
||||
pub const SYS_MUNMAP: usize = 215;
|
||||
pub const SYS_MREMAP: usize = 216;
|
||||
pub const SYS_ADD_KEY: usize = 217;
|
||||
pub const SYS_REQUEST_KEY: usize = 218;
|
||||
pub const SYS_KEYCTL: usize = 219;
|
||||
pub const SYS_CLONE: usize = 220;
|
||||
pub const SYS_EXECVE: usize = 221;
|
||||
pub const SYS_MMAP: usize = 222;
|
||||
pub const SYS_FADVISE64: usize = 223;
|
||||
pub const SYS_SWAPON: usize = 224;
|
||||
pub const SYS_SWAPOFF: usize = 225;
|
||||
pub const SYS_MPROTECT: usize = 226;
|
||||
pub const SYS_MSYNC: usize = 227;
|
||||
pub const SYS_MLOCK: usize = 228;
|
||||
pub const SYS_MUNLOCK: usize = 229;
|
||||
pub const SYS_MLOCKALL: usize = 230;
|
||||
pub const SYS_MUNLOCKALL: usize = 231;
|
||||
pub const SYS_MINCORE: usize = 232;
|
||||
pub const SYS_MADVISE: usize = 233;
|
||||
pub const SYS_REMAP_FILE_PAGES: usize = 234;
|
||||
pub const SYS_MBIND: usize = 235;
|
||||
pub const SYS_GET_MEMPOLICY: usize = 236;
|
||||
pub const SYS_SET_MEMPOLICY: usize = 237;
|
||||
pub const SYS_MIGRATE_PAGES: usize = 238;
|
||||
pub const SYS_MOVE_PAGES: usize = 239;
|
||||
pub const SYS_RT_TGSIGQUEUEINFO: usize = 240;
|
||||
pub const SYS_PERF_EVENT_OPEN: usize = 241;
|
||||
pub const SYS_ACCEPT4: usize = 242;
|
||||
pub const SYS_RECVMMSG: usize = 243;
|
||||
//pub const SYS_ARCH_SPECIFIC_SYSCALL: usize = 244;
|
||||
pub const SYS_WAIT4: usize = 260;
|
||||
pub const SYS_PRLIMIT64: usize = 261;
|
||||
pub const SYS_FANOTIFY_INIT: usize = 262;
|
||||
pub const SYS_FANOTIFY_MARK: usize = 263;
|
||||
pub const SYS_NAME_TO_HANDLE_AT: usize = 264;
|
||||
pub const SYS_OPEN_BY_HANDLE_AT: usize = 265;
|
||||
pub const SYS_CLOCK_ADJTIME: usize = 266;
|
||||
pub const SYS_SYNCFS: usize = 267;
|
||||
pub const SYS_SETNS: usize = 268;
|
||||
pub const SYS_SENDMMSG: usize = 269;
|
||||
pub const SYS_PROCESS_VM_READV: usize = 270;
|
||||
pub const SYS_PROCESS_VM_WRITEV: usize = 271;
|
||||
pub const SYS_KCMP: usize = 272;
|
||||
pub const SYS_FINIT_MODULE: usize = 273;
|
||||
pub const SYS_SCHED_SETATTR: usize = 274;
|
||||
pub const SYS_SCHED_GETATTR: usize = 275;
|
||||
pub const SYS_RENAMEAT2: usize = 276;
|
||||
pub const SYS_SECCOMP: usize = 277;
|
||||
pub const SYS_GETRANDOM: usize = 278;
|
||||
pub const SYS_MEMFD_CREATE: usize = 279;
|
||||
pub const SYS_BPF: usize = 280;
|
||||
pub const SYS_EXECVEAT: usize = 281;
|
||||
pub const SYS_USERFAULTFD: usize = 282;
|
||||
pub const SYS_MEMBARRIER: usize = 283;
|
||||
pub const SYS_MLOCK2: usize = 284;
|
||||
pub const SYS_COPY_FILE_RANGE: usize = 285;
|
||||
pub const SYS_PREADV2: usize = 286;
|
||||
pub const SYS_PWRITEV2: usize = 287;
|
||||
pub const SYS_PKEY_MPROTECT: usize = 288;
|
||||
pub const SYS_PKEY_ALLOC: usize = 289;
|
||||
pub const SYS_PKEY_FREE: usize = 290;
|
||||
pub const SYS_STATX: usize = 291;
|
||||
pub const SYS_IO_PGETEVENTS: usize = 292;
|
||||
pub const SYS_RSEQ: usize = 293;
|
||||
pub const SYS_KEXEC_FILE_LOAD: usize = 294;
|
||||
pub const SYS_PIDFD_SEND_SIGNAL: usize = 424;
|
||||
pub const SYS_IO_URING_SETUP: usize = 425;
|
||||
pub const SYS_IO_URING_ENTER: usize = 426;
|
||||
pub const SYS_IO_URING_REGISTER: usize = 427;
|
||||
pub const SYS_OPEN_TREE: usize = 428;
|
||||
pub const SYS_MOVE_MOUNT: usize = 429;
|
||||
pub const SYS_FSOPEN: usize = 430;
|
||||
pub const SYS_FSCONFIG: usize = 431;
|
||||
pub const SYS_FSMOUNT: usize = 432;
|
||||
pub const SYS_FSPICK: usize = 433;
|
||||
pub const SYS_PIDFD_OPEN: usize = 434;
|
||||
pub const SYS_CLONE3: usize = 435;
|
||||
pub const SYS_CLOSE_RANGE: usize = 436;
|
||||
pub const SYS_OPENAT2: usize = 437;
|
||||
pub const SYS_PIDFD_GETFD: usize = 438;
|
||||
pub const SYS_FACCESSAT2: usize = 439;
|
||||
pub const SYS_PROCESS_MADVISE: usize = 440;
|
||||
pub const SYS_EPOLL_PWAIT2: usize = 441;
|
||||
pub const SYS_MOUNT_SETATTR: usize = 442;
|
||||
pub const SYS_QUOTACTL_FD: usize = 443;
|
||||
pub const SYS_LANDLOCK_CREATE_RULESET: usize = 444;
|
||||
pub const SYS_LANDLOCK_ADD_RULE: usize = 445;
|
||||
pub const SYS_LANDLOCK_RESTRICT_SELF: usize = 446;
|
||||
pub const SYS_PROCESS_MRELEASE: usize = 448;
|
||||
pub const SYS_FUTEX_WAITV: usize = 449;
|
||||
pub const SYS_SET_MEMPOLICY_HOME_NODE: usize = 450;
|
||||
|
||||
// ===以下是为了代码一致性,才定义的调用号===
|
||||
|
||||
pub const SYS_GETDENTS: usize = SYS_GETDENTS64;
|
24
kernel/src/arch/loongarch64/time.rs
Normal file
24
kernel/src/arch/loongarch64/time.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use crate::time::{clocksource::HZ, TimeArch};
|
||||
|
||||
/// 这个是系统jiffies时钟源的固有频率(不是调频之后的)
|
||||
pub const CLOCK_TICK_RATE: u32 = HZ as u32 * 1000000;
|
||||
|
||||
pub struct LoongArch64TimeArch;
|
||||
|
||||
impl TimeArch for LoongArch64TimeArch {
|
||||
fn get_cycles() -> usize {
|
||||
todo!("LoongArch64TimeArch::get_cycles")
|
||||
}
|
||||
|
||||
fn cal_expire_cycles(ns: usize) -> usize {
|
||||
todo!("LoongArch64TimeArch::cal_expire_cycles")
|
||||
}
|
||||
|
||||
fn cycles2ns(cycles: usize) -> usize {
|
||||
todo!("LoongArch64TimeArch::cycles2ns")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn time_init() {
|
||||
todo!("la64:time_init");
|
||||
}
|
@ -13,6 +13,11 @@ pub mod riscv64;
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
pub use self::riscv64::*; // 公开riscv64架构下的函数,使外界接口统一
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
pub mod loongarch64;
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
pub use self::loongarch64::*; // 公开loongarch64架构下的函数,使外界接口统一
|
||||
|
||||
pub mod io;
|
||||
|
||||
/// TraitPciArch Pci架构相关函数,任何架构都应独立实现trait里的函数
|
||||
|
@ -95,9 +95,7 @@ impl From<i32> for Signal {
|
||||
|
||||
impl Into<SigSet> for Signal {
|
||||
fn into(self) -> SigSet {
|
||||
SigSet {
|
||||
bits: (1 << (self as usize - 1) as u64),
|
||||
}
|
||||
self.into_sigset()
|
||||
}
|
||||
}
|
||||
impl Signal {
|
||||
|
@ -1,13 +1,5 @@
|
||||
use crate::libs::rand::soft_rand;
|
||||
|
||||
pub fn rand() -> usize {
|
||||
static mut SEED: u64 = 0xdead_beef_cafe_babe;
|
||||
let mut buf = [0u8; size_of::<usize>()];
|
||||
for x in buf.iter_mut() {
|
||||
unsafe {
|
||||
// from musl
|
||||
SEED = SEED.wrapping_mul(0x5851_f42d_4c95_7f2d);
|
||||
*x = (SEED >> 33) as u8;
|
||||
}
|
||||
}
|
||||
let x: usize = unsafe { core::mem::transmute(buf) };
|
||||
return x;
|
||||
return soft_rand();
|
||||
}
|
||||
|
@ -1,10 +1,26 @@
|
||||
use crate::debug::traceback::lookup_kallsyms;
|
||||
use crate::libs::spinlock::SpinLock;
|
||||
use core::ffi::c_void;
|
||||
use unwinding::abi::{UnwindContext, UnwindReasonCode, _Unwind_Backtrace, _Unwind_GetIP};
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(not(target_arch = "loongarch64"))]
|
||||
{
|
||||
use unwinding::abi::{UnwindContext, UnwindReasonCode, _Unwind_Backtrace, _Unwind_GetIP};
|
||||
use core::ffi::c_void;
|
||||
use crate::debug::traceback::lookup_kallsyms;
|
||||
}
|
||||
}
|
||||
|
||||
static GLOBAL_LOCK: SpinLock<()> = SpinLock::new(());
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
pub fn print_stack_trace() {
|
||||
let _lock = GLOBAL_LOCK.lock();
|
||||
println!("This Arch does not support stack trace printing.");
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "loongarch64"))]
|
||||
pub fn print_stack_trace() {
|
||||
static GLOBAL_LOCK: SpinLock<()> = SpinLock::new(());
|
||||
let _lock = GLOBAL_LOCK.lock();
|
||||
println!("Rust Panic Backtrace:");
|
||||
struct CallbackData {
|
||||
|
@ -63,6 +63,7 @@ pub fn panic(info: &PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "loongarch64"))]
|
||||
if info.can_unwind() {
|
||||
let guard = Box::new(PanicGuard::new());
|
||||
hook::print_stack_trace();
|
||||
@ -79,6 +80,7 @@ pub fn panic(info: &PanicInfo) -> ! {
|
||||
/// The wrapper of `unwinding::panic::begin_panic`. If the panic is
|
||||
/// caught, it will return the result of the function.
|
||||
/// If the panic is not caught, it will return an error.
|
||||
#[cfg(not(target_arch = "loongarch64"))]
|
||||
pub fn kernel_catch_unwind<R, F: FnOnce() -> R>(f: F) -> Result<R, SystemError> {
|
||||
let res = unwinding::panic::catch_unwind(f);
|
||||
match res {
|
||||
@ -90,6 +92,7 @@ pub fn kernel_catch_unwind<R, F: FnOnce() -> R>(f: F) -> Result<R, SystemError>
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "loongarch64"))]
|
||||
#[allow(unused)]
|
||||
pub fn test_unwind() {
|
||||
struct UnwindTest;
|
||||
|
@ -43,6 +43,9 @@ use super::{uart_manager, UartDriver, UartManager, UartPort, TTY_SERIAL_DEFAULT_
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod serial8250_pio;
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
mod serial8250_la64;
|
||||
|
||||
static mut SERIAL8250_ISA_DEVICES: Option<Arc<Serial8250ISADevices>> = None;
|
||||
static mut SERIAL8250_ISA_DRIVER: Option<Arc<Serial8250ISADriver>> = None;
|
||||
|
||||
@ -75,8 +78,11 @@ impl Serial8250Manager {
|
||||
/// 初始化串口设备(在内存管理初始化之前)
|
||||
pub fn early_init(&self) -> Result<(), SystemError> {
|
||||
// todo: riscv64: 串口设备初始化
|
||||
#[cfg(not(target_arch = "riscv64"))]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
serial8250_pio_port_early_init()?;
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
serial8250_la64::early_la64_seria8250_init()?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@ -127,7 +133,7 @@ impl Serial8250Manager {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
#[cfg(any(target_arch = "riscv64", target_arch = "loongarch64"))]
|
||||
fn serial_tty_init(&self) -> Result<(), SystemError> {
|
||||
Ok(())
|
||||
}
|
||||
@ -564,4 +570,9 @@ pub fn send_to_default_serial8250_port(s: &[u8]) {
|
||||
{
|
||||
crate::arch::driver::sbi::console_putstr(s);
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
{
|
||||
serial8250_la64::send_to_default_serial8250_la64_port(s);
|
||||
}
|
||||
}
|
||||
|
69
kernel/src/driver/serial/serial8250/serial8250_la64.rs
Normal file
69
kernel/src/driver/serial/serial8250/serial8250_la64.rs
Normal file
@ -0,0 +1,69 @@
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
arch::MMArch,
|
||||
libs::spinlock::SpinLock,
|
||||
mm::{MemoryManagementArch, PhysAddr, VirtAddr},
|
||||
};
|
||||
|
||||
const UART_PADDR_COM1: PhysAddr = PhysAddr::new(0x01FE001E0);
|
||||
|
||||
static mut UART_PORT_COM1: Option<SpinLock<Serial8250LA64Port>> = None;
|
||||
|
||||
struct Serial8250LA64Port {
|
||||
base_address: VirtAddr,
|
||||
}
|
||||
|
||||
impl Serial8250LA64Port {
|
||||
pub fn new(base_address: PhysAddr) -> Self {
|
||||
Self {
|
||||
base_address: unsafe { MMArch::phys_2_virt(base_address).unwrap() },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn putchar(&mut self, c: u8) {
|
||||
let ptr = self.base_address.as_ptr() as *mut u8;
|
||||
loop {
|
||||
unsafe {
|
||||
if ptr.add(5).read_volatile() & (1 << 5) != 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
ptr.add(0).write_volatile(c);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getchar(&mut self) -> Option<u8> {
|
||||
let ptr = self.base_address.as_ptr() as *mut u8;
|
||||
unsafe {
|
||||
if ptr.add(5).read_volatile() & 1 == 0 {
|
||||
// The DR bit is 0, meaning no data
|
||||
None
|
||||
} else {
|
||||
// The DR bit is 1, meaning data!
|
||||
Some(ptr.add(0).read_volatile())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub(super) fn early_la64_seria8250_init() -> Result<(), SystemError> {
|
||||
let port = Serial8250LA64Port::new(UART_PADDR_COM1);
|
||||
unsafe {
|
||||
UART_PORT_COM1 = Some(SpinLock::new(port));
|
||||
}
|
||||
send_to_default_serial8250_la64_port(b"[DragonOS] loongarch64 debug uart port initialized!\n");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn send_to_default_serial8250_la64_port(s: &[u8]) {
|
||||
if let Some(com) = unsafe { UART_PORT_COM1.as_ref() } {
|
||||
let mut cg = com.lock_irqsave();
|
||||
for c in s.iter() {
|
||||
cg.putchar(*c);
|
||||
}
|
||||
}
|
||||
}
|
@ -155,7 +155,7 @@ impl VideoRefreshManager {
|
||||
}
|
||||
|
||||
/// 在riscv64平台下暂时不支持
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
#[cfg(any(target_arch = "riscv64", target_arch = "loongarch64"))]
|
||||
pub unsafe fn video_init() -> Result<(), SystemError> {
|
||||
return Err(SystemError::ENOSYS);
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ impl BootParams {
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
return Some(self.arch.arch_fdt());
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "loongarch64"))]
|
||||
return None;
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ impl BootParams {
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
return Some(self.arch.fdt_paddr);
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "loongarch64"))]
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
@ -103,6 +103,7 @@ fn do_start_kernel() {
|
||||
#[inline(never)]
|
||||
fn init_before_mem_init() {
|
||||
serial_early_init().expect("serial early init failed");
|
||||
|
||||
let video_ok = unsafe { VideoRefreshManager::video_init().is_ok() };
|
||||
scm_init(video_ok);
|
||||
|
||||
|
206
kernel/src/ipc/generic_signal.rs
Normal file
206
kernel/src/ipc/generic_signal.rs
Normal file
@ -0,0 +1,206 @@
|
||||
use num_traits::FromPrimitive;
|
||||
|
||||
use crate::arch::ipc::signal::{SigSet, MAX_SIG_NUM};
|
||||
|
||||
/// 信号处理的栈的栈指针的最小对齐
|
||||
#[allow(dead_code)]
|
||||
pub const GENERIC_STACK_ALIGN: u64 = 16;
|
||||
/// 信号最大值
|
||||
#[allow(dead_code)]
|
||||
pub const GENERIC_MAX_SIG_NUM: usize = 64;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Eq, PartialEq, FromPrimitive)]
|
||||
#[repr(usize)]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[atomic_enum]
|
||||
pub enum GenericSignal {
|
||||
INVALID = 0,
|
||||
SIGHUP = 1,
|
||||
SIGINT,
|
||||
SIGQUIT,
|
||||
SIGILL,
|
||||
SIGTRAP,
|
||||
/// SIGABRT和SIGIOT共用这个号码
|
||||
SIGABRT_OR_IOT,
|
||||
SIGBUS,
|
||||
SIGFPE,
|
||||
SIGKILL,
|
||||
SIGUSR1,
|
||||
|
||||
SIGSEGV = 11,
|
||||
SIGUSR2,
|
||||
SIGPIPE,
|
||||
SIGALRM,
|
||||
SIGTERM,
|
||||
SIGSTKFLT,
|
||||
SIGCHLD,
|
||||
SIGCONT,
|
||||
SIGSTOP,
|
||||
SIGTSTP,
|
||||
|
||||
SIGTTIN = 21,
|
||||
SIGTTOU,
|
||||
SIGURG,
|
||||
SIGXCPU,
|
||||
SIGXFSZ,
|
||||
SIGVTALRM,
|
||||
SIGPROF,
|
||||
SIGWINCH,
|
||||
/// SIGIO和SIGPOLL共用这个号码
|
||||
SIGIO_OR_POLL,
|
||||
SIGPWR,
|
||||
|
||||
SIGSYS = 31,
|
||||
|
||||
SIGRTMIN = 32,
|
||||
SIGRTMAX = 64,
|
||||
}
|
||||
|
||||
impl GenericSignal {
|
||||
/// 判断一个数字是否为可用的信号
|
||||
#[inline]
|
||||
pub fn is_valid(&self) -> bool {
|
||||
return (*self) as usize <= MAX_SIG_NUM;
|
||||
}
|
||||
|
||||
/// const convertor between `Signal` and `SigSet`
|
||||
pub const fn into_sigset(self) -> SigSet {
|
||||
SigSet::from_bits_truncate(1 << (self as usize - 1))
|
||||
}
|
||||
|
||||
/// 判断一个信号是不是实时信号
|
||||
///
|
||||
/// ## 返回值
|
||||
///
|
||||
/// - `true` 这个信号是实时信号
|
||||
/// - `false` 这个信号不是实时信号
|
||||
#[inline]
|
||||
pub fn is_rt_signal(&self) -> bool {
|
||||
return (*self) as usize >= Self::SIGRTMIN.into();
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GenericSignal> for usize {
|
||||
fn from(val: GenericSignal) -> Self {
|
||||
val as usize
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for GenericSignal {
|
||||
fn from(value: usize) -> Self {
|
||||
<Self as FromPrimitive>::from_usize(value).unwrap_or(GenericSignal::INVALID)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i32> for GenericSignal {
|
||||
fn from(value: i32) -> Self {
|
||||
if value < 0 {
|
||||
log::error!("Try to convert an invalid number to GenericSignal");
|
||||
return GenericSignal::INVALID;
|
||||
} else {
|
||||
return Self::from(value as usize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GenericSignal> for GenericSigSet {
|
||||
fn from(val: GenericSignal) -> Self {
|
||||
GenericSigSet {
|
||||
bits: (1 << (val as usize - 1) as u64),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// SIGCHLD si_codes
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, ToPrimitive)]
|
||||
#[allow(dead_code)]
|
||||
pub enum GenericSigChildCode {
|
||||
/// child has exited
|
||||
///
|
||||
/// CLD_EXITED
|
||||
Exited = 1,
|
||||
/// child was killed
|
||||
///
|
||||
/// CLD_KILLED
|
||||
Killed = 2,
|
||||
/// child terminated abnormally
|
||||
///
|
||||
/// CLD_DUMPED
|
||||
Dumped = 3,
|
||||
/// traced child has trapped
|
||||
///
|
||||
/// CLD_TRAPPED
|
||||
Trapped = 4,
|
||||
/// child has stopped
|
||||
///
|
||||
/// CLD_STOPPED
|
||||
Stopped = 5,
|
||||
/// stopped child has continued
|
||||
///
|
||||
/// CLD_CONTINUED
|
||||
Continued = 6,
|
||||
}
|
||||
|
||||
impl From<GenericSigChildCode> for i32 {
|
||||
fn from(value: GenericSigChildCode) -> Self {
|
||||
value as i32
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
/// 请注意,sigset 这个bitmap, 第0位表示sig=1的信号。也就是说,Signal-1才是sigset_t中对应的位
|
||||
#[derive(Default)]
|
||||
pub struct GenericSigSet:u64 {
|
||||
const SIGHUP = 1<<0;
|
||||
const SIGINT = 1<<1;
|
||||
const SIGQUIT = 1<<2;
|
||||
const SIGILL = 1<<3;
|
||||
const SIGTRAP = 1<<4;
|
||||
/// SIGABRT和SIGIOT共用这个号码
|
||||
const SIGABRT_OR_IOT = 1<<5;
|
||||
const SIGBUS = 1<<6;
|
||||
const SIGFPE = 1<<7;
|
||||
const SIGKILL = 1<<8;
|
||||
const SIGUSR = 1<<9;
|
||||
const SIGSEGV = 1<<10;
|
||||
const SIGUSR2 = 1<<11;
|
||||
const SIGPIPE = 1<<12;
|
||||
const SIGALRM = 1<<13;
|
||||
const SIGTERM = 1<<14;
|
||||
const SIGSTKFLT= 1<<15;
|
||||
const SIGCHLD = 1<<16;
|
||||
const SIGCONT = 1<<17;
|
||||
const SIGSTOP = 1<<18;
|
||||
const SIGTSTP = 1<<19;
|
||||
const SIGTTIN = 1<<20;
|
||||
const SIGTTOU = 1<<21;
|
||||
const SIGURG = 1<<22;
|
||||
const SIGXCPU = 1<<23;
|
||||
const SIGXFSZ = 1<<24;
|
||||
const SIGVTALRM= 1<<25;
|
||||
const SIGPROF = 1<<26;
|
||||
const SIGWINCH = 1<<27;
|
||||
/// SIGIO和SIGPOLL共用这个号码
|
||||
const SIGIO_OR_POLL = 1<<28;
|
||||
const SIGPWR = 1<<29;
|
||||
const SIGSYS = 1<<30;
|
||||
const SIGRTMIN = 1<<31;
|
||||
// TODO 写上实时信号
|
||||
const SIGRTMAX = 1 << (GENERIC_MAX_SIG_NUM-1);
|
||||
}
|
||||
|
||||
#[repr(C,align(8))]
|
||||
#[derive(Default)]
|
||||
pub struct GenericSigFlags:u32{
|
||||
const SA_NOCLDSTOP = 1;
|
||||
const SA_NOCLDWAIT = 2;
|
||||
const SA_SIGINFO = 4;
|
||||
const SA_ONSTACK = 0x08000000;
|
||||
const SA_RESTART = 0x10000000;
|
||||
const SA_NODEFER = 0x40000000;
|
||||
const SA_RESETHAND = 0x80000000;
|
||||
const SA_RESTORER =0x04000000;
|
||||
const SA_ALL = Self::SA_NOCLDSTOP.bits()|Self::SA_NOCLDWAIT.bits()|Self::SA_NODEFER.bits()|Self::SA_ONSTACK.bits()|Self::SA_RESETHAND.bits()|Self::SA_RESTART.bits()|Self::SA_SIGINFO.bits()|Self::SA_RESTORER.bits();
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
pub mod generic_signal;
|
||||
pub mod pipe;
|
||||
pub mod shm;
|
||||
pub mod signal;
|
||||
|
@ -1,13 +1,16 @@
|
||||
#![no_main] // <1>
|
||||
#![no_std]
|
||||
#![feature(alloc_error_handler)]
|
||||
#![feature(asm_goto)]
|
||||
#![feature(new_zeroed_alloc)]
|
||||
#![feature(allocator_api)]
|
||||
#![feature(arbitrary_self_types)]
|
||||
#![feature(concat_idents)]
|
||||
#![feature(const_for)]
|
||||
#![feature(const_size_of_val)]
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(c_variadic)]
|
||||
#![feature(c_void_variant)]
|
||||
#![feature(extract_if)]
|
||||
#![feature(fn_align)]
|
||||
@ -18,8 +21,6 @@
|
||||
#![feature(slice_ptr_get)]
|
||||
#![feature(sync_unsafe_cell)]
|
||||
#![feature(vec_into_raw_parts)]
|
||||
#![feature(c_variadic)]
|
||||
#![feature(asm_goto)]
|
||||
#![feature(linkage)]
|
||||
#![feature(panic_can_unwind)]
|
||||
#![allow(static_mut_refs, non_local_definitions, internal_features)]
|
||||
|
@ -106,6 +106,19 @@ impl ElfLoader {
|
||||
return self.inner_probe_common(param, ehdr);
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
pub fn probe_loongarch(
|
||||
&self,
|
||||
param: &ExecParam,
|
||||
ehdr: &FileHeader<AnyEndian>,
|
||||
) -> Result<(), ExecError> {
|
||||
// 判断架构是否匹配
|
||||
if ElfMachine::from(ehdr.e_machine) != ElfMachine::LoongArch {
|
||||
return Err(ExecError::WrongArchitecture);
|
||||
}
|
||||
return self.inner_probe_common(param, ehdr);
|
||||
}
|
||||
|
||||
/// 设置用户堆空间,映射[start, end)区间的虚拟地址,并把brk指针指向end
|
||||
///
|
||||
/// ## 参数
|
||||
@ -512,7 +525,14 @@ impl BinaryLoader for ElfLoader {
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
return self.probe_riscv(param, &ehdr);
|
||||
|
||||
#[cfg(not(any(target_arch = "x86_64", target_arch = "riscv64")))]
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
return self.probe_loongarch(param, &ehdr);
|
||||
|
||||
#[cfg(not(any(
|
||||
target_arch = "x86_64",
|
||||
target_arch = "riscv64",
|
||||
target_arch = "loongarch64"
|
||||
)))]
|
||||
compile_error!("BinaryLoader: Unsupported architecture");
|
||||
}
|
||||
|
||||
|
@ -5,3 +5,19 @@ bitflags! {
|
||||
const GRND_INSECURE = 0x0004;
|
||||
}
|
||||
}
|
||||
|
||||
// 软件实现的随机数生成器
|
||||
#[allow(dead_code)]
|
||||
pub fn soft_rand() -> usize {
|
||||
static mut SEED: u64 = 0xdead_beef_cafe_babe;
|
||||
let mut buf = [0u8; size_of::<usize>()];
|
||||
for x in buf.iter_mut() {
|
||||
unsafe {
|
||||
// from musl
|
||||
SEED = SEED.wrapping_mul(0x5851_f42d_4c95_7f2d);
|
||||
*x = (SEED >> 33) as u8;
|
||||
}
|
||||
}
|
||||
let x: usize = unsafe { core::mem::transmute(buf) };
|
||||
return x;
|
||||
}
|
||||
|
@ -202,7 +202,6 @@ impl<T> RwLock<T> {
|
||||
return (self.lock.load(Ordering::Relaxed) & WRITER) / WRITER;
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
/// @brief 尝试获得WRITER守卫
|
||||
@ -216,7 +215,6 @@ impl<T> RwLock<T> {
|
||||
return r;
|
||||
} //当架构为arm时,有些代码需要作出调整compare_exchange=>compare_exchange_weak
|
||||
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn try_write_irqsave(&self) -> Option<RwLockWriteGuard<T>> {
|
||||
@ -233,7 +231,6 @@ impl<T> RwLock<T> {
|
||||
return r;
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||
#[allow(dead_code)]
|
||||
fn inner_try_write(&self) -> Option<RwLockWriteGuard<T>> {
|
||||
let res: bool = self
|
||||
|
@ -488,7 +488,6 @@ impl MmioBuddyMemPool {
|
||||
return Err(SystemError::EPERM);
|
||||
}
|
||||
// 计算前导0
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||
let mut size_exp: u32 = 63 - size.leading_zeros();
|
||||
// debug!("create_mmio: size_exp: {}", size_exp);
|
||||
// 记录最终申请的空间大小
|
||||
|
@ -927,6 +927,11 @@ impl<Arch: MemoryManagementArch> PageEntry<Arch> {
|
||||
let ppn = ((self.data & (!((1 << 10) - 1))) >> 10) & ((1 << 54) - 1);
|
||||
super::allocator::page_frame::PhysPageFrame::from_ppn(ppn).phys_address()
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
{
|
||||
todo!("la64: PageEntry::address")
|
||||
}
|
||||
};
|
||||
|
||||
if self.present() {
|
||||
@ -1055,6 +1060,11 @@ impl<Arch: MemoryManagementArch> EntryFlags<Arch> {
|
||||
// riscv64指向下一级页表的页表项,不应设置R/W/X权限位
|
||||
Self::from_data(Arch::ENTRY_FLAG_DEFAULT_TABLE)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
{
|
||||
Self::from_data(Arch::ENTRY_FLAG_DEFAULT_TABLE)
|
||||
}
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
@ -1070,6 +1080,11 @@ impl<Arch: MemoryManagementArch> EntryFlags<Arch> {
|
||||
{
|
||||
r
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
{
|
||||
todo!("loongarch64: new_page_table")
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -1147,6 +1162,11 @@ impl<Arch: MemoryManagementArch> EntryFlags<Arch> {
|
||||
.update_flags(Arch::ENTRY_FLAG_WRITEABLE, false);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
{
|
||||
todo!("la64: set_write")
|
||||
}
|
||||
}
|
||||
|
||||
/// 当前页表项是否可写
|
||||
@ -1280,6 +1300,11 @@ impl<Arch: MemoryManagementArch> EntryFlags<Arch> {
|
||||
.set_execute(true)
|
||||
.set_page_global(true)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
{
|
||||
todo!("la64: mmio_flags()")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,9 @@ impl PerCpu {
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
pub const MAX_CPU_NUM: u32 = 64;
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
pub const MAX_CPU_NUM: u32 = 128;
|
||||
|
||||
/// # 初始化PerCpu
|
||||
///
|
||||
/// 该函数应该在内核初始化时调用一次。
|
||||
|
@ -97,6 +97,11 @@ impl ProcessManager {
|
||||
}
|
||||
return VirtAddr::new(stack_ptr);
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
{
|
||||
todo!("la64: stack_ptr() not implemented yet")
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取idle进程数组的引用
|
||||
|
@ -64,6 +64,9 @@ impl PosixOldUtsName {
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
const MACHINE: &[u8] = b"riscv64";
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
const MACHINE: &[u8] = b"longarch64";
|
||||
|
||||
let mut r = Self {
|
||||
sysname: [0; 65],
|
||||
nodename: [0; 65],
|
||||
|
@ -16,7 +16,7 @@ impl SchedClock {
|
||||
return CurrentTimeArch::cycles2ns(CurrentTimeArch::get_cycles()) as u64;
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
#[cfg(any(target_arch = "riscv64", target_arch = "loongarch64"))]
|
||||
{
|
||||
return CurrentTimeArch::cycles2ns(CurrentTimeArch::get_cycles()) as u64;
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ use core::{
|
||||
|
||||
use crate::{
|
||||
arch::{ipc::signal::SigSet, syscall::nr::*},
|
||||
debug::panic::kernel_catch_unwind,
|
||||
filesystem::vfs::syscall::{PosixStatfs, PosixStatx},
|
||||
ipc::shm::{ShmCtlCmd, ShmFlags, ShmId, ShmKey},
|
||||
libs::{futex::constant::FutexFlag, rand::GRandFlags},
|
||||
@ -78,11 +77,13 @@ impl Syscall {
|
||||
/// 系统调用分发器,用于分发系统调用。
|
||||
///
|
||||
/// 与[handle]不同,这个函数会捕获系统调用处理函数的panic,返回错误码。
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||
pub fn catch_handle(
|
||||
syscall_num: usize,
|
||||
args: &[usize],
|
||||
frame: &mut TrapFrame,
|
||||
) -> Result<usize, SystemError> {
|
||||
use crate::debug::panic::kernel_catch_unwind;
|
||||
let res = kernel_catch_unwind(|| Self::handle(syscall_num, args, frame))?;
|
||||
res
|
||||
}
|
||||
@ -669,6 +670,8 @@ impl Syscall {
|
||||
SYS_GETPGID => Self::getpgid(Pid::new(args[0])).map(|pid| pid.into()),
|
||||
|
||||
SYS_GETPPID => Self::getppid().map(|pid| pid.into()),
|
||||
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||
SYS_FSTAT => {
|
||||
let fd = args[0] as i32;
|
||||
let kstat: *mut PosixKstat = args[1] as *mut PosixKstat;
|
||||
@ -1130,6 +1133,7 @@ impl Syscall {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||
SYS_NEWFSTATAT => {
|
||||
// todo: 这个系统调用还没有实现
|
||||
|
||||
@ -1228,6 +1232,7 @@ impl Syscall {
|
||||
let flags = args[4] as u32;
|
||||
Self::sys_perf_event_open(attr, pid, cpu, group_fd, flags)
|
||||
}
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
|
||||
SYS_SETRLIMIT => Ok(0),
|
||||
SYS_RESTART_SYSCALL => Self::restart_syscall(),
|
||||
SYS_RT_SIGPENDING => Self::rt_sigpending(args[0], args[1]),
|
||||
|
@ -86,7 +86,7 @@ impl PosixTimeSpec {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
#[cfg(any(target_arch = "riscv64", target_arch = "loongarch64"))]
|
||||
{
|
||||
return PosixTimeSpec::new(0, 0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user