ableos/ableos/src/arch/uefi_86/mod.rs

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;
}
}
}
}