1
0
mirror of https://github.com/sgmarz/osblog.git synced 2024-11-24 02:16:19 +04:00

Add GPU init

This commit is contained in:
Stephen Marz 2020-05-23 06:23:32 -04:00
parent 37cc8b7fae
commit 5bc745931b
2 changed files with 161 additions and 4 deletions

View File

@ -5,9 +5,11 @@
#![allow(dead_code)] #![allow(dead_code)]
use crate::{page::{zalloc, PAGE_SIZE}, use crate::{page::{zalloc, PAGE_SIZE},
kmem::kmalloc,
virtio, virtio,
virtio::{MmioOffsets, Queue, StatusField, VIRTIO_RING_SIZE}}; virtio::{MmioOffsets, Queue, StatusField, VIRTIO_RING_SIZE, Descriptor}};
use core::{mem::size_of, ptr::null_mut}; use core::{mem::size_of, ptr::null_mut};
use alloc::boxed::Box;
pub const F_VIRGL: u32 = 0; pub const F_VIRGL: u32 = 0;
pub const F_EDID: u32 = 1; pub const F_EDID: u32 = 1;
@ -73,6 +75,14 @@ pub struct Rect {
width: u32, width: u32,
height: u32, height: u32,
} }
impl Rect {
pub fn new(x: u32, y: u32, width: u32, height: u32) -> Self {
Self {
x, y, width, height
}
}
}
#[repr(C)] #[repr(C)]
pub struct DisplayOne { pub struct DisplayOne {
r: Rect, r: Rect,
@ -185,20 +195,29 @@ pub struct UpdateCursor {
padding: u32, padding: u32,
} }
pub struct Pixel {
r: u8,
g: u8,
b: u8,
a: u8,
}
pub struct Device { pub struct Device {
queue: *mut Queue, queue: *mut Queue,
dev: *mut u32, dev: *mut u32,
idx: u16, idx: u16,
ack_used_idx: u16, ack_used_idx: u16,
framebuffer: *mut Pixel,
} }
impl Device { impl Device {
pub const fn new() -> Self { pub const fn new() -> Self {
Self { queue: null_mut(), Self { queue: null_mut(),
dev: null_mut(), dev: null_mut(),
idx: 0, idx: 0,
ack_used_idx: 0, } ack_used_idx: 0,
framebuffer: null_mut(),
}
} }
} }
@ -213,6 +232,141 @@ static mut GPU_DEVICES: [Option<Device>; 8] = [
None, None,
]; ];
pub fn init(gdev: usize) {
if let Some(mut dev) = unsafe { GPU_DEVICES[gdev-1].take() } {
let rq = Box::new(ResourceCreate2d {
hdr: CtrlHeader {
ctrl_type: CtrlType::CmdResourceCreate2d,
flags: 0,
fence_id: 0,
ctx_id: 0,
padding: 0,
},
resource_id: 1,
format: Formats::R8G8B8A8Unorm,
width: 1024,
height: 768,
});
for col in 0..1024 {
for row in 0..768 {
unsafe {
dev.framebuffer.add(col*row).write(Pixel {
r: 255,
g: 155,
b: 55,
a: 255,
});
}
}
}
let buffer = Box::into_raw(rq);
let desc_c2d =
Descriptor { addr: buffer as u64,
len: size_of::<ResourceCreate2d>() as u32,
flags: 0,
next: 0, };
let rq = Box::new(AttachBacking {
hdr: CtrlHeader {
ctrl_type: CtrlType::CmdResourceAttachBacking,
flags: 0,
fence_id: 0,
ctx_id: 0,
padding: 0,
},
resource_id: 1,
nr_entries: 1
});
let buffer = Box::into_raw(rq);
let desc_ab =
Descriptor { addr: buffer as u64,
len: size_of::<AttachBacking>() as u32,
flags: 0,
next: 0,
};
let rq = Box::new(SetScanout {
hdr: CtrlHeader {
ctrl_type: CtrlType::CmdSetScanout,
flags: 0,
fence_id: 0,
ctx_id: 0,
padding: 0,
},
r: Rect::new(0, 0, 1024, 768),
scanout_id: 1,
resource_id: 1,
});
let buffer = Box::into_raw(rq);
let desc_scanout =
Descriptor { addr: buffer as u64,
len: size_of::<SetScanout>() as u32,
flags: 0,
next: 0,
};
let rq = Box::new(TransferToHost2d {
hdr: CtrlHeader {
ctrl_type: CtrlType::CmdTransferToHost2d,
flags: 0,
fence_id: 0,
ctx_id: 0,
padding: 0,
},
r: Rect::new(0, 0, 1024, 768),
offset: 0,
resource_id: 1,
padding: 0,
});
let buffer = Box::into_raw(rq);
let desc_t2h =
Descriptor { addr: buffer as u64,
len: size_of::<TransferToHost2d>() as u32,
flags: 0,
next: 0,
};
let rq = Box::new(ResourceFlush {
hdr: CtrlHeader {
ctrl_type: CtrlType::CmdResourceFlush,
flags: 0,
fence_id: 0,
ctx_id: 0,
padding: 0,
},
r: Rect::new(0, 0, 1024, 768),
resource_id: 1,
padding: 0,
});
let buffer = Box::into_raw(rq);
let desc_flush =
Descriptor { addr: buffer as u64,
len: size_of::<ResourceFlush>() as u32,
flags: 0,
next: 0,
};
unsafe {
(*dev.queue).desc[dev.idx as usize] = desc_c2d;
dev.idx = (dev.idx + 1) % VIRTIO_RING_SIZE as u16;
(*dev.queue).desc[dev.idx as usize] = desc_ab;
dev.idx = (dev.idx + 1) % VIRTIO_RING_SIZE as u16;
(*dev.queue).desc[dev.idx as usize] = desc_scanout;
dev.idx = (dev.idx + 1) % VIRTIO_RING_SIZE as u16;
(*dev.queue).desc[dev.idx as usize] = desc_t2h;
dev.idx = (dev.idx + 1) % VIRTIO_RING_SIZE as u16;
(*dev.queue).desc[dev.idx as usize] = desc_flush;
dev.idx = (dev.idx + 1) % VIRTIO_RING_SIZE as u16;
(*dev.queue).avail.idx =
(*dev.queue).avail.idx.wrapping_add(5);
println!("Avail idx {}", (*dev.queue).avail.idx);
dev.dev
.add(MmioOffsets::QueueNotify.scale32())
.write_volatile(0);
GPU_DEVICES[gdev-1].replace(dev);
}
}
}
pub fn setup_gpu_device(ptr: *mut u32) -> bool { pub fn setup_gpu_device(ptr: *mut u32) -> bool {
unsafe { unsafe {
// We can get the index of the device based on its address. // We can get the index of the device based on its address.
@ -303,6 +457,7 @@ pub fn setup_gpu_device(ptr: *mut u32) -> bool {
dev: ptr, dev: ptr,
idx: 0, idx: 0,
ack_used_idx: 0, ack_used_idx: 0,
framebuffer: kmalloc(1024*768*size_of::<Pixel>()) as *mut Pixel,
}; };
GPU_DEVICES[idx] = Some(dev); GPU_DEVICES[idx] = Some(dev);
@ -334,7 +489,7 @@ pub fn handle_interrupt(idx: usize) {
} }
else { else {
println!( println!(
"Invalid block device for interrupt {}", "Invalid GPU device for interrupt {}",
idx + 1 idx + 1
); );
} }

View File

@ -111,6 +111,8 @@ extern "C" fn kinit() {
virtio::probe(); virtio::probe();
// Test the block driver! // Test the block driver!
process::add_kernel_process(test::test); process::add_kernel_process(test::test);
// Get the GPU going
gpu::init(6);
// We schedule the next context switch using a multiplier of 1 // We schedule the next context switch using a multiplier of 1
// Block testing code removed. // Block testing code removed.
trap::schedule_next_context_switch(1); trap::schedule_next_context_switch(1);