129 lines
3.3 KiB
Rust
129 lines
3.3 KiB
Rust
pub mod init;
|
|
|
|
pub fn shutdown() {
|
|
loop {}
|
|
}
|
|
|
|
pub fn sloop() -> ! {
|
|
loop {}
|
|
}
|
|
|
|
use crate::kmain::kernel_main;
|
|
|
|
use uefi::{
|
|
prelude::*,
|
|
proto::console::gop::{GraphicsOutput, PixelFormat},
|
|
};
|
|
use uefi::{proto::console::gop::FrameBuffer, ResultExt};
|
|
|
|
#[entry]
|
|
fn main(_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
|
|
system_table
|
|
.stdout()
|
|
.reset(false)
|
|
.expect_success("Failed to reset output buffer");
|
|
// uefi_services::init(&mut system_table).unwrap_success();
|
|
|
|
{
|
|
// Print out UEFI revision number
|
|
let rev = system_table.uefi_revision();
|
|
let (major, minor) = (rev.major(), rev.minor());
|
|
|
|
info!("UEFI {}.{}", major, minor);
|
|
}
|
|
|
|
info!("Running graphics output protocol test");
|
|
|
|
let stdout = system_table.stdout();
|
|
|
|
stdout.set_cursor_position(0, 10).unwrap_success();
|
|
info!("{:?}", stdout.cursor_position());
|
|
|
|
if let Ok(gop) = system_table
|
|
.boot_services()
|
|
.locate_protocol::<GraphicsOutput>()
|
|
{
|
|
let gop = gop.expect("Warnings encountered while opening GOP");
|
|
let gop = unsafe { &mut *gop.get() };
|
|
let mode = gop
|
|
.modes()
|
|
.map(|mode| mode.expect("Warnings encountered while querying mode"))
|
|
.find(|mode| {
|
|
let info = mode.info();
|
|
info.resolution() == (1440, 900)
|
|
})
|
|
.unwrap();
|
|
|
|
gop.set_mode(&mode)
|
|
.expect_success("Failed to set graphics mode");
|
|
|
|
let mut fb_1 = FrameBuffWrap::new(gop);
|
|
|
|
for x in 0..100 {
|
|
fb_1.draw_pixel(x, 400, [123, 123, 123]);
|
|
}
|
|
} else {
|
|
// No tests can be run.
|
|
warn!("UEFI Graphics Output Protocol is not supported");
|
|
}
|
|
|
|
// exit boot services
|
|
kernel_main();
|
|
}
|
|
|
|
use uefi::proto::console::gop::ModeInfo;
|
|
|
|
pub type PixelWriter = unsafe fn(&mut FrameBuffer, usize, [u8; 3]);
|
|
pub struct FrameBuffWrap<'a> {
|
|
inner: FrameBuffer<'a>,
|
|
|
|
mode_info: ModeInfo,
|
|
|
|
pub resolution: (usize, usize),
|
|
}
|
|
|
|
impl<'b: 'c, 'c> FrameBuffWrap<'c> {
|
|
pub fn new(gop: &'c mut GraphicsOutput<'c>) -> Self {
|
|
let mi = gop.current_mode_info();
|
|
let res = mi.resolution();
|
|
|
|
Self {
|
|
inner: gop.frame_buffer(),
|
|
mode_info: mi,
|
|
resolution: res,
|
|
}
|
|
}
|
|
unsafe fn write_pixel_rgb(&mut self, pixel_base: usize, rgb: [u8; 3]) {
|
|
self.inner.write_value(pixel_base, rgb);
|
|
}
|
|
unsafe fn write_pixel_bgr(&mut self, pixel_base: usize, rgb: [u8; 3]) {
|
|
self.inner.write_value(pixel_base, [rgb[2], rgb[1], rgb[0]]);
|
|
}
|
|
}
|
|
|
|
unsafe impl Sync for FrameBuffWrap<'_> {}
|
|
unsafe impl Send for FrameBuffWrap<'_> {}
|
|
|
|
pub trait GraphicsAPI {
|
|
fn draw_pixel(&mut self, x: usize, y: usize, color: [u8; 3]);
|
|
}
|
|
|
|
impl GraphicsAPI for FrameBuffWrap<'_> {
|
|
fn draw_pixel(&mut self, x: usize, y: usize, color: [u8; 3]) {
|
|
let pixel_base = (y * self.mode_info.stride()) + x;
|
|
|
|
match self.mode_info.pixel_format() {
|
|
PixelFormat::Rgb => unsafe {
|
|
self.write_pixel_rgb(pixel_base, color);
|
|
},
|
|
PixelFormat::Bgr => unsafe {
|
|
self.write_pixel_bgr(pixel_base, color);
|
|
},
|
|
_ => {
|
|
info!("This pixel format is not supported by the drawing demo");
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|