Skip to content

Commit

Permalink
feat: support polyhal and fix some code
Browse files Browse the repository at this point in the history
  • Loading branch information
yfblock committed Jun 4, 2024
1 parent a5743fb commit 78137ee
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 112 deletions.
1 change: 0 additions & 1 deletion src/aarch64/gic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use aarch64_cpu::registers::{Readable, DAIF};
use arm_gic::gic_v2::{GicCpuInterface, GicDistributor};
use arm_gic::{translate_irq, InterruptType};
use irq_safety::MutexIrqSafe;
use tock_registers::interfaces::ReadWriteable;

use crate::addr::PhysAddr;
use crate::irq::{IRQVector, IRQ};
Expand Down
2 changes: 1 addition & 1 deletion src/aarch64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub use kcontext::{context_switch, context_switch_pt, read_current_tp, KContext}

pub use page_table::*;
pub use psci::system_off as shutdown;
pub use trap::{disable_irq, enable_external_irq, enable_irq, run_user_task};
pub use trap::run_user_task;

use crate::debug::{display_info, println};
use crate::multicore::MultiCore;
Expand Down
23 changes: 3 additions & 20 deletions src/aarch64/trap.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use core::arch::{asm, global_asm};

use aarch64_cpu::registers::{Writeable, ESR_EL1, FAR_EL1, SCTLR_EL2::I, VBAR_EL1};
use aarch64_cpu::registers::{Writeable, ESR_EL1, FAR_EL1, VBAR_EL1};
use tock_registers::interfaces::Readable;

use crate::{
currrent_arch::{gic::TIMER_IRQ_NUM, timer::set_next_timer},
instruction::Instruction,
irq::IRQVector,
TrapType,
};

Expand Down Expand Up @@ -162,25 +161,9 @@ pub fn run_user_task(cx: &mut TrapFrame) -> Option<()> {
}
}

#[allow(dead_code)]
#[inline(always)]
pub fn enable_irq() {
unsafe { asm!("msr daifclr, #2") };
}

#[inline(always)]
pub fn disable_irq() {
unsafe { asm!("msr daifset, #2") };
}

#[inline(always)]
pub fn enable_external_irq() {
// unsafe {
// sie::set_sext();
// }
}

/// Implement the instructions for the riscv
impl Instruction {
/// ebreak instruction to trigger the breakpoint exception.
#[inline]
pub fn ebreak() {
unsafe { asm!("brk 0") }
Expand Down
2 changes: 0 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@
//! // Init page alloc for polyhal
//! polyhal::init(&PageAllocImpl);
//!
//! polyhal::init_interrupt();
//!
//! get_mem_areas().into_iter().for_each(|(start, size)| {
//! println!("init memory region {:#x} - {:#x}", start, start + size);
//! frame::add_frame_range(start, start + size);
Expand Down
29 changes: 3 additions & 26 deletions src/riscv64/interrupt.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use core::arch::{asm, global_asm};

use riscv::register::{
scause::{self, Exception, Interrupt, Trap},
sie, stval, stvec,
scause::{self, Exception, Interrupt, Trap}, stval, stvec,
};

use crate::{instruction::Instruction, TrapFrame, TrapType, VIRT_ADDR_START};
Expand Down Expand Up @@ -287,31 +286,9 @@ pub fn run_user_task_forever(context: &mut TrapFrame) -> ! {
}
}

#[allow(dead_code)]
#[inline(always)]
pub fn enable_irq() {
unsafe {
sie::set_sext();
sie::set_ssoft();
}
}

#[inline(always)]
pub fn disable_irq() {
unsafe {
sie::clear_sext();
sie::clear_ssoft();
}
}

#[inline(always)]
pub fn enable_external_irq() {
unsafe {
sie::set_sext();
}
}

/// Implement the instructions for the riscv
impl Instruction {
/// ebreak instruction to trigger the breakpoint exception.
#[inline]
pub fn ebreak() {
unsafe {
Expand Down
2 changes: 1 addition & 1 deletion src/riscv64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub use context::TrapFrame;
pub use entry::{kernel_page_table, switch_to_kernel_page_table};
use fdt::Fdt;
pub use interrupt::{
disable_irq, enable_external_irq, enable_irq, run_user_task, run_user_task_forever,
run_user_task, run_user_task_forever,
};
use sbi::*;

Expand Down
81 changes: 52 additions & 29 deletions src/x86_64/apic.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#![allow(dead_code)]

use core::cmp;

use irq_safety::MutexIrqSafe;
use spin::Once;
use x2apic::ioapic::IoApic;
use x2apic::ioapic::{IoApic, RedirectionTableEntry};
use x2apic::lapic::{xapic_base, LocalApic, LocalApicBuilder};
use x86_64::instructions::port::Port;

use self::vectors::*;
use crate::irq::IRQ;
use super::consts::PIC_VECTOR_OFFSET;
use crate::VIRT_ADDR_START;

pub(super) mod vectors {
Expand Down Expand Up @@ -51,6 +53,11 @@ pub(super) fn local_apic<'a>() -> &'a mut LocalApic {
unsafe { LOCAL_APIC.as_mut().unwrap() }
}

/// Get the interrupt controller
pub(super) fn io_apic<'a>() -> &'a MutexIrqSafe<IoApic> {
IO_APIC.get().expect("Can't get io_apic")
}

pub(super) fn raw_apic_id(id_u8: u8) -> u32 {
if unsafe { IS_X2APIC } {
id_u8 as u32
Expand All @@ -59,22 +66,49 @@ pub(super) fn raw_apic_id(id_u8: u8) -> u32 {
}
}

/// Check if the current cpu supports the x2apic
fn cpu_has_x2apic() -> bool {
match raw_cpuid::CpuId::new().get_feature_info() {
Some(finfo) => finfo.has_x2apic(),
None => false,
}
}

/// PIC End of interrupt
/// 8259 Programmable Interrupt Controller
#[allow(dead_code)]
pub(crate) fn pic_eoi() {
unsafe {
Port::<u8>::new(0x20).write(0x20);
Port::<u8>::new(0xa0).write(0x20);
}
}

/// Init APIC
pub(super) fn init() {
info!("Initialize Local APIC...");

// Remap and init pic controller.
unsafe {
let mut pic1_command = Port::<u8>::new(0x20);
let mut pic1_data = Port::<u8>::new(0x21);
let mut pic2_command = Port::<u8>::new(0xa0);
let mut pic2_data = Port::<u8>::new(0xa1);
// Remap 8259a master irqs to 0x20, slave to 0x28
// Map PIC_IRQ -> PIC_IRQ_OFFSET(0x20)
pic1_command.write(0x11);
pic2_command.write(0x11);
pic1_data.write(PIC_VECTOR_OFFSET);
pic2_data.write(PIC_VECTOR_OFFSET + 8);
pic1_data.write(0x04);
pic2_data.write(0x02);
pic1_data.write(0x01);
pic2_data.write(0x01);

// Disable 8259A interrupt controllers
Port::<u8>::new(0x21).write(0xff);
Port::<u8>::new(0xA1).write(0xff);
pic1_data.write(0xff);
pic2_data.write(0xff);
}

let mut builder = LocalApicBuilder::new();
builder
.timer_vector(APIC_TIMER_VECTOR as _)
Expand All @@ -96,31 +130,20 @@ pub(super) fn init() {
}

info!("Initialize IO APIC...");
let io_apic = unsafe { IoApic::new(IO_APIC_BASE) };
IO_APIC.call_once(|| MutexIrqSafe::new(io_apic));
}

/// Implement IRQ operations for the IRQ interface.
impl IRQ {
/// Enable irq for the given IRQ number.
#[inline]
pub fn enable(irq_num: usize) {
// should not affect LAPIC interrupts
if irq_num < APIC_TIMER_VECTOR as _ {
unsafe {
IO_APIC.get_unchecked().lock().enable_irq(irq_num as _);
}
let mut io_apic = unsafe { IoApic::new(IO_APIC_BASE) };
// Remap the PIC irqs, Default disabled.
for irq in 0..cmp::min(unsafe { io_apic.max_table_entry() }, 0x10) {
let mut entry = RedirectionTableEntry::default();
entry.set_vector(0x20 + irq);
entry.set_dest(0); // CPU(s)

// Set table entry and set it disabled.
unsafe {
io_apic.set_table_entry(irq, entry);
io_apic.disable_irq(irq);
}
}

/// Disable irq for the given IRQ number.
#[inline]
pub fn disable(irq_num: usize) {
// should not affect LAPIC interrupts
if irq_num < APIC_TIMER_VECTOR as _ {
unsafe {
IO_APIC.get_unchecked().lock().disable_irq(irq_num as _);
}
}
}
// Initialize the IO_APIC
IO_APIC.call_once(|| MutexIrqSafe::new(io_apic));
}
3 changes: 2 additions & 1 deletion src/x86_64/consts.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub const VIRT_ADDR_START: usize = 0xffff_ff80_0000_0000;
pub const SIG_RETURN_ADDR: usize = 0xFFFF_FF80_0000_0000;

pub const SYSCALL_VECTOR: usize = 0x33445566;
/// The offset of the pic irq.
pub(super) const PIC_VECTOR_OFFSET: u8 = 0x20;
23 changes: 4 additions & 19 deletions src/x86_64/interrupt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ use x86_64::VirtAddr;
use x86::{controlregs::cr2, irq::*};

use crate::consts::TRAPFRAME_SIZE;
use crate::currrent_arch::consts::SYSCALL_VECTOR;
use crate::currrent_arch::gdt::set_tss_kernel_sp;
use crate::SYSCALL_VECTOR;
use crate::{currrent_arch::gdt::GdtStruct, TrapFrame, TrapType};

use super::apic::vectors::APIC_TIMER_VECTOR;
use super::consts::PIC_VECTOR_OFFSET;
use super::context::FxsaveArea;

global_asm!(
Expand Down Expand Up @@ -102,7 +103,8 @@ fn kernel_callback(context: &mut TrapFrame) {
unsafe { super::apic::local_apic().end_of_interrupt() };
TrapType::Time
}
// IRQ_VECTOR_START..=IRQ_VECTOR_END => crate::trap::handle_irq_extern(tf.vector as _),
// PIC IRQS
0x20..=0x2f => TrapType::Irq(crate::irq::IRQVector(context.vector as usize - PIC_VECTOR_OFFSET as usize)),
_ => {
panic!(
"Unhandled exception {} (error_code = {:#x}) @ {:#x}:\n{:#x?}",
Expand Down Expand Up @@ -401,23 +403,6 @@ pub fn run_user_task(context: &mut TrapFrame) -> Option<()> {
}
}

#[allow(dead_code)]
#[inline(always)]
pub fn enable_irq() {
unsafe { asm!("sti") }
}

pub fn disable_irq() {
unsafe { asm!("cli") }
}

#[inline(always)]
pub fn enable_external_irq() {
// unsafe {

// }
}

impl crate::instruction::Instruction {
#[inline]
pub fn ebreak() {
Expand Down
17 changes: 11 additions & 6 deletions src/x86_64/irq.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
use crate::irq::{IRQVector, IRQ};

use super::apic::io_apic;

/// Implement IRQ operations for the IRQ interface.
impl IRQ {
/// Enable irq for the given IRQ number.
#[inline]
pub fn irq_enable(_irq_num: usize) {
log::warn!("irq not implemented in riscv platform yet");
pub fn irq_enable(irq_num: usize) {
unsafe {
io_apic().lock().enable_irq(irq_num as _);
}
}

/// Disable irq for the given IRQ number.
#[inline]
pub fn irq_disable(_irq_num: usize) {
log::warn!("irq not implemented in riscv platform yet");
pub fn irq_disable(irq_num: usize) {
unsafe {
io_apic().lock().disable_irq(irq_num as _);
}
}

/// Enable interrupts.
Expand All @@ -38,12 +44,11 @@ impl IRQVector {
/// Get the irq number in this vector
#[inline]
pub fn irq_num(&self) -> usize {
log::warn!("ack not implemented in x86_64 platform yet");
self.0
}

/// Acknowledge the irq
pub fn ack(&self) {
log::warn!("ack not implemented in x86_64 platform yet");
unsafe { super::apic::local_apic().end_of_interrupt() };
}
}
7 changes: 6 additions & 1 deletion src/x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use core::cmp;

use ::multiboot::information::MemoryType;
use alloc::vec::Vec;
pub use consts::*;
pub use consts::VIRT_ADDR_START;
pub use context::TrapFrame;
pub use interrupt::*;
#[cfg(feature = "kcontext")]
Expand Down Expand Up @@ -55,6 +55,7 @@ static MBOOT_PTR: LazyInit<usize> = LazyInit::new();

fn rust_tmp_main(magic: usize, mboot_ptr: usize) {
crate::clear_bss();
uart::init_early();
idt::init();
apic::init();
sigtrx::init();
Expand Down Expand Up @@ -106,6 +107,10 @@ fn rust_tmp_main(magic: usize, mboot_ptr: usize) {
display_info!("Platform FPU Support", "{}", features.has_fpu());
}
display_info!("Platform Virt Mem Offset", "{:#x}", VIRT_ADDR_START);
// TODO: Use the dynamic uart information.
display_info!("Platform UART Name", "Uart16550");
display_info!("Platform UART Port", "0x3f8");
display_info!("Platform UART IRQ", "0x4");
if let Some(mboot) = use_multiboot(mboot_ptr as _) {
mboot
.command_line()
Expand Down
Loading

0 comments on commit 78137ee

Please sign in to comment.