Skip to content

Commit

Permalink
try to add x86_64 support
Browse files Browse the repository at this point in the history
  • Loading branch information
yfblock committed Feb 4, 2024
1 parent f184cd8 commit 206df82
Show file tree
Hide file tree
Showing 11 changed files with 221 additions and 23 deletions.
2 changes: 0 additions & 2 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ rustflags = [
'--check-cfg=values(board, "qemu","k210","cv1811h", "")'
]

[env]

[target.riscv64imac-unknown-none-elf]

[target.x86_64-unknown-none]
Expand Down
5 changes: 3 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"rust-analyzer.checkOnSave.allTargets": false,
"rust-analyzer.checkOnSave.extraArgs": [
"--target",
"riscv64imac-unknown-none-elf"
// "--target",
// "riscv64imac-unknown-none-elf"
// "x86_64-unknown-none"
],
"files.associations": {
"*.in": "cpp",
Expand Down
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion arch/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@ autocfg = "1.1.0"
riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] }
log = "0.4"
bitflags = "2.0.2"
cfg-if = "1.0.0"
cfg-if = "1.0.0"

[target.'cfg(target_arch = "x86_64")'.dependencies]
x86 = "0.52"
x86_64 = "0.14"
spin = { version = "0.9.8", features = ["mutex"] }
17 changes: 17 additions & 0 deletions arch/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ extern crate log;
#[cfg(target_arch = "riscv64")]
mod riscv64;

use alloc::vec::Vec;
#[cfg(target_arch = "riscv64")]
pub use riscv64::*;

Expand Down Expand Up @@ -74,3 +75,19 @@ pub enum MapPageSize {
Page2m,
Page1G,
}

static mut INT_RECORDS: Vec<usize> = Vec::new();

pub fn add_irq(irq: usize) {
unsafe {
while INT_RECORDS.len() < 256 {
INT_RECORDS.push(0);
}
INT_RECORDS[irq] += 1;
}
}

pub fn get_int_records() -> Vec<usize> {
// INT_RECORDS.lock().clone()
unsafe { INT_RECORDS.clone() }
}
19 changes: 2 additions & 17 deletions arch/src/riscv64/interrupt.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use core::arch::{asm, global_asm};

use alloc::vec::Vec;
use riscv::register::{
scause::{self, Exception, Interrupt, Trap},
sstatus, stval,
};

use crate::{interrupt_table, riscv64::context::Context, shutdown, TrapType, VIRT_ADDR_START};
use crate::{add_irq, interrupt_table, riscv64::context::Context, shutdown, TrapType, VIRT_ADDR_START};

use super::timer;

Expand Down Expand Up @@ -39,6 +38,7 @@ global_asm!(
pub fn init_interrupt() {
crate::riscv64::page_table::sigtrx::init();
// 输出内核信息

unsafe {
asm!("csrw stvec, a0", in("a0") kernelvec as usize);

Expand All @@ -51,21 +51,6 @@ pub fn init_interrupt() {
timer::init();
}

static mut INT_RECORDS: Vec<usize> = Vec::new();

pub fn add_irq(irq: usize) {
unsafe {
while INT_RECORDS.len() < 256 {
INT_RECORDS.push(0);
}
INT_RECORDS[irq] += 1;
}
}

pub fn get_int_records() -> Vec<usize> {
// INT_RECORDS.lock().clone()
unsafe { INT_RECORDS.clone() }
}

// 内核中断回调
#[no_mangle]
Expand Down
2 changes: 1 addition & 1 deletion arch/src/riscv64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub use consts::*;
pub use context::*;
pub use entry::switch_to_kernel_page_table;
pub use interrupt::{
enable_external_irq, enable_irq, get_int_records, init_interrupt, trap_pre_handle, user_restore,
enable_external_irq, enable_irq, init_interrupt, trap_pre_handle, user_restore,
};
pub use page_table::*;
pub use sbi::*;
Expand Down
37 changes: 37 additions & 0 deletions arch/src/x86_64/interrupt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use core::arch::asm;


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

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

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

// }
}

pub fn init_interrupt() {
enable_irq()
}

pub fn time_to_usec(tiscks: usize) -> usize {
tiscks
}

pub fn get_time() -> usize {
unsafe {
core::arch::x86_64::_rdtsc() as _
}
}
6 changes: 6 additions & 0 deletions arch/src/x86_64/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
mod addr;
mod consts;
mod context;
mod interrupt;
mod page_table;
mod uart;

pub use addr::*;
pub use consts::*;
pub use context::Context;
pub use interrupt::*;
pub use page_table::*;
pub use uart::*;
34 changes: 34 additions & 0 deletions arch/src/x86_64/page_table.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use x86::controlregs;

use crate::{PhysAddr, PhysPage, VirtAddr, PAGE_FRAME_BASE};

pub struct PageTable(usize);

/// ppn convert, 如果在高半核空间
pub const fn ppn_c(ppn: PhysPage) -> PhysPage {
PhysPage(ppn.0 | (PAGE_FRAME_BASE >> 12))
}

/// paddr convert, 如果在高半核空间
pub fn paddr_c(paddr: PhysAddr) -> PhysAddr {
assert!(paddr.0 < PAGE_FRAME_BASE);
PhysAddr(paddr.0 + PAGE_FRAME_BASE)
}

/// paddr number convert, 如果在高半核空间
pub fn paddr_cn(paddr: usize) -> usize {
assert!(paddr < PAGE_FRAME_BASE);
paddr + PAGE_FRAME_BASE
}

/// 虚拟地址转物理地址
pub fn virt_to_phys(vaddr: VirtAddr) -> PhysAddr {
// current_page_table().virt_to_phys(vaddr)
todo!()
}

#[inline]
pub fn current_page_table() -> PageTable {
// PhysAddr::new(unsafe { controlregs::cr3() } as usize).align_down_4k()
todo!()
}
101 changes: 101 additions & 0 deletions arch/src/x86_64/uart.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
//! Uart 16550.
use spin::Mutex;
use x86_64::instructions::port::{Port, PortReadOnly, PortWriteOnly};

const UART_CLOCK_FACTOR: usize = 16;
const OSC_FREQ: usize = 1_843_200;

static COM1: Mutex<Uart16550> = Mutex::new(Uart16550::new(0x3f8));

bitflags::bitflags! {
/// Line status flags
struct LineStsFlags: u8 {
const INPUT_FULL = 1;
// 1 to 4 unknown
const OUTPUT_EMPTY = 1 << 5;
// 6 and 7 unknown
}
}

struct Uart16550 {
data: Port<u8>,
int_en: PortWriteOnly<u8>,
fifo_ctrl: PortWriteOnly<u8>,
line_ctrl: PortWriteOnly<u8>,
modem_ctrl: PortWriteOnly<u8>,
line_sts: PortReadOnly<u8>,
}

impl Uart16550 {
const fn new(port: u16) -> Self {
Self {
data: Port::new(port),
int_en: PortWriteOnly::new(port + 1),
fifo_ctrl: PortWriteOnly::new(port + 2),
line_ctrl: PortWriteOnly::new(port + 3),
modem_ctrl: PortWriteOnly::new(port + 4),
line_sts: PortReadOnly::new(port + 5),
}
}

fn init(&mut self, baud_rate: usize) {
unsafe {
// Disable interrupts
self.int_en.write(0x00);

// Enable DLAB
self.line_ctrl.write(0x80);

// Set maximum speed according the input baud rate by configuring DLL and DLM
let divisor = OSC_FREQ / (baud_rate * UART_CLOCK_FACTOR);
self.data.write((divisor & 0xff) as u8);
self.int_en.write((divisor >> 8) as u8);

// Disable DLAB and set data word length to 8 bits
self.line_ctrl.write(0x03);

// Enable FIFO, clear TX/RX queues and
// set interrupt watermark at 14 bytes
self.fifo_ctrl.write(0xC7);

// Mark data terminal ready, signal request to send
// and enable auxilliary output #2 (used as interrupt line for CPU)
self.modem_ctrl.write(0x0B);

// Enable interrupts
self.int_en.write(0x00);
}
}

fn line_sts(&mut self) -> LineStsFlags {
unsafe { LineStsFlags::from_bits_truncate(self.line_sts.read()) }
}

fn putchar(&mut self, c: u8) {
while !self.line_sts().contains(LineStsFlags::OUTPUT_EMPTY) {}
unsafe { self.data.write(c) };
}

fn getchar(&mut self) -> Option<u8> {
if self.line_sts().contains(LineStsFlags::INPUT_FULL) {
unsafe { Some(self.data.read()) }
} else {
None
}
}
}

pub fn console_putchar(c: u8) {
COM1.lock().putchar(c);
}

pub fn console_getchar() -> Option<u8> {
COM1.lock().getchar()
}

pub fn init_early() {
COM1.lock().init(115200);
}

pub fn init() {}

0 comments on commit 206df82

Please sign in to comment.