feat(adapter): higher-half kernel (linked at PHYS_OFFSET, boot trampoline, no low mappings), fix SBI ecall clobbers
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
use crate::board;
|
||||
|
||||
const PLIC_PRIORITY: usize = board::PLIC_BASE;
|
||||
const PLIC_S_ENABLE: usize = board::PLIC_BASE + 0x2080;
|
||||
const PLIC_S_THRESHOLD: usize = board::PLIC_BASE + 0x201000;
|
||||
const PLIC_S_CLAIM: usize = board::PLIC_BASE + 0x201004;
|
||||
const PLIC: usize = crate::mmu::phys_to_virt(board::PLIC_BASE);
|
||||
const PLIC_PRIORITY: usize = PLIC;
|
||||
const PLIC_S_ENABLE: usize = PLIC + 0x2080;
|
||||
const PLIC_S_THRESHOLD: usize = PLIC + 0x201000;
|
||||
const PLIC_S_CLAIM: usize = PLIC + 0x201004;
|
||||
|
||||
pub struct Plic;
|
||||
|
||||
|
||||
@@ -7,10 +7,13 @@ pub fn read_time() -> u64 {
|
||||
}
|
||||
|
||||
fn sbi_set_timer(stime: u64) {
|
||||
// SBI returns an error code in a0 and a value in a1; both are
|
||||
// clobbered even though we ignore them.
|
||||
unsafe {
|
||||
core::arch::asm!(
|
||||
"ecall",
|
||||
in("a0") stime,
|
||||
inlateout("a0") stime => _,
|
||||
lateout("a1") _,
|
||||
in("a6") 0usize,
|
||||
in("a7") 0x54494D45usize,
|
||||
);
|
||||
|
||||
@@ -7,7 +7,7 @@ pub struct Uart {
|
||||
impl Uart {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
base: board::UART_BASE,
|
||||
base: crate::mmu::phys_to_virt(board::UART_BASE),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::mmu::{phys_to_virt, virt_to_phys};
|
||||
use hw_virtio::block::{self, DmaAddrs};
|
||||
use hw_virtio::mmio::{self, DirectMmio};
|
||||
use hw_virtio::queue::{QUEUE_SIZE, QueueAddrs, VirtioQueue};
|
||||
@@ -27,27 +28,38 @@ pub struct VirtioBlk {
|
||||
|
||||
impl VirtioBlk {
|
||||
pub fn probe() -> Option<Self> {
|
||||
let mmio = mmio::scan_for_device(mmio::DEVICE_ID_BLOCK)?;
|
||||
let mmio = mmio::scan_for_device(phys_to_virt(mmio::MMIO_FIRST), mmio::DEVICE_ID_BLOCK)?;
|
||||
|
||||
let vq_phys = core::ptr::addr_of!(VQUEUE) as usize;
|
||||
mmio::init_legacy_device(&mmio, vq_phys, QUEUE_SIZE as u32);
|
||||
// The device sees physical addresses; the CPU uses kernel ones.
|
||||
let vq_va = core::ptr::addr_of!(VQUEUE) as usize;
|
||||
mmio::init_legacy_device(&mmio, virt_to_phys(vq_va), QUEUE_SIZE as u32);
|
||||
|
||||
let queue = VirtioQueue::new(QueueAddrs::from_base(vq_phys));
|
||||
let queue = VirtioQueue::new(QueueAddrs::from_base(vq_va));
|
||||
|
||||
let pair = |va: usize| {
|
||||
(
|
||||
PhysicalAddress::from_raw(virt_to_phys(va)),
|
||||
VirtualAddress::from_raw(va),
|
||||
)
|
||||
};
|
||||
let (header_pa, header_va) = pair(core::ptr::addr_of_mut!(REQ_HEADER) as usize);
|
||||
let (status_pa, status_va) = pair(core::ptr::addr_of_mut!(REQ_STATUS) as usize);
|
||||
let (data_pa, data_va) = pair(core::ptr::addr_of_mut!(SECTOR_BUF) as usize);
|
||||
let dma = DmaAddrs {
|
||||
header_pa: PhysicalAddress::from_raw(core::ptr::addr_of!(REQ_HEADER) as usize),
|
||||
header_va: VirtualAddress::from_raw(core::ptr::addr_of_mut!(REQ_HEADER) as usize),
|
||||
status_pa: PhysicalAddress::from_raw(core::ptr::addr_of!(REQ_STATUS) as usize),
|
||||
status_va: VirtualAddress::from_raw(core::ptr::addr_of_mut!(REQ_STATUS) as usize),
|
||||
data_pa: PhysicalAddress::from_raw(core::ptr::addr_of!(SECTOR_BUF) as usize),
|
||||
data_va: VirtualAddress::from_raw(core::ptr::addr_of_mut!(SECTOR_BUF) as usize),
|
||||
header_pa,
|
||||
header_va,
|
||||
status_pa,
|
||||
status_va,
|
||||
data_pa,
|
||||
data_va,
|
||||
};
|
||||
|
||||
Some(Self { mmio, queue, dma })
|
||||
}
|
||||
|
||||
/// Physical address of the device's MMIO window.
|
||||
pub fn base(&self) -> usize {
|
||||
self.mmio.base()
|
||||
virt_to_phys(self.mmio.base())
|
||||
}
|
||||
|
||||
pub fn read_sector(&mut self, sector: u32, buf: &mut [u8; SECTOR_SIZE]) -> bool {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::mmu::{phys_to_virt, virt_to_phys};
|
||||
use hw_virtio::gpu::{self, GpuDmaAddrs};
|
||||
use hw_virtio::mmio::{self, DirectMmio};
|
||||
use hw_virtio::queue::{QUEUE_SIZE, QueueAddrs, VirtioQueue};
|
||||
@@ -10,12 +11,13 @@ pub struct VirtioGpu {
|
||||
|
||||
impl VirtioGpu {
|
||||
pub fn probe() -> Option<Self> {
|
||||
let mmio = mmio::scan_for_device(mmio::DEVICE_ID_GPU)?;
|
||||
let mmio = mmio::scan_for_device(phys_to_virt(mmio::MMIO_FIRST), mmio::DEVICE_ID_GPU)?;
|
||||
Some(Self { mmio })
|
||||
}
|
||||
|
||||
/// Physical address of the device's MMIO window.
|
||||
pub fn base(&self) -> usize {
|
||||
self.mmio.base()
|
||||
virt_to_phys(self.mmio.base())
|
||||
}
|
||||
|
||||
pub fn mmio(&self) -> &DirectMmio {
|
||||
@@ -34,10 +36,10 @@ impl VirtioGpu {
|
||||
width: Dimension,
|
||||
height: Dimension,
|
||||
) -> bool {
|
||||
let queue = VirtioQueue::new(QueueAddrs::from_base(vq_phys));
|
||||
let queue = VirtioQueue::new(QueueAddrs::from_base(phys_to_virt(vq_phys)));
|
||||
let dma = GpuDmaAddrs {
|
||||
cmd_pa: PhysicalAddress::from_raw(cmd_phys),
|
||||
cmd_va: VirtualAddress::from_raw(cmd_phys),
|
||||
cmd_va: VirtualAddress::from_raw(phys_to_virt(cmd_phys)),
|
||||
resp_pa: PhysicalAddress::from_raw(cmd_phys + 512),
|
||||
};
|
||||
let ok1 = gpu::create_2d(&self.mmio, &queue, &dma, 1, width, height);
|
||||
|
||||
Reference in New Issue
Block a user