Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions crates/display-server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ fn handle_incoming(_msg: ulib::sys::Message, _buf: &[u8], resp_socket: FileDesc)
// TODO: proper listen + connect sockets
// (this just broadcasts a response to all listeners and hopes that there aren't race conditions)

let buffer = init_buffer();
let buffer = init_buffer(640, 480);

let fds = [buffer.fd, buffer.present_sem_fd];
let handle = unsafe { proto::BufferHandle::new(buffer.mapped, &fds) };
Expand All @@ -55,10 +55,9 @@ fn handle_incoming(_msg: ulib::sys::Message, _buf: &[u8], resp_socket: FileDesc)
handle
}

fn init_buffer() -> BufferInfo {
fn init_buffer(width: usize, height: usize) -> BufferInfo {
println!("init_buffer");
let screen_size = (640, 480);
let vmem_size = screen_size.0 * screen_size.1 * 4;
let vmem_size = width * height * 4;

let header_size = size_of::<proto::BufferHeader>().next_multiple_of(4096);
let total_size = header_size + vmem_size;
Expand Down Expand Up @@ -87,9 +86,9 @@ fn init_buffer() -> BufferInfo {
server_to_client_queue: proto::EventQueue::new(),

video_meta: proto::VideoMeta {
width: screen_size.0 as u16,
height: screen_size.1 as u16,
row_stride: (screen_size.0 as u16 * 4),
width: width as u16,
height: height as u16,
row_stride: (width as u16 * 4),
bytes_per_pixel: 4,
bit_layout: 0,
present_ts: 0,
Expand Down
1 change: 1 addition & 0 deletions crates/kernel/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.pcap
2 changes: 1 addition & 1 deletion crates/kernel/examples/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extern crate kernel;

use kernel::*;

fn test_irq_handler(_ctx: &mut event::context::Context) {
fn test_irq_handler(_ctx: &mut event::context::Context, _irq: usize) {
//Reset the timer to ping again
device::system_timer::ARM_GENERIC_TIMERS.with_current(|timer| {
timer.reset_timer();
Expand Down
9 changes: 9 additions & 0 deletions crates/kernel/examples/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ async fn main() {
let user_region = user_region as *mut u8;

let ttbr0 = process.get_ttbr0();
println!("init ttbr0={:#x}", ttbr0);

let callback = || {
println!("User ptr: {:p}", user_region);
println!(
Expand All @@ -65,6 +67,13 @@ async fn main() {
let end = sync::get_time();

println!("Done copying user data, took {:4}µs", end - start);

unsafe {
crate::arch::memory::flush_range(
user_region.addr(),
user_region.addr() + INIT_CODE.len(),
)
};
};
unsafe { with_user_vmem(ttbr0, callback) };

Expand Down
8 changes: 8 additions & 0 deletions crates/kernel/scripts/run-usb-passthrough.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash

set -ex
QEMU_DISPLAY=${QEMU_DISPLAY-"default"} \
QEMU_DEVICES="-usb -device usb-host,hostbus=3,hostport=4.3" "$(dirname "$0")/run.sh"
#QEMU_DEVICES="-usb -device usb-host,vendorid=0x1532,productid=0x025e" "$(dirname "$0")/run.sh"
#QEMU_DEVICES="-usb -device usb-host,vendorid=0x2109,productid=0x2817" "$(dirname "$0")/run.sh"

3 changes: 2 additions & 1 deletion crates/kernel/scripts/run-usb.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env bash

set -ex
QEMU_DISPLAY="default" QEMU_DEVICES="-usb -device usb-kbd -device usb-mouse -device usb-net,netdev=net0 -netdev user,id=net0,hostfwd=tcp::2222-:22 -object filter-dump,id=f1,netdev=net0,file=net0.pcap" "$(dirname "$0")/run.sh"
QEMU_DISPLAY=${QEMU_DISPLAY-"default"} QEMU_DEVICES="-device usb-hub,id=hub1 -device usb-kbd -device usb-mouse" "$(dirname "$0")/run.sh"
# QEMU_DISPLAY=${QEMU_DISPLAY-"default"} QEMU_DEVICES="-usb -device usb-kbd -device usb-mouse,pcap=usb-mouse.pcap -device usb-net,netdev=net0 -netdev user,id=net0,hostfwd=tcp::2222-:22 -object filter-dump,id=f1,netdev=net0,file=net0.pcap" "$(dirname "$0")/run.sh"
45 changes: 32 additions & 13 deletions crates/kernel/src/arch/aarch64/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,20 @@ kernel_entry_alt:

b kernel_entry_rust_alt

// TODO: somehow this sometimes gets triggered twice on core 0?
// Taking exception 1 [Undefined Instruction] on CPU 0
// ...from EL1 to EL1
// ...with ESR 0x0/0x2000000
// ...with ELR 0x8005c
// ...to EL1 PC 0x80a00 PSTATE 0x3c5
drop_to_el1:
// Init core ids? TODO: probably unneeded
mrs x5, midr_el1
mrs x6, mpidr_el1
msr vpidr_el2, x5
msr vmpidr_el2, x6

// Init timers on core zero???
mrs x5, cnthctl_el2
orr x5, x5, #0x3
msr cnthctl_el2, x5
msr cntvoff_el2, xzr

mov x5, #(1 << 31)
// orr x5, x5, #0x38
ldr x5, ={HCR_EL2}
msr hcr_el2, x5

// Enable FPU
Expand All @@ -114,7 +118,7 @@ drop_to_el1:
ldr x5, ={MAIR_EL1}
msr MAIR_EL1, x5

mov x5, #0b0101
mov x5, #0x3c5 // EL1_SP1, DAIF masked
msr SPSR_EL2, x5

// Enable FPU
Expand Down Expand Up @@ -163,6 +167,7 @@ switch_kernel_vmem:
mrs x3, TTBR1_EL1
msr TTBR0_EL1, x3

isb
dsb sy
tlbi vmalle1is
dsb sy
Expand All @@ -173,6 +178,7 @@ switch_kernel_vmem:

msr TTBR0_EL1, x4

isb
dsb sy
tlbi vmalle1is
dsb sy
Expand All @@ -187,6 +193,7 @@ switch_kernel_vmem_in_phys:
msr TCR_EL1, x1
msr TTBR1_EL1, x0

isb
dsb sy
tlbi vmalle1is
dsb sy
Expand All @@ -198,6 +205,7 @@ switch_kernel_vmem_in_phys:
switch_user_tcr_el1:
msr TCR_EL1, x0

isb
dsb sy
tlbi vmalle1is
dsb sy
Expand All @@ -207,17 +215,28 @@ switch_user_tcr_el1:
STACK_SIZE_LOG2 = const STACK_SIZE_LOG2,
TCR_EL1 = const INIT_TCR_EL1,
TRANSLATION_ENTRY = const INIT_TRANSLATION,
HCR_EL2 = const (
(1 << 31) | // 64 bit mode in EL1
// orr x5, x5, #0x38 (???)
0
),
SCTLR_EL1 = const (
(1 << 11) | // enable instruction caching
(1 << 29) | // ???
(1 << 28) |
(1 << 23) |
(1 << 22) |
(1 << 20) |
(1 << 12) | // enable instruction caching
(1 << 11) | // exceptions as sync point?
(1 << 4) | // enable EL0 stack pointer alignment
(1 << 3) | // enable EL1 stack pointer alignment
(1 << 2) | // enable data caching
(1 << 1) | // enable alignment faults
1 // enable EL1&0 virtual memory
),
MAIR_EL1 = const (
(0b01000100 << 16) | // Entry 2: normal noncacheable memory
(0b00000000 << 8) | // Entry 1: device memory
(0b11111111 << 0) // Entry 0: normal memory
(0x44 << 16) | // Entry 2: normal noncacheable memory
(0x00 << 8) | // Entry 1: device memory
(0xFF << 0) // Entry 0: normal memory
)
);
65 changes: 39 additions & 26 deletions crates/kernel/src/arch/aarch64/memory/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,42 +97,55 @@ pub unsafe fn clean_physical_buffer_for_device(va: *mut (), bytes: usize) {
for ptr in va..(va + bytes) {
// clean each byte
// TODO: only invoke the cleaning once per cache line by using the cache registers to find line width
unsafe {
asm! {
"dc cvac, {ptr}",
ptr = in(reg) ptr,
options(readonly, nostack, preserves_flags)
}
}
unsafe { asm!("dc cvac, {ptr}",ptr = in(reg) ptr,options(nostack, preserves_flags)) };
}
// enforce memory barrier between this and subsequent memory operations
// must be inserted at some point before the device access, and this is a reasonable point
unsafe {
asm! {
"dmb sy",
options(readonly, nostack, preserves_flags)
}
}
unsafe { asm!("dmb sy", options(nostack, preserves_flags)) };
}
pub unsafe fn invalidate_physical_buffer_for_device(va: *mut (), bytes: usize) {
// enforce memory barrier between this and prior memory operations
// probably needs to be inserted (?) at some point after the device work completes, and this is a reasonable point
unsafe {
asm! {
"dmb sy",
options(readonly, nostack, preserves_flags)
}
}
unsafe { asm!("dmb sy", options(nostack, preserves_flags)) };
let va = va.addr();
for ptr in va..(va + bytes) {
// invalidate each byte
// TODO: only invoke the invalidating once per cache line by using the cache registers to find line width
unsafe {
asm! {
"dc ivac, {ptr}",
ptr = in(reg) ptr,
options(readonly, nostack, preserves_flags)
}
}
unsafe { asm!("dc ivac, {ptr}",ptr = in(reg) ptr,options(nostack, preserves_flags)) };
}
}

pub unsafe fn flush_range(start: usize, end: usize) {
use core::arch::asm;

// might not be needed
unsafe { asm!("dsb sy", "isb", options(nostack, preserves_flags)) };

let ctr_el0: usize;
unsafe { asm!("mrs {0}, CTR_EL0", out(reg) ctr_el0, options(nomem, nostack, preserves_flags)) };

let d_cacheline = 4 << ((ctr_el0 >> 16) & 0x0F);
let i_cacheline = 4 << ((ctr_el0 >> 0) & 0x0F);

let start_line = (start / d_cacheline) * d_cacheline;
let end_line = end.next_multiple_of(d_cacheline);
for line in (start_line..end_line).step_by(d_cacheline) {
// TODO: figure out what subset of cache flushing is needed here
// unsafe { asm!("dc cvau, {0}", in(reg) line, options(nostack, preserves_flags)) };
unsafe { asm!("dc cvac, {0}", in(reg) line, options(nostack, preserves_flags)) };
unsafe { asm!("dc ivac, {0}", in(reg) line, options(nostack, preserves_flags)) };
}

unsafe { asm!("dsb ish", options(nostack, preserves_flags)) };

let start_line = (start / i_cacheline) * i_cacheline;
let end_line = end.next_multiple_of(i_cacheline);
for line in (start_line..end_line).step_by(i_cacheline) {
unsafe { asm!("ic ivau, {0}", in(reg) line, options(nostack, preserves_flags)) };
}

unsafe { asm!("dsb ish", "isb", options(nostack, preserves_flags)) };

// might not be needed
unsafe { asm!("dsb sy", "isb", options(nostack, preserves_flags)) };
}
Loading
Loading