Skip to content

Commit

Permalink
Get solution and prepare for framebuffer setup
Browse files Browse the repository at this point in the history
  • Loading branch information
dequeueing committed Jan 11, 2025
1 parent 5dcaacd commit 0d32664
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 17 deletions.
19 changes: 17 additions & 2 deletions kernel/comps/virtio/src/device/gpu/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub(crate) const RESPONSE_SIZE: usize = size_of::<VirtioGpuRespDisplayInfo>();

#[repr(C, packed)]
#[derive(Debug, Clone, Copy, Pod)]
struct VirtioGpuRect {
pub(crate) struct VirtioGpuRect {
/// For any coordinates given 0,0 is top left, larger x moves right, larger y moves down.
x: u32,
/// For any coordinates given 0,0 is top left, larger x moves right, larger y moves down.
Expand All @@ -22,6 +22,16 @@ struct VirtioGpuRect {
height: u32,
}

impl VirtioGpuRect {
pub fn width(&self) -> u32 {
self.width
}

pub fn height(&self) -> u32 {
self.height
}
}

pub const VIRTIO_GPU_MAX_SCANOUTS: usize = 16;

#[repr(C, packed)]
Expand Down Expand Up @@ -87,4 +97,9 @@ impl Default for VirtioGpuRespEdid {
}
}

}
}
impl VirtioGpuRespDisplayInfo {
pub fn get_rect(&self, index: usize) -> Option<VirtioGpuRect> {
Some(self.pmodes[index].r)
}
}
44 changes: 29 additions & 15 deletions kernel/comps/virtio/src/device/gpu/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ use core::hint::spin_loop;

use log::info;
use ostd::{
early_println,
mm::{DmaDirection, DmaStream, DmaStreamSlice, FrameAllocOptions, VmIo},
sync::SpinLock,
trap::TrapFrame,
early_println, mm::{DmaDirection, DmaStream, DmaStreamSlice, FrameAllocOptions, VmIo}, sync::SpinLock, task::scheduler::info, trap::TrapFrame
};

use super::{
Expand Down Expand Up @@ -124,19 +121,18 @@ impl GPUDevice {
// Done: query the display information from the device using the VIRTIO_GPU_CMD_GET_DISPLAY_INFO command,
// and use that information for the initial scanout setup.

// TODO: fetch the EDID information using the VIRTIO_GPU_CMD_GET_EDID command,
// TODO: (Taojie) fetch the EDID information using the VIRTIO_GPU_CMD_GET_EDID command,
// If no information is available or all displays are disabled the driver MAY choose to use a fallback, such as 1024x768 at display 0.

// TODO: query all shared memory regions supported by the device.
// TODO: (Taojie) query all shared memory regions supported by the device.
// If the device supports shared memory, the shmid of a region MUST be one of:
// - VIRTIO_GPU_SHM_ID_UNDEFINED = 0
// - VIRTIO_GPU_SHM_ID_HOST_VISIBLE = 1
// Taojie: I think the above requirement is too complex to implement.

// Taojie: we directly test gpu functionality here rather than writing a user application.
// Test device
// test_device(device);

// Request display info
device.request_display_info();
test_device(Arc::clone(&device));

// Get EDID info
// TODO: check feature flag if EDID is set
Expand Down Expand Up @@ -219,7 +215,13 @@ impl GPUDevice {
Ok(())
}

fn request_display_info(&self) -> Result<(), VirtioDeviceError> {
fn resolution(&self) -> Result<(u32, u32), VirtioDeviceError> {
let display_info = self.request_display_info()?;
let rect = display_info.get_rect(0).unwrap();
Ok((rect.width(), rect.height()))
}

fn request_display_info(&self) -> Result<VirtioGpuRespDisplayInfo, VirtioDeviceError> {
// Prepare request DMA buffer
let req_slice = {
let req_slice = DmaStreamSlice::new(&self.control_request, 0, REQUEST_SIZE);
Expand Down Expand Up @@ -255,19 +257,31 @@ impl GPUDevice {

// Wait for response
while !control_queue.can_pop() {
early_println!("waiting for response...");
// early_println!("waiting for response...");
spin_loop();
}
control_queue.pop_used().expect("Pop used failed");

resp_slice.sync().unwrap();
let resp: VirtioGpuRespDisplayInfo = resp_slice.read_val(0).unwrap();
early_println!("display info from virt_gpu device: {:?}", resp);
// TODO: use the edid info to setup the scanout
// early_println!("display info from virt_gpu device: {:?}", resp);
Ok(resp)
}

pub fn setup_framebuffer(&self) -> Result<(), VirtioDeviceError> {
// get display info
let display_info = self.request_display_info()?;
let rect = display_info.get_rect(0).unwrap();

// create resource 2d

Ok(())
}
}

/// Test the functionality of gpu device and driver.
fn test_device(device: Arc<GPUDevice>) {
unimplemented!()
let (width, height) = device.resolution().expect("failed to get resolution");
early_println!("resolution: {}x{}", width, height);
device.setup_framebuffer().expect("failed to setup framebuffer");
}

0 comments on commit 0d32664

Please sign in to comment.