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:
parent
37cc8b7fae
commit
5bc745931b
@ -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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user