Wholesale fix of warnings
Pretty straightforward changes. This commit tries to avoid making any non-trivial fixes.
This commit is contained in:
+1
-18
@@ -2,7 +2,7 @@ use alloc::boxed::Box;
|
||||
|
||||
use crate::paging::KernelMapper;
|
||||
|
||||
use super::{get_sdt, sdt::Sdt};
|
||||
use super::get_sdt;
|
||||
|
||||
pub trait Rxsdt {
|
||||
fn iter(&self) -> Box<dyn Iterator<Item = usize>>;
|
||||
@@ -13,21 +13,4 @@ pub trait Rxsdt {
|
||||
get_sdt(sdt, &mut mapper);
|
||||
}
|
||||
}
|
||||
|
||||
fn find(
|
||||
&self,
|
||||
signature: [u8; 4],
|
||||
oem_id: [u8; 6],
|
||||
oem_table_id: [u8; 8],
|
||||
) -> Option<&'static Sdt> {
|
||||
for sdt in self.iter() {
|
||||
let sdt = unsafe { &*(sdt as *const Sdt) };
|
||||
|
||||
if sdt.match_pattern(signature, oem_id, oem_table_id) {
|
||||
return Some(sdt);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
+1
-14
@@ -1,4 +1,4 @@
|
||||
use core::{mem, slice};
|
||||
use core::mem;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[repr(packed)]
|
||||
@@ -30,17 +30,4 @@ impl Sdt {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn data(&self) -> &[u8] {
|
||||
unsafe { slice::from_raw_parts(self.data_address() as *const u8, self.data_len()) }
|
||||
}
|
||||
|
||||
pub fn match_pattern(
|
||||
&self,
|
||||
signature: [u8; 4],
|
||||
oem_id: [u8; 6],
|
||||
oem_table_id: [u8; 8],
|
||||
) -> bool {
|
||||
self.signature == signature && self.oem_id == oem_id && self.oem_table_id == oem_table_id
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#![allow(unused)]
|
||||
|
||||
// Because the memory map is so important to not be aliased, it is defined here, in one place
|
||||
// The lower 256 PML4 entries are reserved for userspace
|
||||
// Each PML4 entry references up to 512 GB of memory
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#![allow(unused)]
|
||||
|
||||
//! Functions to read and write control registers.
|
||||
|
||||
use core::arch::asm;
|
||||
@@ -72,38 +74,38 @@ pub unsafe fn tpidrro_el0_write(val: u64) {
|
||||
|
||||
pub unsafe fn esr_el1() -> u32 {
|
||||
let ret: u32;
|
||||
asm!("mrs {}, esr_el1", out(reg) ret);
|
||||
asm!("mrs {0:w}, esr_el1", out(reg) ret);
|
||||
ret
|
||||
}
|
||||
|
||||
pub unsafe fn cntfreq_el0() -> u32 {
|
||||
let ret: u32;
|
||||
let ret: usize;
|
||||
asm!("mrs {}, cntfrq_el0", out(reg) ret);
|
||||
ret
|
||||
ret as u32
|
||||
}
|
||||
|
||||
pub unsafe fn tmr_ctrl() -> u32 {
|
||||
let ret: u32;
|
||||
let ret: usize;
|
||||
asm!("mrs {}, cntp_ctl_el0", out(reg) ret);
|
||||
ret
|
||||
ret as u32
|
||||
}
|
||||
|
||||
pub unsafe fn tmr_ctrl_write(val: u32) {
|
||||
asm!("msr cntp_ctl_el0, {}", in(reg) val);
|
||||
asm!("msr cntp_ctl_el0, {}", in(reg) val as usize);
|
||||
}
|
||||
|
||||
pub unsafe fn tmr_tval() -> u32 {
|
||||
let ret: u32;
|
||||
asm!("mrs {}, cntp_tval_el0", out(reg) ret);
|
||||
ret
|
||||
let ret: usize;
|
||||
asm!("mrs {0}, cntp_tval_el0", out(reg) ret);
|
||||
ret as u32
|
||||
}
|
||||
|
||||
pub unsafe fn tmr_tval_write(val: u32) {
|
||||
asm!("msr cntp_tval_el0, {}", in(reg) val);
|
||||
asm!("msr cntp_tval_el0, {}", in(reg) val as usize);
|
||||
}
|
||||
|
||||
pub unsafe fn midr() -> u32 {
|
||||
let ret: u32;
|
||||
let ret: usize;
|
||||
asm!("mrs {}, midr_el1", out(reg) ret);
|
||||
ret
|
||||
ret as u32
|
||||
}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
pub mod control_regs;
|
||||
pub mod tlb;
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
//! Functions to flush the translation lookaside buffer (TLB).
|
||||
|
||||
use core::arch::asm;
|
||||
|
||||
pub unsafe fn flush(_addr: usize) {
|
||||
asm!("tlbi vmalle1is");
|
||||
}
|
||||
|
||||
pub unsafe fn flush_all() {
|
||||
asm!("tlbi vmalle1is");
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
use alloc::boxed::Box;
|
||||
use log::{debug, info};
|
||||
use log::info;
|
||||
|
||||
use crate::{
|
||||
arch::device::irqchip::IRQ_CHIP, context, context::timeout,
|
||||
@@ -85,12 +85,14 @@ impl GenericTimer {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn disable() {
|
||||
let mut ctrl = TimerCtrlFlags::from_bits_truncate(unsafe { control_regs::tmr_ctrl() });
|
||||
ctrl.remove(TimerCtrlFlags::ENABLE);
|
||||
unsafe { control_regs::tmr_ctrl_write(ctrl.bits()) };
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn set_irq(&mut self) {
|
||||
let mut ctrl = TimerCtrlFlags::from_bits_truncate(unsafe { control_regs::tmr_ctrl() });
|
||||
ctrl.remove(TimerCtrlFlags::IMASK);
|
||||
|
||||
@@ -88,7 +88,7 @@ impl InterruptController for GenericInterruptController {
|
||||
ic_idx: usize,
|
||||
irq_idx: &mut usize,
|
||||
) -> Result<Option<usize>> {
|
||||
let (dist_addr, dist_size, cpu_addr, cpu_size) =
|
||||
let (dist_addr, _dist_size, cpu_addr, _cpu_size) =
|
||||
match GenericInterruptController::parse(fdt) {
|
||||
Ok(regs) => regs,
|
||||
Err(err) => return Err(err),
|
||||
@@ -137,15 +137,14 @@ impl InterruptController for GenericInterruptController {
|
||||
unsafe { self.gic_dist_if.irq_disable(irq_num) }
|
||||
}
|
||||
fn irq_xlate(&mut self, irq_data: &[u32], idx: usize) -> Result<usize> {
|
||||
let mut off: usize = 0;
|
||||
let mut i = 0;
|
||||
for chunk in irq_data.chunks(3) {
|
||||
if i == idx {
|
||||
match chunk[0] {
|
||||
0 => off = chunk[1] as usize + 32, //SPI
|
||||
1 => off = chunk[1] as usize + 16, //PPI,
|
||||
let mut off = match chunk[0] {
|
||||
0 => chunk[1] as usize + 32, //SPI
|
||||
1 => chunk[1] as usize + 16, //PPI,
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
}
|
||||
};
|
||||
off += self.irq_range.0;
|
||||
return Ok(off);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
use alloc::vec::Vec;
|
||||
use core::{
|
||||
arch::asm,
|
||||
ptr::{read_volatile, write_volatile},
|
||||
};
|
||||
use core::arch::asm;
|
||||
|
||||
use byteorder::{ByteOrder, BE};
|
||||
use fdt::{DeviceTree, Node};
|
||||
use fdt::DeviceTree;
|
||||
|
||||
use super::gic::GicDistIf;
|
||||
use crate::init::device_tree::find_compatible_node;
|
||||
use log::{debug, info};
|
||||
use syscall::{
|
||||
error::{Error, EINVAL},
|
||||
Result,
|
||||
@@ -116,7 +112,7 @@ impl InterruptController for GicV3 {
|
||||
i += 1;
|
||||
}
|
||||
|
||||
info!("gic irq_range = ({}, {})", idx, idx + cnt);
|
||||
log::info!("gic irq_range = ({}, {})", idx, idx + cnt);
|
||||
self.irq_range = (idx, idx + cnt);
|
||||
*irq_idx = idx + cnt;
|
||||
Ok(None)
|
||||
@@ -135,15 +131,14 @@ impl InterruptController for GicV3 {
|
||||
unsafe { self.gic_dist_if.irq_disable(irq_num) }
|
||||
}
|
||||
fn irq_xlate(&mut self, irq_data: &[u32], idx: usize) -> Result<usize> {
|
||||
let mut off: usize = 0;
|
||||
let mut i = 0;
|
||||
for chunk in irq_data.chunks(3) {
|
||||
if i == idx {
|
||||
match chunk[0] {
|
||||
0 => off = chunk[1] as usize + 32, //SPI
|
||||
1 => off = chunk[1] as usize + 16, //PPI,
|
||||
let mut off = match chunk[0] {
|
||||
0 => chunk[1] as usize + 32, //SPI
|
||||
1 => chunk[1] as usize + 16, //PPI,
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
}
|
||||
};
|
||||
off += self.irq_range.0;
|
||||
return Ok(off);
|
||||
}
|
||||
@@ -169,37 +164,37 @@ impl GicV3CpuIf {
|
||||
unsafe fn init(&mut self) {
|
||||
// Enable system register access
|
||||
{
|
||||
let value = 1;
|
||||
let value = 1_usize;
|
||||
asm!("msr icc_sre_el1, {}", in(reg) value);
|
||||
}
|
||||
// Set control register
|
||||
{
|
||||
let value = 0;
|
||||
let value = 0_usize;
|
||||
asm!("msr icc_ctlr_el1, {}", in(reg) value);
|
||||
}
|
||||
// Enable non-secure group 1
|
||||
{
|
||||
let value = 1;
|
||||
let value = 1_usize;
|
||||
asm!("msr icc_igrpen1_el1, {}", in(reg) value);
|
||||
}
|
||||
// Set CPU0's Interrupt Priority Mask
|
||||
{
|
||||
let value = 0xFF;
|
||||
let value = 0xFF_usize;
|
||||
asm!("msr icc_pmr_el1, {}", in(reg) value);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn irq_ack(&mut self) -> u32 {
|
||||
let mut irq;
|
||||
let mut irq: usize;
|
||||
asm!("mrs {}, icc_iar1_el1", out(reg) irq);
|
||||
irq &= 0x1ff;
|
||||
if irq == 1023 {
|
||||
panic!("irq_ack: got ID 1023!!!");
|
||||
}
|
||||
irq
|
||||
irq as u32
|
||||
}
|
||||
|
||||
unsafe fn irq_eoi(&mut self, irq: u32) {
|
||||
asm!("msr icc_eoir1_el1, {}", in(reg) irq);
|
||||
asm!("msr icc_eoir1_el1, {}", in(reg) irq as usize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use alloc::{boxed::Box, vec::Vec};
|
||||
use alloc::vec::Vec;
|
||||
use core::ptr::{read_volatile, write_volatile};
|
||||
|
||||
use crate::arch::device::irqchip::IRQ_CHIP;
|
||||
@@ -39,7 +39,6 @@ fn ffs(num: u32) -> u32 {
|
||||
r += 2;
|
||||
}
|
||||
if (x & 0x1) == 0 {
|
||||
x >>= 1;
|
||||
r += 1;
|
||||
}
|
||||
|
||||
@@ -49,7 +48,6 @@ fn ffs(num: u32) -> u32 {
|
||||
const PENDING_0: u32 = 0x0;
|
||||
const PENDING_1: u32 = 0x4;
|
||||
const PENDING_2: u32 = 0x8;
|
||||
const FIQ_CTRL: u32 = 0xc;
|
||||
const ENABLE_0: u32 = 0x18;
|
||||
const ENABLE_1: u32 = 0x10;
|
||||
const ENABLE_2: u32 = 0x14;
|
||||
@@ -148,7 +146,7 @@ impl InterruptController for Bcm2835ArmInterruptController {
|
||||
ic_idx: usize,
|
||||
irq_idx: &mut usize,
|
||||
) -> Result<Option<usize>> {
|
||||
let (base, size, virq) = match Bcm2835ArmInterruptController::parse(fdt) {
|
||||
let (base, _size, virq) = match Bcm2835ArmInterruptController::parse(fdt) {
|
||||
Ok((a, b, c)) => (a, b, c),
|
||||
Err(_) => return Err(Error::new(EINVAL)),
|
||||
};
|
||||
@@ -274,7 +272,6 @@ impl InterruptController for Bcm2835ArmInterruptController {
|
||||
}
|
||||
fn irq_xlate(&mut self, irq_data: &[u32], idx: usize) -> Result<usize> {
|
||||
//assert interrupt-cells == 0x2
|
||||
let mut off: usize = 0;
|
||||
let mut i = 0;
|
||||
//assert interrupt-cells == 0x2
|
||||
for chunk in irq_data.chunks(2) {
|
||||
@@ -283,7 +280,7 @@ impl InterruptController for Bcm2835ArmInterruptController {
|
||||
let irq = chunk[1] as usize;
|
||||
//TODO: check bank && irq
|
||||
let hwirq = bank << 5 | irq;
|
||||
off = hwirq + self.irq_range.0;
|
||||
let off = hwirq + self.irq_range.0;
|
||||
return Ok(off);
|
||||
}
|
||||
i += 1;
|
||||
|
||||
@@ -21,16 +21,8 @@ const LOCAL_PRESCALER: u32 = 0x008;
|
||||
const LOCAL_GPU_ROUTING: u32 = 0x00C;
|
||||
const LOCAL_TIMER_INT_CONTROL0: u32 = 0x040;
|
||||
const LOCAL_IRQ_PENDING: u32 = 0x060;
|
||||
const LOCAL_FIQ_PENDING: u32 = 0x070;
|
||||
|
||||
const LOCAL_IRQ_CNTPSIRQ: u32 = 0x0;
|
||||
const LOCAL_IRQ_CNTPNSIRQ: u32 = 0x1;
|
||||
const LOCAL_IRQ_CNTHPIRQ: u32 = 0x2;
|
||||
const LOCAL_IRQ_CNTVIRQ: u32 = 0x3;
|
||||
const LOCAL_IRQ_MAILBOX0: u32 = 0x4;
|
||||
const LOCAL_IRQ_MAILBOX1: u32 = 0x5;
|
||||
const LOCAL_IRQ_MAILBOX2: u32 = 0x6;
|
||||
const LOCAL_IRQ_MAILBOX3: u32 = 0x7;
|
||||
const LOCAL_IRQ_GPU_FAST: u32 = 0x8;
|
||||
const LOCAL_IRQ_PMU_FAST: u32 = 0x9;
|
||||
const LOCAL_IRQ_LAST: u32 = LOCAL_IRQ_PMU_FAST;
|
||||
@@ -59,7 +51,6 @@ fn ffs(num: u32) -> u32 {
|
||||
r += 2;
|
||||
}
|
||||
if (x & 0x1) == 0 {
|
||||
x >>= 1;
|
||||
r += 1;
|
||||
}
|
||||
|
||||
@@ -128,13 +119,13 @@ impl InterruptController for Bcm2836ArmInterruptController {
|
||||
ic_idx: usize,
|
||||
irq_idx: &mut usize,
|
||||
) -> Result<Option<usize>> {
|
||||
let (base, size) = match Bcm2836ArmInterruptController::parse(fdt) {
|
||||
let (base, _size) = match Bcm2836ArmInterruptController::parse(fdt) {
|
||||
Ok((a, b)) => (a, b),
|
||||
Err(_) => return Err(Error::new(EINVAL)),
|
||||
};
|
||||
unsafe {
|
||||
self.address = base + crate::PHYS_OFFSET;
|
||||
let mut cpuid: usize = 0;
|
||||
let cpuid: usize;
|
||||
asm!("mrs {}, mpidr_el1", out(reg) cpuid);
|
||||
self.active_cpu = cpuid as u32 & 0x3;
|
||||
|
||||
@@ -160,7 +151,7 @@ impl InterruptController for Bcm2836ArmInterruptController {
|
||||
}
|
||||
|
||||
fn irq_ack(&mut self) -> u32 {
|
||||
let mut cpuid: usize = 0;
|
||||
let cpuid: usize;
|
||||
unsafe {
|
||||
asm!("mrs {}, mpidr_el1", out(reg) cpuid);
|
||||
}
|
||||
@@ -174,7 +165,7 @@ impl InterruptController for Bcm2836ArmInterruptController {
|
||||
fn irq_enable(&mut self, irq_num: u32) {
|
||||
match irq_num {
|
||||
LOCAL_IRQ_CNTPNSIRQ => unsafe {
|
||||
let mut cpuid: usize = 0;
|
||||
let cpuid: usize;
|
||||
asm!("mrs {}, mpidr_el1", out(reg) cpuid);
|
||||
let cpu = cpuid as u32 & 0x3;
|
||||
let mut reg_val = self.read(LOCAL_TIMER_INT_CONTROL0 + 4 * cpu);
|
||||
@@ -193,11 +184,9 @@ impl InterruptController for Bcm2836ArmInterruptController {
|
||||
fn irq_disable(&mut self, irq_num: u32) {
|
||||
match irq_num {
|
||||
LOCAL_IRQ_CNTPNSIRQ => unsafe {
|
||||
let mut cpuid: usize = 0;
|
||||
unsafe {
|
||||
asm!("mrs {}, mpidr_el1", out(reg) cpuid);
|
||||
}
|
||||
let mut cpu = cpuid as u32 & 0x3;
|
||||
let cpuid: usize;
|
||||
asm!("mrs {}, mpidr_el1", out(reg) cpuid);
|
||||
let cpu = cpuid as u32 & 0x3;
|
||||
let mut reg_val = self.read(LOCAL_TIMER_INT_CONTROL0 + 4 * cpu);
|
||||
reg_val &= !0x2;
|
||||
self.write(LOCAL_TIMER_INT_CONTROL0 + 4 * cpu, reg_val);
|
||||
@@ -211,12 +200,11 @@ impl InterruptController for Bcm2836ArmInterruptController {
|
||||
}
|
||||
}
|
||||
fn irq_xlate(&mut self, irq_data: &[u32], idx: usize) -> Result<usize> {
|
||||
let mut off: usize = 0;
|
||||
let mut i = 0;
|
||||
//assert interrupt-cells == 0x2
|
||||
for chunk in irq_data.chunks(2) {
|
||||
if i == idx {
|
||||
off = chunk[0] as usize + self.irq_range.0;
|
||||
let off = chunk[0] as usize + self.irq_range.0;
|
||||
return Ok(off);
|
||||
}
|
||||
i += 1;
|
||||
@@ -231,5 +219,5 @@ impl InterruptController for Bcm2836ArmInterruptController {
|
||||
}
|
||||
}
|
||||
|
||||
fn irq_handler(&mut self, irq: u32) {}
|
||||
fn irq_handler(&mut self, _irq: u32) {}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
use alloc::{
|
||||
boxed::Box,
|
||||
string::{String, ToString},
|
||||
vec::Vec,
|
||||
};
|
||||
use alloc::{boxed::Box, vec::Vec};
|
||||
use byteorder::{ByteOrder, BE};
|
||||
use fdt::DeviceTree;
|
||||
use syscall::Result;
|
||||
@@ -15,13 +11,6 @@ mod gicv3;
|
||||
mod irq_bcm2835;
|
||||
mod irq_bcm2836;
|
||||
|
||||
pub const IRQ_TYPE_NONE: u32 = 0;
|
||||
pub const IRQ_TYPE_EDGE_RISING: u32 = 1;
|
||||
pub const IRQ_TYPE_EDGE_FALLING: u32 = 2;
|
||||
pub const IRQ_TYPE_EDGE: u32 = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; //both rising && failling
|
||||
pub const IRQ_TYPE_LEVEL_HIGH: u32 = 4;
|
||||
pub const IRQ_TYPE_LEVEL_LOW: u32 = 8;
|
||||
|
||||
pub trait InterruptController {
|
||||
fn irq_init(
|
||||
&mut self,
|
||||
@@ -33,6 +22,7 @@ pub trait InterruptController {
|
||||
fn irq_ack(&mut self) -> u32;
|
||||
fn irq_eoi(&mut self, irq_num: u32);
|
||||
fn irq_enable(&mut self, irq_num: u32);
|
||||
#[allow(unused)]
|
||||
fn irq_disable(&mut self, irq_num: u32);
|
||||
fn irq_xlate(&mut self, irq_data: &[u32], idx: usize) -> Result<usize>;
|
||||
fn irq_to_virq(&mut self, hwirq: u32) -> Option<usize>;
|
||||
@@ -44,10 +34,8 @@ pub trait InterruptHandler {
|
||||
}
|
||||
|
||||
pub struct IrqChipItem {
|
||||
pub compatible: String,
|
||||
pub phandle: u32,
|
||||
pub parent_phandle: Option<u32>,
|
||||
pub intr_cell_size: u32,
|
||||
pub parent: Option<usize>, //parent idx in chiplist
|
||||
pub childs: Vec<usize>, //child idx in chiplist
|
||||
pub interrupts: Vec<u32>,
|
||||
@@ -117,10 +105,8 @@ impl IrqChipList {
|
||||
BE::read_u32(phandle.data)
|
||||
);
|
||||
let mut item = IrqChipItem {
|
||||
compatible: s.to_string(),
|
||||
phandle: BE::read_u32(phandle.data),
|
||||
parent_phandle: None,
|
||||
intr_cell_size: BE::read_u32(intr_cells.data),
|
||||
parent: None,
|
||||
childs: Vec::new(),
|
||||
interrupts: Vec::new(),
|
||||
@@ -151,10 +137,9 @@ impl IrqChipList {
|
||||
|
||||
fn init_inner2(&mut self) {
|
||||
let mut x = 0;
|
||||
let mut y = 0;
|
||||
|
||||
while x < self.chips.len() {
|
||||
y = 0;
|
||||
let mut y = 0;
|
||||
while y < self.chips.len() {
|
||||
if x == y {
|
||||
y += 1;
|
||||
@@ -193,7 +178,6 @@ impl IrqChipList {
|
||||
pub struct IrqChipCore {
|
||||
//TODO: support multi level interrupt constrollers
|
||||
pub irq_chip_list: IrqChipList,
|
||||
pub handlers: [Option<Box<dyn InterruptHandler>>; 1024],
|
||||
pub irq_desc: [IrqDesc; 1024],
|
||||
}
|
||||
|
||||
@@ -220,6 +204,7 @@ impl IrqChipCore {
|
||||
self.irq_chip_list.chips[ic_idx].ic.irq_enable(hwirq)
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn irq_disable(&mut self, virq: u32) {
|
||||
let irq_desc = &self.irq_desc[virq as usize];
|
||||
let ic_idx = irq_desc.basic.ic_idx;
|
||||
@@ -276,7 +261,6 @@ pub static mut IRQ_CHIP: IrqChipCore = IrqChipCore {
|
||||
root_phandle: 0,
|
||||
root_idx: 0,
|
||||
},
|
||||
handlers: [INIT_HANDLER; 1024],
|
||||
irq_desc: [INIT_IRQ_DESC; 1024],
|
||||
};
|
||||
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
use core::arch::asm;
|
||||
|
||||
use crate::{
|
||||
dtb::DTB_BINARY,
|
||||
memory::Frame,
|
||||
paging::{KernelMapper, Page, PageFlags, PhysicalAddress, VirtualAddress},
|
||||
};
|
||||
use log::info;
|
||||
use crate::{dtb::DTB_BINARY, info};
|
||||
|
||||
pub mod cpu;
|
||||
pub mod generic_timer;
|
||||
@@ -30,29 +23,5 @@ pub unsafe fn init_noncore() {
|
||||
rtc::init();
|
||||
}
|
||||
|
||||
pub unsafe fn init_ap() {}
|
||||
|
||||
//map physical addr X to virtual addr PHYS_OFFSET + X
|
||||
pub unsafe fn io_mmap(addr: usize, io_size: usize) {
|
||||
let mut mapper = KernelMapper::lock();
|
||||
|
||||
let start_frame = Frame::containing_address(PhysicalAddress::new(addr));
|
||||
let end_frame = Frame::containing_address(PhysicalAddress::new(addr + io_size - 1));
|
||||
for frame in Frame::range_inclusive(start_frame, end_frame) {
|
||||
let page = Page::containing_address(VirtualAddress::new(
|
||||
frame.start_address().data() + crate::PHYS_OFFSET,
|
||||
));
|
||||
mapper
|
||||
.get_mut()
|
||||
.expect("failed to access KernelMapper for mapping GIC distributor")
|
||||
.map_phys(
|
||||
page.start_address(),
|
||||
frame.start_address(),
|
||||
PageFlags::new().write(true),
|
||||
)
|
||||
.expect("failed to map GIC distributor")
|
||||
.flush();
|
||||
}
|
||||
}
|
||||
#[derive(Default)]
|
||||
pub struct ArchPercpuMisc;
|
||||
|
||||
@@ -1,19 +1,12 @@
|
||||
use core::ptr::{read_volatile, write_volatile};
|
||||
use core::ptr::read_volatile;
|
||||
|
||||
use crate::{
|
||||
memory::Frame,
|
||||
paging::{KernelMapper, Page, PageFlags, PhysicalAddress, TableKind, VirtualAddress},
|
||||
paging::{KernelMapper, Page, PageFlags, PhysicalAddress, VirtualAddress},
|
||||
time,
|
||||
};
|
||||
|
||||
static RTC_DR: u32 = 0x000;
|
||||
static RTC_MR: u32 = 0x004;
|
||||
static RTC_LR: u32 = 0x008;
|
||||
static RTC_CR: u32 = 0x00c;
|
||||
static RTC_IMSC: u32 = 0x010;
|
||||
static RTC_RIS: u32 = 0x014;
|
||||
static RTC_MIS: u32 = 0x018;
|
||||
static RTC_ICR: u32 = 0x01c;
|
||||
|
||||
static mut PL031_RTC: Pl031rtc = Pl031rtc { address: 0 };
|
||||
|
||||
@@ -57,10 +50,6 @@ impl Pl031rtc {
|
||||
val
|
||||
}
|
||||
|
||||
unsafe fn write(&mut self, reg: u32, value: u32) {
|
||||
write_volatile((self.address + reg as usize) as *mut u32, value);
|
||||
}
|
||||
|
||||
pub fn time(&mut self) -> u64 {
|
||||
let seconds = unsafe { self.read(RTC_DR) } as u64;
|
||||
seconds
|
||||
|
||||
@@ -2,12 +2,12 @@ use alloc::boxed::Box;
|
||||
use spin::Mutex;
|
||||
|
||||
use crate::{device::uart_pl011::SerialPort, init::device_tree, interrupt::irq::trigger};
|
||||
use log::{debug, info};
|
||||
|
||||
use super::irqchip::{register_irq, InterruptHandler, IRQ_CHIP};
|
||||
use crate::{dtb::DTB_BINARY, init::device_tree::find_compatible_node};
|
||||
use alloc::vec::Vec;
|
||||
use byteorder::{ByteOrder, BE};
|
||||
use log::info;
|
||||
|
||||
pub static COM1: Mutex<Option<SerialPort>> = Mutex::new(None);
|
||||
|
||||
@@ -30,7 +30,7 @@ pub unsafe fn init_early(dtb_base: usize, dtb_size: usize) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some((phys, size, skip_init, cts)) = device_tree::diag_uart_range(dtb_base, dtb_size) {
|
||||
if let Some((phys, _size, skip_init, cts)) = device_tree::diag_uart_range(dtb_base, dtb_size) {
|
||||
let virt = crate::PHYS_OFFSET + phys;
|
||||
{
|
||||
let mut serial_port = SerialPort::new(virt, skip_init, cts);
|
||||
|
||||
@@ -134,10 +134,6 @@ impl SerialPort {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn base(&self) -> usize {
|
||||
self.base
|
||||
}
|
||||
|
||||
pub fn read_reg(&self, register: u8) -> u32 {
|
||||
unsafe { ptr::read_volatile((self.base + register as usize) as *mut u32) }
|
||||
}
|
||||
@@ -230,10 +226,6 @@ impl SerialPort {
|
||||
self.write_reg(self.intr_clr_reg, flags.bits());
|
||||
}
|
||||
|
||||
pub fn disable_irq(&mut self) {
|
||||
self.write_reg(self.intr_mask_setclr_reg, 0);
|
||||
}
|
||||
|
||||
pub fn enable_irq(&mut self) {
|
||||
self.clear_all_irqs();
|
||||
|
||||
|
||||
@@ -4,8 +4,7 @@ extern crate fdt;
|
||||
use self::byteorder::{ByteOrder, BE};
|
||||
use core::slice;
|
||||
use fdt::Node;
|
||||
|
||||
use log::{debug, info};
|
||||
use log::debug;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
#[repr(C)]
|
||||
@@ -94,6 +93,7 @@ pub fn travel_interrupt_ctrl(fdt: &fdt::DeviceTree) {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn memory_ranges(
|
||||
dt: &fdt::DeviceTree,
|
||||
address_cells: usize,
|
||||
@@ -106,7 +106,7 @@ fn memory_ranges(
|
||||
.find(|p| p.name.contains("reg"))
|
||||
.unwrap();
|
||||
let chunk_sz = (address_cells + size_cells) * 4;
|
||||
let chunk_count = (reg.data.len() / chunk_sz);
|
||||
let chunk_count = reg.data.len() / chunk_sz;
|
||||
let mut index = 0;
|
||||
for chunk in reg.data.chunks(chunk_sz as usize) {
|
||||
if index == chunk_count {
|
||||
@@ -157,7 +157,7 @@ fn dev_memory_ranges(
|
||||
.find(|p| p.name.contains("ranges"))
|
||||
.unwrap();
|
||||
let chunk_sz = (address_cells * 2 + size_cells) * 4;
|
||||
let chunk_count = (reg.data.len() / chunk_sz);
|
||||
let chunk_count = reg.data.len() / chunk_sz;
|
||||
let mut index = 0;
|
||||
for chunk in reg.data.chunks(chunk_sz as usize) {
|
||||
if index == chunk_count {
|
||||
@@ -238,7 +238,7 @@ pub fn diag_uart_range(dtb_base: usize, dtb_size: usize) -> Option<(usize, usize
|
||||
.unwrap();
|
||||
|
||||
let (address_cells, size_cells) = root_cell_sz(&dt).unwrap();
|
||||
let chunk_sz = (address_cells + size_cells) * 4;
|
||||
let _chunk_sz = (address_cells + size_cells) * 4;
|
||||
let (base, size) = reg.data.split_at((address_cells * 4) as usize);
|
||||
let mut b = 0;
|
||||
// FIXME likely needs shifting before addition
|
||||
@@ -252,18 +252,6 @@ pub fn diag_uart_range(dtb_base: usize, dtb_size: usize) -> Option<(usize, usize
|
||||
Some((b as usize, s as usize, skip_init, cts_event_walkaround))
|
||||
}
|
||||
|
||||
fn compatible_node_present<'a>(dt: &fdt::DeviceTree<'a>, compat_string: &str) -> bool {
|
||||
for node in dt.nodes() {
|
||||
if let Some(compatible) = node.properties().find(|p| p.name.contains("compatible")) {
|
||||
let s = core::str::from_utf8(compatible.data).unwrap();
|
||||
if s.contains(compat_string) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn find_compatible_node<'a>(
|
||||
dt: &'a fdt::DeviceTree<'a>,
|
||||
compat_string: &str,
|
||||
@@ -279,6 +267,7 @@ pub fn find_compatible_node<'a>(
|
||||
None
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn fill_env_data(dtb_base: usize, dtb_size: usize, env_base: usize) -> usize {
|
||||
let data = unsafe { slice::from_raw_parts(dtb_base as *const u8, dtb_size) };
|
||||
let dt = fdt::DeviceTree::new(data).unwrap();
|
||||
|
||||
@@ -34,7 +34,7 @@ unsafe fn instr_data_abort_inner(
|
||||
stack: &mut InterruptStack,
|
||||
from_user: bool,
|
||||
instr_not_data: bool,
|
||||
from: &str,
|
||||
_from: &str,
|
||||
) -> bool {
|
||||
let iss = iss(stack.iret.esr_el1);
|
||||
let fsc = iss & 0x3F;
|
||||
@@ -82,12 +82,12 @@ unsafe fn cntvct_el0() -> usize {
|
||||
|
||||
unsafe fn instr_trapped_msr_mrs_inner(
|
||||
stack: &mut InterruptStack,
|
||||
from_user: bool,
|
||||
instr_not_data: bool,
|
||||
from: &str,
|
||||
_from_user: bool,
|
||||
_instr_not_data: bool,
|
||||
_from: &str,
|
||||
) -> bool {
|
||||
let iss = iss(stack.iret.esr_el1);
|
||||
let res0 = (iss & 0x1C0_0000) >> 22;
|
||||
// let res0 = (iss & 0x1C0_0000) >> 22;
|
||||
let op0 = (iss & 0x030_0000) >> 20;
|
||||
let op2 = (iss & 0x00e_0000) >> 17;
|
||||
let op1 = (iss & 0x001_c000) >> 14;
|
||||
|
||||
@@ -22,7 +22,7 @@ pub struct ScratchRegisters {
|
||||
pub x16: usize,
|
||||
pub x17: usize,
|
||||
pub x18: usize,
|
||||
pub padding: usize,
|
||||
pub _padding: usize,
|
||||
}
|
||||
|
||||
impl ScratchRegisters {
|
||||
@@ -262,10 +262,7 @@ impl InterruptStack {
|
||||
}
|
||||
|
||||
//TODO
|
||||
pub fn is_singlestep(&self) -> bool {
|
||||
false
|
||||
}
|
||||
pub fn set_singlestep(&mut self, singlestep: bool) {}
|
||||
pub fn set_singlestep(&mut self, _singlestep: bool) {}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
//use crate::device::generic_timer::{GENTIMER};
|
||||
use crate::device::{irqchip::IRQ_CHIP, serial::COM1};
|
||||
use crate::device::irqchip::IRQ_CHIP;
|
||||
|
||||
pub struct IrqDesc {
|
||||
pub virq: u32,
|
||||
pub hwirq: u32,
|
||||
}
|
||||
|
||||
exception_stack!(irq_at_el0, |stack| {
|
||||
exception_stack!(irq_at_el0, |_stack| {
|
||||
let irq = IRQ_CHIP.irq_ack();
|
||||
if let Some(virq) = IRQ_CHIP.irq_to_virq(irq)
|
||||
&& virq < 1024
|
||||
@@ -23,7 +17,7 @@ exception_stack!(irq_at_el0, |stack| {
|
||||
}
|
||||
});
|
||||
|
||||
exception_stack!(irq_at_el1, |stack| {
|
||||
exception_stack!(irq_at_el1, |_stack| {
|
||||
let irq = IRQ_CHIP.irq_ack();
|
||||
if let Some(virq) = IRQ_CHIP.irq_to_virq(irq)
|
||||
&& virq < 1024
|
||||
@@ -54,13 +48,6 @@ pub unsafe fn acknowledge(_irq: usize) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
pub unsafe fn irq_handler_com1(irq: u32) {
|
||||
if let Some(ref mut serial_port) = *COM1.lock() {
|
||||
serial_port.receive();
|
||||
};
|
||||
trigger(irq);
|
||||
}
|
||||
|
||||
/*
|
||||
pub unsafe fn irq_handler_gentimer(irq: u32) {
|
||||
GENTIMER.clear_irq();
|
||||
|
||||
@@ -20,12 +20,6 @@ pub unsafe fn disable() {
|
||||
asm!("msr daifset, #2");
|
||||
}
|
||||
|
||||
/// Set interrupts
|
||||
#[inline(always)]
|
||||
pub unsafe fn enable() {
|
||||
asm!("msr daifclr, #2");
|
||||
}
|
||||
|
||||
/// Set interrupts and halt
|
||||
/// This will atomically wait for the next interrupt
|
||||
/// Performing enable followed by halt is not guaranteed to be atomic, use this instead!
|
||||
@@ -57,7 +51,7 @@ pub fn pause() {
|
||||
unsafe { asm!("nop") };
|
||||
}
|
||||
|
||||
pub fn available_irqs_iter(cpu_id: LogicalCpuId) -> impl Iterator<Item = u8> + 'static {
|
||||
pub fn available_irqs_iter(_cpu_id: LogicalCpuId) -> impl Iterator<Item = u8> + 'static {
|
||||
0..0
|
||||
}
|
||||
|
||||
@@ -67,12 +61,12 @@ pub fn bsp_apic_id() -> Option<u32> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_reserved(cpu_id: LogicalCpuId, index: u8) -> bool {
|
||||
pub fn is_reserved(_cpu_id: LogicalCpuId, _index: u8) -> bool {
|
||||
//TODO
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_reserved(cpu_id: LogicalCpuId, index: u8, reserved: bool) {
|
||||
pub fn set_reserved(_cpu_id: LogicalCpuId, _index: u8, _reserved: bool) {
|
||||
//TODO
|
||||
}
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
use crate::{
|
||||
arch::interrupt::InterruptStack,
|
||||
context, syscall,
|
||||
syscall::flag::{PTRACE_FLAG_IGNORE, PTRACE_STOP_POST_SYSCALL, PTRACE_STOP_PRE_SYSCALL},
|
||||
};
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn do_exception_unhandled() {}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use core::{arch::asm, mem};
|
||||
use goblin::elf::sym;
|
||||
|
||||
use crate::paging::{KernelMapper, TableKind, VirtualAddress};
|
||||
use crate::paging::{KernelMapper, VirtualAddress};
|
||||
|
||||
/// Get a stack trace
|
||||
//TODO: Check for stack being mapped before dereferencing
|
||||
@@ -37,117 +36,3 @@ pub unsafe fn stack_trace() {
|
||||
}
|
||||
}
|
||||
}
|
||||
///
|
||||
/// Get a symbol
|
||||
//TODO: Do not create Elf object for every symbol lookup
|
||||
#[inline(never)]
|
||||
pub unsafe fn symbol_trace(addr: usize) {
|
||||
use core::{slice, sync::atomic::Ordering};
|
||||
|
||||
use crate::{
|
||||
elf::Elf,
|
||||
start::{KERNEL_BASE, KERNEL_SIZE},
|
||||
};
|
||||
|
||||
let kernel_ptr = (KERNEL_BASE.load(Ordering::SeqCst) + crate::KERNEL_OFFSET) as *const u8;
|
||||
let kernel_slice = slice::from_raw_parts(kernel_ptr, KERNEL_SIZE.load(Ordering::SeqCst));
|
||||
|
||||
println!("symbol_trace: 0, kernel_ptr = 0x{:x}", kernel_ptr as usize);
|
||||
|
||||
match Elf::from(kernel_slice) {
|
||||
Ok(elf) => {
|
||||
println!("symbol_trace: 1");
|
||||
let mut strtab_opt = None;
|
||||
for section in elf.sections() {
|
||||
if section.sh_type == ::goblin::elf::section_header::SHT_STRTAB {
|
||||
strtab_opt = Some(section);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
println!("symbol_trace: 2");
|
||||
|
||||
if let Some(symbols) = elf.symbols() {
|
||||
println!("symbol_trace: 3");
|
||||
for sym in symbols {
|
||||
if sym::st_type(sym.st_info) == sym::STT_FUNC
|
||||
&& addr >= sym.st_value as usize
|
||||
&& addr < (sym.st_value + sym.st_size) as usize
|
||||
{
|
||||
println!(
|
||||
" {:>016X}+{:>04X}",
|
||||
sym.st_value,
|
||||
addr - sym.st_value as usize
|
||||
);
|
||||
|
||||
if let Some(strtab) = strtab_opt {
|
||||
let start = strtab.sh_offset as usize + sym.st_name as usize;
|
||||
let mut end = start;
|
||||
while end < elf.data.len() {
|
||||
let b = elf.data[end];
|
||||
end += 1;
|
||||
if b == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if end > start {
|
||||
let sym_name = &elf.data[start..end];
|
||||
|
||||
print!(" ");
|
||||
|
||||
if sym_name.starts_with(b"_ZN") {
|
||||
// Skip _ZN
|
||||
let mut i = 3;
|
||||
let mut first = true;
|
||||
while i < sym_name.len() {
|
||||
// E is the end character
|
||||
if sym_name[i] == b'E' {
|
||||
break;
|
||||
}
|
||||
|
||||
// Parse length string
|
||||
let mut len = 0;
|
||||
while i < sym_name.len() {
|
||||
let b = sym_name[i];
|
||||
if b >= b'0' && b <= b'9' {
|
||||
i += 1;
|
||||
len *= 10;
|
||||
len += (b - b'0') as usize;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Print namespace seperator, if required
|
||||
if first {
|
||||
first = false;
|
||||
} else {
|
||||
print!("::");
|
||||
}
|
||||
|
||||
// Print name string
|
||||
let end = i + len;
|
||||
while i < sym_name.len() && i < end {
|
||||
print!("{}", sym_name[i] as char);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for &b in sym_name.iter() {
|
||||
print!("{}", b as char);
|
||||
}
|
||||
}
|
||||
|
||||
println!("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_e) => {
|
||||
println!("WTF ?");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,15 +3,11 @@
|
||||
pub enum IpiKind {
|
||||
Wakeup = 0x40,
|
||||
Tlb = 0x41,
|
||||
Switch = 0x42,
|
||||
Pit = 0x43,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(u8)]
|
||||
pub enum IpiTarget {
|
||||
Current = 1,
|
||||
All = 2,
|
||||
Other = 3,
|
||||
}
|
||||
|
||||
@@ -21,7 +17,7 @@ pub fn ipi(_kind: IpiKind, _target: IpiTarget) {}
|
||||
|
||||
#[cfg(feature = "multi_core")]
|
||||
#[inline(always)]
|
||||
pub fn ipi(kind: IpiKind, target: IpiTarget) {}
|
||||
pub fn ipi(_kind: IpiKind, _target: IpiTarget) {}
|
||||
|
||||
#[cfg(not(feature = "multi_core"))]
|
||||
#[inline(always)]
|
||||
@@ -29,4 +25,4 @@ pub fn ipi_single(_kind: IpiKind, _target: crate::cpu_set::LogicalCpuId) {}
|
||||
|
||||
#[cfg(feature = "multi_core")]
|
||||
#[inline(always)]
|
||||
pub fn ipi_single(kind: IpiKind, target: crate::cpu_set::LogicalCpuId) {}
|
||||
pub fn ipi_single(_kind: IpiKind, _target: crate::cpu_set::LogicalCpuId) {}
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
use core::{
|
||||
cell::{Cell, RefCell},
|
||||
sync::atomic::AtomicBool,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
cpu_set::LogicalCpuId,
|
||||
paging::{RmmA, RmmArch},
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
//! # Page table entry
|
||||
//! Some code borrowed from [Phil Opp's Blog](http://os.phil-opp.com/modifying-page-tables.html)
|
||||
|
||||
/// A page table entry
|
||||
#[repr(packed(8))]
|
||||
pub struct Entry(u64);
|
||||
|
||||
bitflags! {
|
||||
pub struct EntryFlags: usize {
|
||||
const NO_CACHE = 1 << 2;
|
||||
|
||||
@@ -7,13 +7,6 @@ pub use rmm::{Flusher, PageFlush, PageFlushAll};
|
||||
pub struct InactiveFlusher {
|
||||
_inner: (),
|
||||
}
|
||||
impl InactiveFlusher {
|
||||
// TODO: cpu id
|
||||
pub fn new() -> Self {
|
||||
Self { _inner: () }
|
||||
}
|
||||
}
|
||||
|
||||
impl Flusher<RmmA> for InactiveFlusher {
|
||||
fn consume(&mut self, flush: PageFlush<RmmA>) {
|
||||
// TODO: Push to TLB "mailbox" or tell it to reload CR3 if there are too many entries.
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
//! # Paging
|
||||
//! Some code was borrowed from [Phil Opp's Blog](http://os.phil-opp.com/modifying-page-tables.html)
|
||||
|
||||
use core::{mem, ptr};
|
||||
|
||||
use crate::device::cpu::registers::{control_regs, tlb};
|
||||
|
||||
use self::mapper::PageFlushAll;
|
||||
use crate::device::cpu::registers::control_regs;
|
||||
|
||||
pub use super::CurrentRmmArch as RmmA;
|
||||
pub use rmm::{Arch as RmmArch, Flusher, PageFlags, PhysicalAddress, TableKind, VirtualAddress};
|
||||
pub use rmm::{Arch as RmmArch, PageFlags, PhysicalAddress, TableKind, VirtualAddress};
|
||||
|
||||
pub type PageMapper = rmm::PageMapper<RmmA, crate::memory::TheFrameAllocator>;
|
||||
pub use crate::rmm::KernelMapper;
|
||||
@@ -16,9 +12,6 @@ pub use crate::rmm::KernelMapper;
|
||||
pub mod entry;
|
||||
pub mod mapper;
|
||||
|
||||
/// Number of entries per page table
|
||||
pub const ENTRY_COUNT: usize = RmmA::PAGE_ENTRIES;
|
||||
|
||||
/// Size of pages
|
||||
pub const PAGE_SIZE: usize = RmmA::PAGE_SIZE;
|
||||
pub const PAGE_MASK: usize = RmmA::PAGE_OFFSET_MASK;
|
||||
@@ -52,22 +45,6 @@ impl Page {
|
||||
VirtualAddress::new(self.number * PAGE_SIZE)
|
||||
}
|
||||
|
||||
pub fn p4_index(self) -> usize {
|
||||
(self.number >> 27) & 0o777
|
||||
}
|
||||
|
||||
pub fn p3_index(self) -> usize {
|
||||
(self.number >> 18) & 0o777
|
||||
}
|
||||
|
||||
pub fn p2_index(self) -> usize {
|
||||
(self.number >> 9) & 0o777
|
||||
}
|
||||
|
||||
pub fn p1_index(self) -> usize {
|
||||
self.number & 0o777
|
||||
}
|
||||
|
||||
pub fn containing_address(address: VirtualAddress) -> Page {
|
||||
//TODO assert!(address.data() < 0x0000_8000_0000_0000 || address.data() >= 0xffff_8000_0000_0000,
|
||||
// "invalid address: 0x{:x}", address.data());
|
||||
@@ -82,10 +59,6 @@ impl Page {
|
||||
end: r#final.next(),
|
||||
}
|
||||
}
|
||||
pub fn range_exclusive(start: Page, end: Page) -> PageIter {
|
||||
PageIter { start, end }
|
||||
}
|
||||
|
||||
pub fn next(self) -> Page {
|
||||
self.next_by(1)
|
||||
}
|
||||
|
||||
+3
-11
@@ -4,10 +4,9 @@ use core::{
|
||||
sync::atomic::{self, AtomicUsize, Ordering},
|
||||
};
|
||||
use rmm::{
|
||||
Arch, BuddyAllocator, BumpAllocator, FrameAllocator, FrameCount, FrameUsage, MemoryArea,
|
||||
PageFlags, PageMapper, PhysicalAddress, TableKind, VirtualAddress, KILOBYTE, MEGABYTE,
|
||||
Arch, BumpAllocator, MemoryArea, PageFlags, PageMapper, PhysicalAddress, TableKind,
|
||||
VirtualAddress, KILOBYTE, MEGABYTE,
|
||||
};
|
||||
use spin::Mutex;
|
||||
|
||||
use crate::{cpu_set::LogicalCpuId, init::device_tree::MEMORY_MAP, paging::entry::EntryFlags};
|
||||
|
||||
@@ -16,6 +15,7 @@ use super::CurrentRmmArch as RmmA;
|
||||
// Keep synced with OsMemoryKind in bootloader
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
#[repr(u64)]
|
||||
#[allow(dead_code)]
|
||||
pub enum BootloaderMemoryKind {
|
||||
Null = 0,
|
||||
Free = 1,
|
||||
@@ -216,14 +216,6 @@ static AREAS: SyncUnsafeCell<[MemoryArea; 512]> = SyncUnsafeCell::new(
|
||||
);
|
||||
static AREA_COUNT: SyncUnsafeCell<u16> = SyncUnsafeCell::new(0);
|
||||
|
||||
// TODO: Share code
|
||||
pub fn areas() -> &'static [MemoryArea] {
|
||||
// SAFETY: Both AREAS and AREA_COUNT are initialized once and then never changed.
|
||||
//
|
||||
// TODO: Memory hotplug?
|
||||
unsafe { &(&*AREAS.get())[..AREA_COUNT.get().read().into()] }
|
||||
}
|
||||
|
||||
const NO_PROCESSOR: usize = !0;
|
||||
static LOCK_OWNER: AtomicUsize = AtomicUsize::new(NO_PROCESSOR);
|
||||
static LOCK_COUNT: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
@@ -5,19 +5,10 @@
|
||||
use core::slice;
|
||||
use core::sync::atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering};
|
||||
|
||||
use crate::{
|
||||
memory::Frame,
|
||||
paging::{Page, PhysicalAddress, VirtualAddress, PAGE_SIZE},
|
||||
};
|
||||
|
||||
#[cfg(feature = "graphical_debug")]
|
||||
use crate::devices::graphical_debug;
|
||||
use crate::{
|
||||
allocator, device, dtb,
|
||||
init::device_tree,
|
||||
interrupt,
|
||||
paging::{self, KernelMapper},
|
||||
};
|
||||
|
||||
use crate::{allocator, device, dtb, init::device_tree, paging};
|
||||
use log::info;
|
||||
|
||||
/// Test of zero values in BSS.
|
||||
@@ -201,6 +192,7 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! {
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
#[allow(unused)]
|
||||
pub struct KernelArgsAp {
|
||||
cpu_id: u64,
|
||||
page_table: u64,
|
||||
@@ -209,6 +201,7 @@ pub struct KernelArgsAp {
|
||||
}
|
||||
|
||||
/// Entry to rust for an AP
|
||||
pub unsafe extern "C" fn kstart_ap(args_ptr: *const KernelArgsAp) -> ! {
|
||||
#[allow(unused)]
|
||||
pub unsafe extern "C" fn kstart_ap(_args_ptr: *const KernelArgsAp) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
@@ -3,21 +3,24 @@ use core::arch::asm;
|
||||
pub unsafe fn kreset() -> ! {
|
||||
println!("kreset");
|
||||
|
||||
let val: u32 = 0x8400_0009;
|
||||
asm!("mov x0, {}", in(reg) val);
|
||||
asm!("hvc #0", options(noreturn));
|
||||
asm!("hvc #0",
|
||||
in("x0") 0x8400_0009_usize,
|
||||
options(noreturn),
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn emergency_reset() -> ! {
|
||||
let val: u32 = 0x8400_0009;
|
||||
asm!("mov x0, {}", in(reg) val);
|
||||
asm!("hvc #0", options(noreturn));
|
||||
asm!("hvc #0",
|
||||
in("x0") 0x8400_0009_usize,
|
||||
options(noreturn),
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn kstop() -> ! {
|
||||
println!("kstop");
|
||||
|
||||
let val: u32 = 0x8400_0008;
|
||||
asm!("mov x0, {}", in(reg) val);
|
||||
asm!("hvc #0", options(noreturn));
|
||||
asm!("hvc #0",
|
||||
in("x0") 0x8400_0008_usize,
|
||||
options(noreturn),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#![allow(unused)]
|
||||
// Because the memory map is so important to not be aliased, it is defined here, in one place
|
||||
// The lower 256 PML4 entries are reserved for userspace
|
||||
// Each PML4 entry references up to 512 GB of memory
|
||||
|
||||
+1
-9
@@ -1,12 +1,6 @@
|
||||
//! Global descriptor table
|
||||
|
||||
use core::{
|
||||
cell::{Cell, RefCell},
|
||||
convert::TryInto,
|
||||
mem,
|
||||
ptr::addr_of_mut,
|
||||
sync::atomic::AtomicBool,
|
||||
};
|
||||
use core::{mem, ptr::addr_of_mut};
|
||||
|
||||
use crate::cpu_set::LogicalCpuId;
|
||||
|
||||
@@ -19,8 +13,6 @@ use x86::{
|
||||
|
||||
use crate::paging::{RmmA, RmmArch, PAGE_SIZE};
|
||||
|
||||
use super::cpuid::cpuid;
|
||||
|
||||
pub const GDT_NULL: usize = 0;
|
||||
pub const GDT_KERNEL_CODE: usize = 1;
|
||||
pub const GDT_KERNEL_DATA: usize = 2;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use rmm::TableKind;
|
||||
use x86::irq::PageFaultError;
|
||||
|
||||
use crate::{
|
||||
|
||||
@@ -174,10 +174,6 @@ impl InterruptStack {
|
||||
self.iret.eflags &= !FLAG_SINGLESTEP;
|
||||
}
|
||||
}
|
||||
/// Checks if the trap flag is enabled, see `set_singlestep`
|
||||
pub fn is_singlestep(&self) -> bool {
|
||||
self.iret.eflags & FLAG_SINGLESTEP == FLAG_SINGLESTEP
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
use crate::{
|
||||
arch::{gdt, interrupt::InterruptStack},
|
||||
context, ptrace, syscall,
|
||||
ptrace, syscall,
|
||||
syscall::flag::{PTRACE_FLAG_IGNORE, PTRACE_STOP_POST_SYSCALL, PTRACE_STOP_PRE_SYSCALL},
|
||||
};
|
||||
use core::mem::offset_of;
|
||||
use x86::{bits32::task::TaskStateSegment, msr, segmentation::SegmentSelector};
|
||||
|
||||
pub unsafe fn init() {}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ pub use ::rmm::X86Arch as CurrentRmmArch;
|
||||
pub mod flags {
|
||||
pub const SHIFT_SINGLESTEP: usize = 8;
|
||||
pub const FLAG_SINGLESTEP: usize = 1 << SHIFT_SINGLESTEP;
|
||||
pub const FLAG_INTERRUPTS: usize = 1 << 9;
|
||||
}
|
||||
|
||||
#[naked]
|
||||
|
||||
@@ -7,13 +7,6 @@ pub use rmm::{Flusher, PageFlush, PageFlushAll};
|
||||
pub struct InactiveFlusher {
|
||||
_inner: (),
|
||||
}
|
||||
impl InactiveFlusher {
|
||||
// TODO: cpu id
|
||||
pub fn new() -> Self {
|
||||
Self { _inner: () }
|
||||
}
|
||||
}
|
||||
|
||||
impl Flusher<RmmA> for InactiveFlusher {
|
||||
fn consume(&mut self, flush: PageFlush<RmmA>) {
|
||||
// TODO: Push to TLB "mailbox" or tell it to reload CR3 if there are too many entries.
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
//! # Paging
|
||||
//! Some code was borrowed from [Phil Opp's Blog](http://os.phil-opp.com/modifying-page-tables.html)
|
||||
|
||||
use core::{mem, ptr};
|
||||
use x86::msr;
|
||||
|
||||
use self::mapper::PageFlushAll;
|
||||
|
||||
pub use super::CurrentRmmArch as RmmA;
|
||||
pub use rmm::{Arch as RmmArch, Flusher, PageFlags, PhysicalAddress, TableKind, VirtualAddress};
|
||||
pub use rmm::{Arch as RmmArch, PageFlags, PhysicalAddress, TableKind, VirtualAddress};
|
||||
|
||||
pub type PageMapper = rmm::PageMapper<RmmA, crate::memory::TheFrameAllocator>;
|
||||
pub use crate::rmm::KernelMapper;
|
||||
@@ -24,9 +21,6 @@ pub mod entry {
|
||||
|
||||
pub mod mapper;
|
||||
|
||||
/// Number of entries per page table
|
||||
pub const ENTRY_COUNT: usize = RmmA::PAGE_ENTRIES;
|
||||
|
||||
/// Size of pages
|
||||
pub const PAGE_SIZE: usize = RmmA::PAGE_SIZE;
|
||||
pub const PAGE_MASK: usize = RmmA::PAGE_OFFSET_MASK;
|
||||
@@ -80,22 +74,6 @@ impl Page {
|
||||
VirtualAddress::new(self.number * PAGE_SIZE)
|
||||
}
|
||||
|
||||
pub fn p4_index(self) -> usize {
|
||||
(self.number >> 27) & 0o777
|
||||
}
|
||||
|
||||
pub fn p3_index(self) -> usize {
|
||||
(self.number >> 18) & 0o777
|
||||
}
|
||||
|
||||
pub fn p2_index(self) -> usize {
|
||||
(self.number >> 9) & 0o777
|
||||
}
|
||||
|
||||
pub fn p1_index(self) -> usize {
|
||||
self.number & 0o777
|
||||
}
|
||||
|
||||
pub fn containing_address(address: VirtualAddress) -> Page {
|
||||
//TODO assert!(address.data() < 0x0000_8000_0000_0000 || address.data() >= 0xffff_8000_0000_0000,
|
||||
// "invalid address: 0x{:x}", address.data());
|
||||
@@ -110,10 +88,6 @@ impl Page {
|
||||
end: r#final.next(),
|
||||
}
|
||||
}
|
||||
pub fn range_exclusive(start: Page, end: Page) -> PageIter {
|
||||
PageIter { start, end }
|
||||
}
|
||||
|
||||
pub fn next(self) -> Page {
|
||||
self.next_by(1)
|
||||
}
|
||||
|
||||
+3
-9
@@ -4,11 +4,9 @@ use core::{
|
||||
sync::atomic::{self, AtomicUsize, Ordering},
|
||||
};
|
||||
use rmm::{
|
||||
Arch, BuddyAllocator, BumpAllocator, FrameAllocator, FrameCount, FrameUsage, MemoryArea,
|
||||
PageEntry, PageFlags, PageMapper, PhysicalAddress, TableKind, VirtualAddress, KILOBYTE,
|
||||
MEGABYTE,
|
||||
Arch, BumpAllocator, FrameAllocator, MemoryArea, PageEntry, PageFlags, PageMapper,
|
||||
PhysicalAddress, TableKind, VirtualAddress, KILOBYTE, MEGABYTE,
|
||||
};
|
||||
use spin::Mutex;
|
||||
|
||||
use crate::{cpu_set::LogicalCpuId, memory::TheFrameAllocator};
|
||||
|
||||
@@ -17,6 +15,7 @@ use super::CurrentRmmArch as RmmA;
|
||||
// Keep synced with OsMemoryKind in bootloader
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
#[repr(u64)]
|
||||
#[allow(dead_code)]
|
||||
pub enum BootloaderMemoryKind {
|
||||
Null = 0,
|
||||
Free = 1,
|
||||
@@ -197,11 +196,6 @@ static AREAS: SyncUnsafeCell<[MemoryArea; 512]> = SyncUnsafeCell::new(
|
||||
);
|
||||
static AREA_COUNT: SyncUnsafeCell<u16> = SyncUnsafeCell::new(0);
|
||||
|
||||
pub fn areas() -> &'static [MemoryArea] {
|
||||
// SAFETY: Both areas and AREA_COUNT are initialized once and then never changed.
|
||||
unsafe { &(&*AREAS.get())[..AREA_COUNT.get().read().into()] }
|
||||
}
|
||||
|
||||
const NO_PROCESSOR: usize = !0;
|
||||
static LOCK_OWNER: AtomicUsize = AtomicUsize::new(NO_PROCESSOR);
|
||||
static LOCK_COUNT: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
@@ -11,10 +11,9 @@ use crate::acpi;
|
||||
use crate::devices::graphical_debug;
|
||||
use crate::{
|
||||
allocator,
|
||||
arch::{flags::*, pti},
|
||||
cpu_set::LogicalCpuId,
|
||||
device, gdt, idt, interrupt, memory,
|
||||
paging::{self, KernelMapper, PhysicalAddress, RmmA, RmmArch, TableKind},
|
||||
device, gdt, idt, interrupt,
|
||||
paging::{self, PhysicalAddress, RmmA, RmmArch, TableKind},
|
||||
};
|
||||
use log::info;
|
||||
|
||||
|
||||
@@ -185,10 +185,6 @@ impl InterruptStack {
|
||||
self.iret.rflags &= !FLAG_SINGLESTEP;
|
||||
}
|
||||
}
|
||||
/// Checks if the trap flag is enabled, see `set_singlestep`
|
||||
pub fn is_singlestep(&self) -> bool {
|
||||
self.iret.rflags & FLAG_SINGLESTEP == FLAG_SINGLESTEP
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
|
||||
@@ -35,7 +35,6 @@ pub use ::rmm::X8664Arch as CurrentRmmArch;
|
||||
pub mod flags {
|
||||
pub const SHIFT_SINGLESTEP: usize = 8;
|
||||
pub const FLAG_SINGLESTEP: usize = 1 << SHIFT_SINGLESTEP;
|
||||
pub const FLAG_INTERRUPTS: usize = 1 << 9;
|
||||
}
|
||||
|
||||
// TODO: Maybe support rewriting relocations (using LD's --emit-relocs) when working with entire
|
||||
|
||||
@@ -7,13 +7,6 @@ pub use rmm::{Flusher, PageFlush, PageFlushAll};
|
||||
pub struct InactiveFlusher {
|
||||
_inner: (),
|
||||
}
|
||||
impl InactiveFlusher {
|
||||
// TODO: cpu id
|
||||
pub fn new() -> Self {
|
||||
Self { _inner: () }
|
||||
}
|
||||
}
|
||||
|
||||
impl Flusher<RmmA> for InactiveFlusher {
|
||||
fn consume(&mut self, flush: PageFlush<RmmA>) {
|
||||
// TODO: Push to TLB "mailbox" or tell it to reload CR3 if there are too many entries.
|
||||
|
||||
@@ -91,10 +91,6 @@ impl Page {
|
||||
end: r#final.next(),
|
||||
}
|
||||
}
|
||||
pub fn range_exclusive(start: Page, end: Page) -> PageIter {
|
||||
PageIter { start, end }
|
||||
}
|
||||
|
||||
pub fn next(self) -> Page {
|
||||
self.next_by(1)
|
||||
}
|
||||
|
||||
@@ -9,11 +9,13 @@ use crate::acpi::madt::{self, Madt, MadtEntry, MadtIntSrcOverride, MadtIoApic};
|
||||
use crate::{
|
||||
arch::interrupt::irq,
|
||||
memory::Frame,
|
||||
paging::{entry::EntryFlags, KernelMapper, Page, PageFlags, PhysicalAddress, RmmA, RmmArch},
|
||||
paging::{entry::EntryFlags, KernelMapper, Page, PageFlags, PhysicalAddress},
|
||||
};
|
||||
|
||||
use super::pic;
|
||||
use crate::arch::cpuid::cpuid;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use {crate::memory::RmmA, rmm::Arch};
|
||||
|
||||
pub struct IoApicRegs {
|
||||
pointer: *const u32,
|
||||
@@ -46,15 +48,9 @@ impl IoApicRegs {
|
||||
pub fn read_ioapicid(&mut self) -> u32 {
|
||||
self.read_reg(0x00)
|
||||
}
|
||||
pub fn write_ioapicid(&mut self, value: u32) {
|
||||
self.write_reg(0x00, value);
|
||||
}
|
||||
pub fn read_ioapicver(&mut self) -> u32 {
|
||||
self.read_reg(0x01)
|
||||
}
|
||||
pub fn read_ioapicarb(&mut self) -> u32 {
|
||||
self.read_reg(0x02)
|
||||
}
|
||||
pub fn read_ioredtbl(&mut self, idx: u8) -> u64 {
|
||||
assert!(idx < 24);
|
||||
let lo = self.read_reg(0x10 + idx * 2);
|
||||
@@ -76,6 +72,7 @@ impl IoApicRegs {
|
||||
let ver = self.read_ioapicver();
|
||||
((ver & 0x00FF_0000) >> 16) as u8
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub fn id(&mut self) -> u8 {
|
||||
let id_reg = self.read_ioapicid();
|
||||
((id_reg & 0x0F00_0000) >> 24) as u8
|
||||
@@ -87,6 +84,7 @@ pub struct IoApic {
|
||||
count: u8,
|
||||
}
|
||||
impl IoApic {
|
||||
#[allow(dead_code)]
|
||||
pub fn new(regs_base: *const u32, gsi_start: u32) -> Self {
|
||||
let mut regs = IoApicRegs { pointer: regs_base };
|
||||
let count = regs.max_redirection_table_entries();
|
||||
@@ -98,6 +96,7 @@ impl IoApic {
|
||||
}
|
||||
}
|
||||
/// Map an interrupt vector to a physical local APIC ID of a processor (thus physical mode).
|
||||
#[allow(dead_code)]
|
||||
pub fn map(&self, idx: u8, info: MapInfo) {
|
||||
self.regs.lock().write_ioredtbl(idx, info.as_raw())
|
||||
}
|
||||
@@ -125,12 +124,14 @@ pub enum ApicPolarity {
|
||||
}
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[allow(unused)]
|
||||
pub enum DestinationMode {
|
||||
Physical = 0,
|
||||
Logical = 1,
|
||||
}
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[allow(unused)]
|
||||
pub enum DeliveryMode {
|
||||
Fixed = 0b000,
|
||||
LowestPriority = 0b001,
|
||||
@@ -297,6 +298,7 @@ pub unsafe fn handle_src_override(src_override: &'static MadtIntSrcOverride) {
|
||||
SRC_OVERRIDES.get_or_insert_with(Vec::new).push(over);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub unsafe fn init(active_table: &mut KernelMapper) {
|
||||
let bsp_apic_id = cpuid().get_feature_info().unwrap().initial_local_apic_id(); // TODO: remove unwraps
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use x86::msr::*;
|
||||
|
||||
use crate::{
|
||||
ipi::IpiKind,
|
||||
paging::{KernelMapper, PageFlags, PhysicalAddress, RmmA, RmmArch},
|
||||
paging::{KernelMapper, PageFlags, PhysicalAddress},
|
||||
};
|
||||
|
||||
use crate::arch::cpuid::cpuid;
|
||||
@@ -34,9 +34,6 @@ pub struct LocalApic {
|
||||
pub x2: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct NoFreqInfo;
|
||||
|
||||
static BSP_APIC_ID: AtomicU32 = AtomicU32::new(u32::max_value());
|
||||
|
||||
#[no_mangle]
|
||||
@@ -59,7 +56,10 @@ impl LocalApic {
|
||||
#[cfg(target_arch = "x86")]
|
||||
let virtaddr = rmm::VirtualAddress::new(crate::LAPIC_OFFSET);
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
let virtaddr = RmmA::phys_to_virt(physaddr);
|
||||
let virtaddr = {
|
||||
use rmm::Arch;
|
||||
crate::memory::RmmA::phys_to_virt(physaddr)
|
||||
};
|
||||
|
||||
self.address = virtaddr.data();
|
||||
self.x2 = cpuid()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::syscall::io::{Io, Pio};
|
||||
|
||||
pub static mut CHAN0: Pio<u8> = Pio::new(0x40);
|
||||
pub static mut CHAN1: Pio<u8> = Pio::new(0x41);
|
||||
pub static mut CHAN2: Pio<u8> = Pio::new(0x42);
|
||||
//pub static mut CHAN1: Pio<u8> = Pio::new(0x41);
|
||||
//pub static mut CHAN2: Pio<u8> = Pio::new(0x42);
|
||||
pub static mut COMMAND: Pio<u8> = Pio::new(0x43);
|
||||
|
||||
const SELECT_CHAN0: u8 = 0b00 << 6;
|
||||
|
||||
@@ -5,8 +5,8 @@ use spin::Mutex;
|
||||
|
||||
pub static COM1: Mutex<SerialPort<Pio<u8>>> = Mutex::new(SerialPort::<Pio<u8>>::new(0x3F8));
|
||||
pub static COM2: Mutex<SerialPort<Pio<u8>>> = Mutex::new(SerialPort::<Pio<u8>>::new(0x2F8));
|
||||
pub static COM3: Mutex<SerialPort<Pio<u8>>> = Mutex::new(SerialPort::<Pio<u8>>::new(0x3E8));
|
||||
pub static COM4: Mutex<SerialPort<Pio<u8>>> = Mutex::new(SerialPort::<Pio<u8>>::new(0x2E8));
|
||||
// pub static COM3: Mutex<SerialPort<Pio<u8>>> = Mutex::new(SerialPort::<Pio<u8>>::new(0x3E8));
|
||||
// pub static COM4: Mutex<SerialPort<Pio<u8>>> = Mutex::new(SerialPort::<Pio<u8>>::new(0x2E8));
|
||||
|
||||
#[cfg(feature = "lpss_debug")]
|
||||
pub static LPSS: Mutex<Option<&'static mut SerialPort<Mmio<u32>>>> = Mutex::new(None);
|
||||
|
||||
+15
-50
@@ -1,7 +1,6 @@
|
||||
use core::{
|
||||
cell::SyncUnsafeCell,
|
||||
mem,
|
||||
num::NonZeroU8,
|
||||
sync::atomic::{AtomicU32, Ordering},
|
||||
};
|
||||
|
||||
@@ -15,7 +14,7 @@ use x86::{
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::interrupt::irq::{__generic_interrupts_end, __generic_interrupts_start};
|
||||
use crate::{cpu_set::LogicalCpuId, interrupt::*, ipi::IpiKind, paging::PAGE_SIZE};
|
||||
use crate::{cpu_set::LogicalCpuId, interrupt::*, ipi::IpiKind};
|
||||
|
||||
use spin::RwLock;
|
||||
|
||||
@@ -36,30 +35,6 @@ impl Idt {
|
||||
reservations: new_idt_reservations(),
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn is_reserved(&self, index: u8) -> bool {
|
||||
let byte_index = index / 32;
|
||||
let bit = index % 32;
|
||||
|
||||
{ &self.reservations[usize::from(byte_index)] }.load(Ordering::Acquire) & (1 << bit) != 0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_reserved(&self, index: u8, reserved: bool) {
|
||||
let byte_index = index / 32;
|
||||
let bit = index % 32;
|
||||
|
||||
{ &self.reservations[usize::from(byte_index)] }
|
||||
.fetch_or(u32::from(reserved) << bit, Ordering::AcqRel);
|
||||
}
|
||||
#[inline]
|
||||
pub fn is_reserved_mut(&mut self, index: u8) -> bool {
|
||||
let byte_index = index / 32;
|
||||
let bit = index % 32;
|
||||
|
||||
*{ &mut self.reservations[usize::from(byte_index)] }.get_mut() & (1 << bit) != 0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_reserved_mut(&mut self, index: u8, reserved: bool) {
|
||||
let byte_index = index / 32;
|
||||
@@ -111,17 +86,6 @@ pub fn set_reserved(cpu_id: LogicalCpuId, index: u8, reserved: bool) {
|
||||
.fetch_or(u32::from(reserved) << bit, Ordering::AcqRel);
|
||||
}
|
||||
|
||||
pub fn allocate_interrupt() -> Option<NonZeroU8> {
|
||||
let cpu_id = crate::cpu_id();
|
||||
for number in 50..=254 {
|
||||
if !is_reserved(cpu_id, number) {
|
||||
set_reserved(cpu_id, number, true);
|
||||
return Some(unsafe { NonZeroU8::new_unchecked(number) });
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn available_irqs_iter(cpu_id: LogicalCpuId) -> impl Iterator<Item = u8> + 'static {
|
||||
(32..=254).filter(move |&index| !is_reserved(cpu_id, index))
|
||||
}
|
||||
@@ -229,22 +193,23 @@ pub unsafe fn init_generic(cpu_id: LogicalCpuId, idt: &mut Idt) {
|
||||
// Note that each CPU has its own "backup interrupt stack".
|
||||
let index = 1_u8;
|
||||
|
||||
// Allocate 64 KiB of stack space for the backup stack.
|
||||
const BACKUP_STACK_SIZE: usize = PAGE_SIZE << 4;
|
||||
let frames = crate::memory::allocate_p2frame(4)
|
||||
.expect("failed to allocate pages for backup interrupt stack");
|
||||
|
||||
use crate::paging::{RmmA, RmmArch};
|
||||
|
||||
// Physical pages are mapped linearly. So is the linearly mapped virtual memory.
|
||||
let base_address = RmmA::phys_to_virt(frames.start_address());
|
||||
|
||||
// Stack always grows downwards.
|
||||
let address = base_address.data() + BACKUP_STACK_SIZE;
|
||||
|
||||
// Put them in the 1st entry of the IST.
|
||||
#[cfg(target_arch = "x86_64")] // TODO: x86
|
||||
{
|
||||
use crate::paging::PAGE_SIZE;
|
||||
// Allocate 64 KiB of stack space for the backup stack.
|
||||
const BACKUP_STACK_SIZE: usize = PAGE_SIZE << 4;
|
||||
let frames = crate::memory::allocate_p2frame(4)
|
||||
.expect("failed to allocate pages for backup interrupt stack");
|
||||
|
||||
use crate::paging::{RmmA, RmmArch};
|
||||
|
||||
// Physical pages are mapped linearly. So is the linearly mapped virtual memory.
|
||||
let base_address = RmmA::phys_to_virt(frames.start_address());
|
||||
|
||||
// Stack always grows downwards.
|
||||
let address = base_address.data() + BACKUP_STACK_SIZE;
|
||||
|
||||
(*crate::gdt::pcr()).tss.ist[usize::from(index - 1)] = address as u64;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,12 +16,6 @@ pub unsafe fn disable() {
|
||||
core::arch::asm!("cli", options(nomem, nostack));
|
||||
}
|
||||
|
||||
/// Set interrupts
|
||||
#[inline(always)]
|
||||
pub unsafe fn enable() {
|
||||
core::arch::asm!("sti", options(nomem, nostack));
|
||||
}
|
||||
|
||||
/// Set interrupts and halt
|
||||
/// This will atomically wait for the next interrupt
|
||||
/// Performing enable followed by halt is not guaranteed to be atomic, use this instead!
|
||||
|
||||
@@ -1,19 +1,7 @@
|
||||
use alloc::sync::Arc;
|
||||
use core::{
|
||||
arch::asm,
|
||||
mem,
|
||||
mem::offset_of,
|
||||
ptr,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
use core::{arch::asm, mem, mem::offset_of, ptr, sync::atomic::AtomicBool};
|
||||
use spin::Once;
|
||||
|
||||
use crate::{
|
||||
device::cpu::registers::{control_regs, tlb},
|
||||
paging::{RmmA, RmmArch, TableKind},
|
||||
percpu::PercpuBlock,
|
||||
syscall::FloatRegisters,
|
||||
};
|
||||
use crate::{percpu::PercpuBlock, syscall::FloatRegisters};
|
||||
|
||||
/// This must be used by the kernel to ensure that context switches are done atomically
|
||||
/// Compare and exchange this to true when beginning a context switch on any CPU
|
||||
@@ -86,19 +74,12 @@ impl Context {
|
||||
self.lr = address;
|
||||
}
|
||||
|
||||
pub fn set_fp(&mut self, address: usize) {
|
||||
self.fp = address;
|
||||
}
|
||||
|
||||
pub fn set_context_handle(&mut self) {
|
||||
let address = self as *const _ as usize;
|
||||
self.tpidrro_el0 = address;
|
||||
}
|
||||
|
||||
pub fn get_context_handle(&mut self) -> usize {
|
||||
self.tpidrro_el0
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn dump(&self) {
|
||||
println!("elr_el1: 0x{:016x}", self.elr_el1);
|
||||
println!("sp_el0: 0x{:016x}", self.sp_el0);
|
||||
@@ -131,7 +112,7 @@ impl super::Context {
|
||||
unsafe { ptr::read(self.kfx.as_ptr() as *const FloatRegisters) }
|
||||
}
|
||||
|
||||
pub fn set_fx_regs(&mut self, mut new: FloatRegisters) {
|
||||
pub fn set_fx_regs(&mut self, new: FloatRegisters) {
|
||||
if !self.arch.fx_loadable {
|
||||
panic!("TODO: make set_fx_regs always work");
|
||||
}
|
||||
@@ -162,7 +143,7 @@ pub unsafe fn empty_cr3() -> rmm::PhysicalAddress {
|
||||
|
||||
#[target_feature(enable = "neon")]
|
||||
#[naked]
|
||||
unsafe fn fp_save(float_regs: &mut FloatRegisters) {
|
||||
unsafe extern "C" fn fp_save(float_regs: &mut FloatRegisters) {
|
||||
asm!(
|
||||
"stp q0, q1, [x0, {0} + 16 * 0]",
|
||||
"stp q2, q3, [x0, {0} + 16 * 2]",
|
||||
@@ -195,7 +176,7 @@ unsafe fn fp_save(float_regs: &mut FloatRegisters) {
|
||||
|
||||
#[target_feature(enable = "neon")]
|
||||
#[naked]
|
||||
unsafe fn fp_load(float_regs: &mut FloatRegisters) {
|
||||
unsafe extern "C" fn fp_load(float_regs: &mut FloatRegisters) {
|
||||
asm!(
|
||||
"ldp q0, q1, [x0, {0} + 16 * 0]",
|
||||
"ldp q2, q3, [x0, {0} + 16 * 2]",
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
use core::{mem, sync::atomic::AtomicBool};
|
||||
|
||||
use alloc::sync::Arc;
|
||||
use core::sync::atomic::AtomicBool;
|
||||
|
||||
use crate::{
|
||||
gdt::{pcr, GDT_USER_FS, GDT_USER_GS},
|
||||
paging::{RmmA, RmmArch, TableKind},
|
||||
percpu::PercpuBlock,
|
||||
syscall::FloatRegisters,
|
||||
};
|
||||
|
||||
@@ -6,7 +6,6 @@ use core::{
|
||||
num::NonZeroUsize,
|
||||
sync::atomic::{AtomicU32, Ordering},
|
||||
};
|
||||
use hashbrown::HashMap;
|
||||
use rmm::{Arch as _, PageFlush};
|
||||
use spin::{RwLock, RwLockReadGuard, RwLockUpgradableGuard, RwLockWriteGuard};
|
||||
use syscall::{error::*, flag::MapFlags, GrantFlags, MunmapFlags};
|
||||
@@ -728,9 +727,6 @@ pub struct UserGrants {
|
||||
holes: BTreeMap<VirtualAddress, usize>,
|
||||
// TODO: Would an additional map ordered by (size,start) to allow for O(log n) allocations be
|
||||
// beneficial?
|
||||
|
||||
//TODO: technically VirtualAddress is from a scheme's context!
|
||||
pub funmap: HashMap<Page, (usize, Page)>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
@@ -836,7 +832,6 @@ impl UserGrants {
|
||||
inner: BTreeMap::new(),
|
||||
holes: core::iter::once((VirtualAddress::new(0), crate::USER_END_OFFSET))
|
||||
.collect::<BTreeMap<_, _>>(),
|
||||
funmap: HashMap::new(),
|
||||
}
|
||||
}
|
||||
/// Returns the grant, if any, which occupies the specified page
|
||||
|
||||
@@ -11,6 +11,7 @@ pub static DEBUG_DISPLAY: Mutex<Option<DebugDisplay>> = Mutex::new(None);
|
||||
|
||||
pub static FRAMEBUFFER: Mutex<(usize, usize, usize)> = Mutex::new((0, 0, 0));
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn init(env: &[u8]) {
|
||||
println!("Starting graphical debug");
|
||||
|
||||
@@ -66,12 +67,14 @@ pub fn init(env: &[u8]) {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn init_heap() {
|
||||
if let Some(debug_display) = &mut *DEBUG_DISPLAY.lock() {
|
||||
debug_display.display.heap_init();
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn fini() {
|
||||
DEBUG_DISPLAY.lock().take();
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#![allow(unused)]
|
||||
|
||||
use core::{
|
||||
convert::TryInto,
|
||||
ptr::{addr_of, addr_of_mut},
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#![allow(unused)]
|
||||
|
||||
//! ELF executables
|
||||
|
||||
use alloc::string::String;
|
||||
|
||||
+1
-1
@@ -243,7 +243,7 @@ fn kmain(cpu_count: u32, bootstrap: Bootstrap) -> ! {
|
||||
}
|
||||
|
||||
/// This is the main kernel entry point for secondary CPUs
|
||||
#[allow(unreachable_code, unused_variables)]
|
||||
#[allow(unreachable_code, unused_variables, dead_code)]
|
||||
fn kmain_ap(cpu_id: crate::cpu_set::LogicalCpuId) -> ! {
|
||||
#[cfg(feature = "profiling")]
|
||||
profiling::maybe_run_profiling_helper_forever(cpu_id);
|
||||
|
||||
@@ -47,6 +47,7 @@ const NULL: AtomicPtr<PercpuBlock> = AtomicPtr::new(core::ptr::null_mut());
|
||||
static ALL_PERCPU_BLOCKS: [AtomicPtr<PercpuBlock>; MAX_CPU_COUNT as usize] =
|
||||
[NULL; MAX_CPU_COUNT as usize];
|
||||
|
||||
#[allow(unused)]
|
||||
pub unsafe fn init_tlb_shootdown(id: LogicalCpuId, block: *mut PercpuBlock) {
|
||||
ALL_PERCPU_BLOCKS[id.get() as usize].store(block, Ordering::Release)
|
||||
}
|
||||
|
||||
@@ -284,6 +284,7 @@ pub fn breakpoint_callback(
|
||||
|
||||
/// Obtain the next breakpoint flags for the current process. This is used for
|
||||
/// detecting whether or not the tracer decided to use sysemu mode.
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
pub fn next_breakpoint() -> Option<PtraceFlags> {
|
||||
let context_lock = context::current();
|
||||
let context = context_lock.read();
|
||||
|
||||
+3
-3
@@ -6,12 +6,12 @@ use spin::{Once, RwLock};
|
||||
use super::{CallerCtx, KernelScheme, OpenResult};
|
||||
use crate::{
|
||||
dtb::DTB_BINARY,
|
||||
scheme::{InternalFlags, SchemeId},
|
||||
scheme::InternalFlags,
|
||||
syscall::{
|
||||
data::Stat,
|
||||
error::*,
|
||||
flag::{MODE_FILE, O_STAT, SEEK_CUR, SEEK_END, SEEK_SET},
|
||||
usercopy::{UserSliceRo, UserSliceWo},
|
||||
flag::{MODE_FILE, O_STAT},
|
||||
usercopy::UserSliceWo,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -5,8 +5,9 @@ use core::{
|
||||
};
|
||||
use spin::RwLock;
|
||||
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
use crate::arch::interrupt;
|
||||
use crate::{
|
||||
arch::interrupt,
|
||||
context::file::InternalFlags,
|
||||
syscall::{
|
||||
data::Stat,
|
||||
|
||||
+1
-1
@@ -688,7 +688,7 @@ impl UserInner {
|
||||
dst.copy_exactly(&self.translate_sqe_to_packet(&sqe)?)?;
|
||||
bytes_read += size_of::<Packet>();
|
||||
}
|
||||
Err(_error) if bytes_read > 0 => return Ok(bytes_read),
|
||||
Err(_) if bytes_read > 0 => return Ok(bytes_read),
|
||||
Err(Error { errno: EAGAIN }) if self.unmounting.load(Ordering::SeqCst) => {
|
||||
return Ok(bytes_read)
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ fn enforce_root() -> Result<()> {
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
pub fn iopl(level: usize) -> Result<usize> {
|
||||
pub fn iopl(_level: usize) -> Result<usize> {
|
||||
Err(Error::new(syscall::error::ENOSYS))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user