diff --git a/Makefile b/Makefile index d95ae301f..230ff1b26 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ .PHONY: love default all clean install iso run runs test apps doc kernel boot refresh -.SUFFIXED: .wasm +.SUFFIXES: .wasm MNT = ./mnt/ MISC = ./misc/ @@ -39,6 +39,10 @@ default: $(TARGETS) all: $(ALL_TARGETS) clean: + (cd system; cargo clean) + (cd apps; cargo clean) + (cd boot; cargo clean) + (cd tools; cargo clean) -rm -rf system/target apps/target boot/target tools/target refresh: clean @@ -57,7 +61,6 @@ run: $(QEMU_X64) -machine q35 -cpu SandyBridge -smp 4,cores=2,threads=2 \ -bios $(OVMF_X64) \ -rtc base=localtime,clock=host \ --vga virtio \ -device virtio-net-pci \ -device nec-usb-xhci,id=xhci \ -device intel-hda -device hda-duplex \ diff --git a/README.md b/README.md index 2c7ce7ed0..76fff0411 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # MEG-OS -***Note: It is currently not possible to build with the latest nightly version.*** +***NOTE: IT IS CURRENTLY NOT POSSIBLE TO BUILD WITH THE LATEST NIGHTLY VERSION.*** ![GitHub](https://img.shields.io/github/license/neri/maystorm) ![GitHub top language](https://img.shields.io/github/languages/top/neri/maystorm) diff --git a/apps/life/src/main.rs b/apps/life/src/main.rs index e5515703b..591ecc56f 100644 --- a/apps/life/src/main.rs +++ b/apps/life/src/main.rs @@ -1,7 +1,7 @@ #![no_main] #![no_std] -use megstd::{drawing::OneBitColor, sys::syscall::*, window::*}; +use megstd::{drawing::Monochrome, sys::syscall::*, window::*}; const BG_COLOR: WindowColor = WindowColor::BLACK; const FG_COLOR: WindowColor = WindowColor::YELLOW; @@ -77,13 +77,13 @@ fn _start() { let next_life = if life.into_bool() { if count <= 1 || count >= 4 { - OneBitColor::Zero + Monochrome::Zero } else { life } } else { if count == 3 { - OneBitColor::One + Monochrome::One } else { life } diff --git a/assets/initrd/wall.jpg b/assets/initrd/wall.jpg new file mode 100644 index 000000000..e1747296e Binary files /dev/null and b/assets/initrd/wall.jpg differ diff --git a/assets/initrd/wall.png b/assets/initrd/wall.png deleted file mode 100644 index 0fe7f2e17..000000000 Binary files a/assets/initrd/wall.png and /dev/null differ diff --git a/boot/boot-efi/src/page/amd64.rs b/boot/boot-efi/src/page/amd64.rs index ed9856c09..633659361 100644 --- a/boot/boot-efi/src/page/amd64.rs +++ b/boot/boot-efi/src/page/amd64.rs @@ -172,19 +172,19 @@ impl PageManager { shared.pml2k = PageTableEntry::new(pml2kp, common_attributes); pml3k[kernel_base.index_of(3)] = shared.pml2k; - // vram (temp) - let vram_base = info.vram_base; - let vram_size = Self::pages( - info.vram_stride as u64 * info.screen_height as u64 * 4, - PageTableEntry::LARGE_PAGE_SIZE, - ) as u64; - let offset = vram_base / PageTableEntry::LARGE_PAGE_SIZE; - for i in 0..vram_size { - pml2[(offset + i) as usize] = PageTableEntry::new( - vram_base + i * PageTableEntry::LARGE_PAGE_SIZE, - common_attributes | PageAttributes::LARGE, - ); - } + // // vram (temp) + // let vram_base = info.vram_base; + // let vram_size = Self::pages( + // info.vram_stride as u64 * info.screen_height as u64 * 4, + // PageTableEntry::LARGE_PAGE_SIZE, + // ) as u64; + // let offset = vram_base / PageTableEntry::LARGE_PAGE_SIZE; + // for i in 0..vram_size { + // pml2[(offset + i) as usize] = PageTableEntry::new( + // vram_base + i * PageTableEntry::LARGE_PAGE_SIZE, + // common_attributes | PageAttributes::LARGE, + // ); + // } } #[allow(dead_code)] diff --git a/boot/lib-efi/src/debug/mod.rs b/boot/lib-efi/src/debug/mod.rs index 2b5eade36..652f80c96 100644 --- a/boot/lib-efi/src/debug/mod.rs +++ b/boot/lib-efi/src/debug/mod.rs @@ -54,7 +54,7 @@ impl Console { shared.cols = (width - Self::PADDING_X * 2) / FONT_MEGH0816_WIDTH; shared.rows = (height - Self::PADDING_Y * 2) / FONT_MEGH0816_HEIGHT; - // shared.fill_rect(0, 0, width, height, 0x000000); + shared.fill_rect(0, 0, width, height, 0x000000); } pub fn put_char(&mut self, c: char) { diff --git a/lib/meggl/src/bitmap.rs b/lib/meggl/src/bitmap.rs index a1a7e04ab..69efc7674 100644 --- a/lib/meggl/src/bitmap.rs +++ b/lib/meggl/src/bitmap.rs @@ -1,7 +1,7 @@ use super::*; use alloc::{borrow::ToOwned, boxed::Box, vec::Vec}; use core::{ - borrow::Borrow, + borrow::{Borrow, BorrowMut}, cell::UnsafeCell, convert::TryFrom, intrinsics::copy_nonoverlapping, @@ -15,7 +15,7 @@ pub trait Blt: Drawable { fn blt(&mut self, src: &T, origin: Point, rect: Rect); } -pub trait BasicDrawing: SetPixel { +pub trait DrawRect: SetPixel { fn fill_rect(&mut self, rect: Rect, color: Self::ColorType); fn draw_hline(&mut self, origin: Point, width: isize, color: Self::ColorType); @@ -297,7 +297,7 @@ pub trait DrawGlyph: SetPixel { } } -pub trait BltConvert: MutableRasterImage { +pub trait BltConvert: MutableRasterImage { #[inline] fn blt_convert(&mut self, src: &U, origin: Point, rect: Rect, mut f: F) where @@ -460,7 +460,7 @@ macro_rules! define_bitmap { stride: Option, ) -> Self where - ::ColorType: ~const ColorTrait, + ::ColorType: ~const PixelColor, { Self { size, @@ -475,7 +475,7 @@ macro_rules! define_bitmap { #[inline] pub const fn from_bytes(bytes: &'a [$inner_type], size: Size) -> Self where - ::ColorType: ~const ColorTrait + ::ColorType: ~const PixelColor { Self { size, @@ -495,16 +495,6 @@ macro_rules! define_bitmap { } impl<'a> []<'a> { - #[inline] - pub const fn as_const(&'a self) -> &'a []<'a> { - unsafe { transmute(self) } - } - - #[inline] - pub const fn into_const(self) -> []<'a> { - unsafe { transmute(self) } - } - #[inline] pub const fn from_slice( slice: &'a mut [$slice_type], @@ -512,7 +502,7 @@ macro_rules! define_bitmap { stride: Option, ) -> Self where - ::ColorType: ~const ColorTrait + ::ColorType: ~const PixelColor { Self { size, @@ -527,7 +517,7 @@ macro_rules! define_bitmap { #[inline] pub const fn from_bytes(bytes: &'a mut [$inner_type], size: Size) -> Self where - ::ColorType: ~const ColorTrait + ::ColorType: ~const PixelColor { Self { size, @@ -537,7 +527,17 @@ macro_rules! define_bitmap { } #[inline] - pub fn clone_mut(&'a mut self) -> Self { + pub const fn as_const(&'a self) -> &'a []<'a> { + unsafe { transmute(self) } + } + + #[inline] + pub const fn into_const(self) -> []<'a> { + unsafe { transmute(self) } + } + + #[inline] + pub fn clone_mut(&'a mut self) -> []<'a> { let slice = unsafe { &mut *self.slice.get() }; Self { size: self.size(), @@ -594,6 +594,13 @@ macro_rules! define_bitmap { } } + impl<'a> Borrow<[]<'a>> for []<'a> { + #[inline] + fn borrow(&self) -> &[]<'a> { + unsafe { transmute(self) } + } + } + impl ToOwned for []<'_> { type Owned = []; @@ -618,6 +625,13 @@ macro_rules! define_bitmap { } } + impl<'a> Borrow<[]<'a>> for [] { + #[inline] + fn borrow(&self) -> &[]<'a> { + unsafe { transmute(self) } + } + } + impl<'a> Borrow<[]<'a>> for [] { #[inline] fn borrow(&self) -> &[]<'a> { @@ -625,6 +639,13 @@ macro_rules! define_bitmap { } } + impl<'a> BorrowMut<[]<'a>> for [] { + #[inline] + fn borrow_mut(&mut self) -> &mut []<'a> { + unsafe { transmute(self) } + } + } + } }; ( $suffix:tt, $inner_type:ty, $color_type:ty, ) => { @@ -779,7 +800,7 @@ macro_rules! define_bitmap { impl DrawGlyph for []<'_> {} - impl BasicDrawing for []<'_> { + impl DrawRect for []<'_> { fn fill_rect(&mut self, rect: Rect, color: Self::ColorType) { let mut width = rect.width(); let mut height = rect.height(); @@ -891,9 +912,9 @@ macro_rules! define_bitmap { define_bitmap!(8, u8, IndexedColor,); define_bitmap!(16, u16, RGB565,); -define_bitmap!(32, u32, BGRA8888,); +define_bitmap!(32, u32, ARGB8888,); -impl BltConvert for BitmapRefMut8<'_> {} +impl BltConvert for BitmapRefMut8<'_> {} impl BltConvert for BitmapRefMut8<'_> {} impl BitmapRefMut8<'_> { @@ -937,11 +958,11 @@ impl BitmapRefMut8<'_> { } } -impl BltConvert for BitmapRefMut32<'_> {} +impl BltConvert for BitmapRefMut32<'_> {} impl BltConvert for BitmapRefMut32<'_> {} impl BitmapRefMut32<'_> { - pub fn blend_rect(&mut self, rect: Rect, color: BGRA8888) { + pub fn blend_rect(&mut self, rect: Rect, color: ARGB8888) { let rhs = color.components(); if rhs.is_opaque() { return self.fill_rect(rect, color); @@ -1034,7 +1055,7 @@ impl BitmapRefMut32<'_> { pub fn blt8(&mut self, src: &BitmapRef8, origin: Point, rect: Rect, palette: &[u32; 256]) { self.blt_convert(src, origin, rect, |c| { - BGRA8888::from_argb(palette[c.0 as usize]) + ARGB8888::from_argb(palette[c.0 as usize]) }); } @@ -1290,7 +1311,7 @@ impl DrawGlyph for BitmapRefMut<'_> { } } -impl BasicDrawing for BitmapRefMut<'_> { +impl DrawRect for BitmapRefMut<'_> { #[inline] fn fill_rect(&mut self, rect: Rect, color: Self::ColorType) { match self { @@ -1453,7 +1474,7 @@ pub struct OperationalBitmap { vec: Vec, } -impl ColorTrait for u8 {} +impl PixelColor for u8 {} impl const Drawable for OperationalBitmap { type ColorType = u8; @@ -1976,7 +1997,7 @@ mod memory_colors { } #[inline] - pub fn _memset_colors32(slice: &mut [BGRA8888], cursor: usize, count: usize, color: BGRA8888) { + pub fn _memset_colors32(slice: &mut [ARGB8888], cursor: usize, count: usize, color: ARGB8888) { for v in unsafe { slice.get_unchecked_mut(cursor..cursor + count) }.iter_mut() { *v = color; } @@ -1985,9 +2006,9 @@ mod memory_colors { // Alpha blending #[inline] pub fn _memcpy_blend32( - dest: &mut [BGRA8888], + dest: &mut [ARGB8888], dest_cursor: usize, - src: &[BGRA8888], + src: &[ARGB8888], src_cursor: usize, count: usize, ) { @@ -1999,7 +2020,7 @@ mod memory_colors { } } -define_bitmap!(1, u8, OneBitColor, Octet,); +define_bitmap!(1, u8, Monochrome, Octet,); impl BitmapRef1<'_> { #[inline] diff --git a/lib/meggl/src/color.rs b/lib/meggl/src/color.rs index 9eeac5d3b..63d954433 100644 --- a/lib/meggl/src/color.rs +++ b/lib/meggl/src/color.rs @@ -6,32 +6,43 @@ use core::{ /// Common color trait #[const_trait] -pub trait ColorTrait: Sized + Copy + Clone + PartialEq + Eq + Default { - // fn bits_per_pixel() -> usize; - // fn bits_per_channel() -> usize; - +pub trait PixelColor: Sized + Copy + Clone + PartialEq + Eq + Default { + /// This value is used to calculate the address of a raster image that supports this color format. #[inline] fn stride_for(width: isize) -> usize { width as usize } } -pub trait Transparency: ColorTrait { +#[const_trait] +pub trait Translucent: PixelColor { const TRANSPARENT: Self; + + fn is_transparent(&self) -> bool; + + fn is_opaque(&self) -> bool; } -pub trait KeyColor: ColorTrait { +pub trait KeyColor: PixelColor { const KEY_COLOR: Self; } -pub trait PrimaryColor: ColorTrait { +pub trait PrimaryColor: PixelColor { + /// RGB (0, 0, 0) const PRIMARY_BLACK: Self; + /// RGB (0, 0, 1) const PRIMARY_BLUE: Self; + /// RGB (0, 1, 0) const PRIMARY_GREEN: Self; + /// RGB (0, 1, 1) const PRIMARY_CYAN: Self; + /// RGB (1, 0, 0) const PRIMARY_RED: Self; + /// RGB (1, 0, 1) const PRIMARY_MAGENTA: Self; + /// RGB (1, 1, 0) const PRIMARY_YELLOW: Self; + /// RGB (1, 1, 1) const PRIMARY_WHITE: Self; } @@ -50,7 +61,7 @@ pub enum ColorFormat { #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)] pub struct IndexedColor(pub u8); -impl const ColorTrait for IndexedColor {} +impl const PixelColor for IndexedColor {} impl KeyColor for IndexedColor { const KEY_COLOR: Self = Self(u8::MAX); @@ -144,8 +155,8 @@ impl IndexedColor { } #[inline] - pub const fn as_true_color(self) -> BGRA8888 { - BGRA8888::from_argb(self.as_argb()) + pub const fn as_true_color(self) -> ARGB8888 { + ARGB8888::from_argb(self.as_argb()) } #[inline] @@ -161,7 +172,7 @@ impl const From for IndexedColor { } } -impl const From for BGRA8888 { +impl const From for ARGB8888 { #[inline] fn from(val: IndexedColor) -> Self { val.as_true_color() @@ -172,29 +183,24 @@ impl const From for BGRA8888 { #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct Alpha8(pub u8); -impl Alpha8 { - pub const TRANSPARENT: Self = Self(0); - pub const OPAQUE: Self = Self(u8::MAX); +impl PixelColor for Alpha8 {} - #[inline] - pub const fn transparent() -> Self { - Self::TRANSPARENT - } - - #[inline] - pub const fn opaque() -> Self { - Self::OPAQUE - } +impl const Translucent for Alpha8 { + const TRANSPARENT: Self = Self(0); #[inline] - pub const fn is_transparent(&self) -> bool { + fn is_transparent(&self) -> bool { self.0 == Self::TRANSPARENT.0 } #[inline] - pub const fn is_opaque(&self) -> bool { + fn is_opaque(&self) -> bool { self.0 == Self::OPAQUE.0 } +} + +impl Alpha8 { + pub const OPAQUE: Self = Self(u8::MAX); #[inline] pub const fn into_f32(self) -> f32 { @@ -352,21 +358,30 @@ impl const SubAssign for Alpha8 { } } -#[cfg(target_endian = "little")] -pub type TrueColor = BGRA8888; +pub type TrueColor = ARGB8888; /// 32bit TrueColor #[repr(transparent)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] -pub struct BGRA8888(pub u32); +pub struct ARGB8888(pub u32); -impl ColorTrait for BGRA8888 {} +impl PixelColor for ARGB8888 {} -impl Transparency for BGRA8888 { +impl const Translucent for ARGB8888 { const TRANSPARENT: Self = Self(0); + + #[inline] + fn is_transparent(&self) -> bool { + self.opacity().is_transparent() + } + + #[inline] + fn is_opaque(&self) -> bool { + self.opacity().is_opaque() + } } -impl PrimaryColor for BGRA8888 { +impl PrimaryColor for ARGB8888 { const PRIMARY_BLACK: Self = Self::from_rgb(0x00_00_00); const PRIMARY_BLUE: Self = Self::from_rgb(0x00_00_FF); const PRIMARY_GREEN: Self = Self::from_rgb(0x00_FF_00); @@ -377,7 +392,7 @@ impl PrimaryColor for BGRA8888 { const PRIMARY_WHITE: Self = Self::from_rgb(0xFF_FF_FF); } -impl BGRA8888 { +impl ARGB8888 { pub const BLACK: Self = Self::from_rgb(0x212121); pub const BLUE: Self = Self::from_rgb(0x0D47A1); pub const GREEN: Self = Self::from_rgb(0x1B5E20); @@ -451,16 +466,6 @@ impl BGRA8888 { components.into_true_color() } - #[inline] - pub const fn is_opaque(&self) -> bool { - self.opacity().is_opaque() - } - - #[inline] - pub const fn is_transparent(&self) -> bool { - self.opacity().is_transparent() - } - #[inline] pub fn blending(&self, rhs: Self, f_rgb: F1, f_a: F2) -> Self where @@ -505,16 +510,16 @@ impl BGRA8888 { } } -impl const From for BGRA8888 { +impl const From for ARGB8888 { #[inline] fn from(argb: u32) -> Self { Self::from_argb(argb) } } -impl const From for IndexedColor { +impl const From for IndexedColor { #[inline] - fn from(color: BGRA8888) -> Self { + fn from(color: ARGB8888) -> Self { Self::from_rgb(color.rgb()) } } @@ -546,13 +551,13 @@ impl ColorComponents { #[inline] #[cfg(target_endian = "little")] - pub const fn from_true_color(val: BGRA8888) -> Self { + pub const fn from_true_color(val: ARGB8888) -> Self { unsafe { transmute(val) } } #[inline] #[cfg(target_endian = "little")] - pub const fn into_true_color(self) -> BGRA8888 { + pub const fn into_true_color(self) -> ARGB8888 { unsafe { transmute(self) } } @@ -582,15 +587,15 @@ impl ColorComponents { } #[cfg(target_endian = "little")] -impl const From for ColorComponents { +impl const From for ColorComponents { #[inline] - fn from(color: BGRA8888) -> Self { + fn from(color: ARGB8888) -> Self { unsafe { transmute(color) } } } #[cfg(target_endian = "little")] -impl const From for BGRA8888 { +impl const From for ARGB8888 { #[inline] fn from(components: ColorComponents) -> Self { unsafe { transmute(components) } @@ -610,10 +615,20 @@ impl const Into for ColorComponents { #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] pub struct RGBA8888(pub(super) u32); -impl ColorTrait for RGBA8888 {} +impl PixelColor for RGBA8888 {} -impl Transparency for RGBA8888 { +impl const Translucent for RGBA8888 { const TRANSPARENT: Self = Self(0); + + #[inline] + fn is_transparent(&self) -> bool { + self.components().is_transparent() + } + + #[inline] + fn is_opaque(&self) -> bool { + self.components().is_opaque() + } } impl PrimaryColor for RGBA8888 { @@ -639,16 +654,6 @@ impl RGBA8888 { pub const fn opacity(&self) -> Alpha8 { self.components().a } - - #[inline] - pub const fn is_transparent(&self) -> bool { - self.components().is_transparent() - } - - #[inline] - pub const fn is_opaque(&self) -> bool { - self.components().is_opaque() - } } #[cfg(target_endian = "little")] @@ -659,14 +664,14 @@ impl RGBA8888 { } } -impl const From for RGBA8888 { +impl const From for RGBA8888 { #[inline] - fn from(v: BGRA8888) -> Self { + fn from(v: ARGB8888) -> Self { Self::from(ColorComponentsRGBA::from(v.components())) } } -impl const From for BGRA8888 { +impl const From for ARGB8888 { #[inline] fn from(v: RGBA8888) -> Self { Self::from(ColorComponents::from(v.components())) @@ -774,13 +779,37 @@ impl const From<[u8; 4]> for ColorComponentsRGBA { pub enum Color { Transparent, Indexed(IndexedColor), - Argb32(BGRA8888), + Argb32(ARGB8888), } -impl ColorTrait for Color {} +impl PixelColor for Color {} -impl Transparency for Color { +impl const Translucent for Color { const TRANSPARENT: Self = Self::Transparent; + + #[inline] + fn is_transparent(&self) -> bool { + match self { + Color::Transparent => true, + Color::Indexed(c) => match *c { + IndexedColor::KEY_COLOR => true, + _ => false, + }, + Color::Argb32(c) => c.is_transparent(), + } + } + + #[inline] + fn is_opaque(&self) -> bool { + match self { + Color::Transparent => false, + Color::Indexed(c) => match *c { + IndexedColor::KEY_COLOR => false, + _ => true, + }, + Color::Argb32(c) => c.is_opaque(), + } + } } impl KeyColor for Color { @@ -799,31 +828,31 @@ impl PrimaryColor for Color { } impl Color { - pub const BLACK: Self = Self::Argb32(BGRA8888::BLACK); - pub const BLUE: Self = Self::Argb32(BGRA8888::BLUE); - pub const GREEN: Self = Self::Argb32(BGRA8888::GREEN); - pub const CYAN: Self = Self::Argb32(BGRA8888::CYAN); - pub const RED: Self = Self::Argb32(BGRA8888::RED); - pub const MAGENTA: Self = Self::Argb32(BGRA8888::MAGENTA); - pub const BROWN: Self = Self::Argb32(BGRA8888::BROWN); - pub const LIGHT_GRAY: Self = Self::Argb32(BGRA8888::LIGHT_GRAY); - pub const DARK_GRAY: Self = Self::Argb32(BGRA8888::DARK_GRAY); - pub const LIGHT_BLUE: Self = Self::Argb32(BGRA8888::LIGHT_BLUE); - pub const LIGHT_GREEN: Self = Self::Argb32(BGRA8888::LIGHT_GREEN); - pub const LIGHT_CYAN: Self = Self::Argb32(BGRA8888::LIGHT_CYAN); - pub const LIGHT_RED: Self = Self::Argb32(BGRA8888::LIGHT_RED); - pub const LIGHT_MAGENTA: Self = Self::Argb32(BGRA8888::LIGHT_MAGENTA); - pub const YELLOW: Self = Self::Argb32(BGRA8888::YELLOW); - pub const WHITE: Self = Self::Argb32(BGRA8888::WHITE); + pub const BLACK: Self = Self::Argb32(ARGB8888::BLACK); + pub const BLUE: Self = Self::Argb32(ARGB8888::BLUE); + pub const GREEN: Self = Self::Argb32(ARGB8888::GREEN); + pub const CYAN: Self = Self::Argb32(ARGB8888::CYAN); + pub const RED: Self = Self::Argb32(ARGB8888::RED); + pub const MAGENTA: Self = Self::Argb32(ARGB8888::MAGENTA); + pub const BROWN: Self = Self::Argb32(ARGB8888::BROWN); + pub const LIGHT_GRAY: Self = Self::Argb32(ARGB8888::LIGHT_GRAY); + pub const DARK_GRAY: Self = Self::Argb32(ARGB8888::DARK_GRAY); + pub const LIGHT_BLUE: Self = Self::Argb32(ARGB8888::LIGHT_BLUE); + pub const LIGHT_GREEN: Self = Self::Argb32(ARGB8888::LIGHT_GREEN); + pub const LIGHT_CYAN: Self = Self::Argb32(ARGB8888::LIGHT_CYAN); + pub const LIGHT_RED: Self = Self::Argb32(ARGB8888::LIGHT_RED); + pub const LIGHT_MAGENTA: Self = Self::Argb32(ARGB8888::LIGHT_MAGENTA); + pub const YELLOW: Self = Self::Argb32(ARGB8888::YELLOW); + pub const WHITE: Self = Self::Argb32(ARGB8888::WHITE); #[inline] pub const fn from_rgb(rgb: u32) -> Self { - Self::Argb32(BGRA8888::from_rgb(rgb)) + Self::Argb32(ARGB8888::from_rgb(rgb)) } #[inline] pub const fn from_argb(argb: u32) -> Self { - Self::Argb32(BGRA8888::from_argb(argb)) + Self::Argb32(ARGB8888::from_argb(argb)) } #[inline] @@ -836,9 +865,9 @@ impl Color { } #[inline] - pub const fn into_true_color(&self) -> BGRA8888 { + pub const fn into_true_color(&self) -> ARGB8888 { match self { - Color::Transparent => BGRA8888::TRANSPARENT, + Color::Transparent => ARGB8888::TRANSPARENT, Color::Indexed(v) => v.as_true_color(), Color::Argb32(v) => *v, } @@ -852,18 +881,6 @@ impl Color { Color::Argb32(c) => c.brightness(), } } - - #[inline] - pub const fn is_transparent(&self) -> bool { - match self { - Color::Transparent => true, - Color::Indexed(c) => match *c { - IndexedColor::KEY_COLOR => true, - _ => false, - }, - Color::Argb32(c) => c.is_transparent(), - } - } } impl const Default for Color { @@ -880,9 +897,9 @@ impl const Into for Color { } } -impl const Into for Color { +impl const Into for Color { #[inline] - fn into(self) -> BGRA8888 { + fn into(self) -> ARGB8888 { self.into_true_color() } } @@ -894,9 +911,9 @@ impl const From for Color { } } -impl const From for Color { +impl const From for Color { #[inline] - fn from(val: BGRA8888) -> Self { + fn from(val: ARGB8888) -> Self { Self::Argb32(val) } } @@ -908,21 +925,35 @@ impl const From for Color { #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub struct PackedColor(pub u32); -impl ColorTrait for PackedColor {} +impl PixelColor for PackedColor {} -impl Transparency for PackedColor { +impl const Translucent for PackedColor { const TRANSPARENT: Self = Self(Self::INDEX_COLOR_MAX + 1); + + #[inline] + fn is_transparent(&self) -> bool { + matches!(*self, Self::TRANSPARENT) + } + + #[inline] + fn is_opaque(&self) -> bool { + match self.as_color() { + Color::Transparent => false, + Color::Indexed(_) => true, + Color::Argb32(c) => c.is_opaque(), + } + } } impl PrimaryColor for PackedColor { - const PRIMARY_BLACK: Self = Self::from_true_color(BGRA8888::PRIMARY_BLACK); - const PRIMARY_BLUE: Self = Self::from_true_color(BGRA8888::PRIMARY_BLUE); - const PRIMARY_GREEN: Self = Self::from_true_color(BGRA8888::PRIMARY_GREEN); - const PRIMARY_CYAN: Self = Self::from_true_color(BGRA8888::PRIMARY_CYAN); - const PRIMARY_RED: Self = Self::from_true_color(BGRA8888::PRIMARY_RED); - const PRIMARY_MAGENTA: Self = Self::from_true_color(BGRA8888::PRIMARY_MAGENTA); - const PRIMARY_YELLOW: Self = Self::from_true_color(BGRA8888::PRIMARY_YELLOW); - const PRIMARY_WHITE: Self = Self::from_true_color(BGRA8888::PRIMARY_WHITE); + const PRIMARY_BLACK: Self = Self::from_true_color(ARGB8888::PRIMARY_BLACK); + const PRIMARY_BLUE: Self = Self::from_true_color(ARGB8888::PRIMARY_BLUE); + const PRIMARY_GREEN: Self = Self::from_true_color(ARGB8888::PRIMARY_GREEN); + const PRIMARY_CYAN: Self = Self::from_true_color(ARGB8888::PRIMARY_CYAN); + const PRIMARY_RED: Self = Self::from_true_color(ARGB8888::PRIMARY_RED); + const PRIMARY_MAGENTA: Self = Self::from_true_color(ARGB8888::PRIMARY_MAGENTA); + const PRIMARY_YELLOW: Self = Self::from_true_color(ARGB8888::PRIMARY_YELLOW); + const PRIMARY_WHITE: Self = Self::from_true_color(ARGB8888::PRIMARY_WHITE); } impl PackedColor { @@ -948,7 +979,7 @@ impl PackedColor { #[inline] pub const fn from_argb(argb: u32) -> Self { - Self::from_true_color(BGRA8888::from_argb(argb)) + Self::from_true_color(ARGB8888::from_argb(argb)) } #[inline] @@ -957,7 +988,7 @@ impl PackedColor { } #[inline] - pub const fn from_true_color(argb: BGRA8888) -> Self { + pub const fn from_true_color(argb: ARGB8888) -> Self { match argb.is_transparent() { true => Self::TRANSPARENT, false => Self(argb.argb()), @@ -993,7 +1024,7 @@ impl PackedColor { } #[inline] - pub const fn into_true_color(self) -> BGRA8888 { + pub const fn into_true_color(self) -> ARGB8888 { self.as_color().into_true_color() } @@ -1003,9 +1034,9 @@ impl PackedColor { } } -impl const From for PackedColor { +impl const From for PackedColor { #[inline] - fn from(color: BGRA8888) -> Self { + fn from(color: ARGB8888) -> Self { Self::from_true_color(color) } } @@ -1036,7 +1067,7 @@ impl const From for Color { #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)] pub struct RGB555(pub u16); -impl ColorTrait for RGB555 {} +impl PixelColor for RGB555 {} impl PrimaryColor for RGB555 { const PRIMARY_BLACK: Self = Self::from_rgb(0x00_00_00); @@ -1064,7 +1095,7 @@ impl RGB555 { } #[inline] - pub const fn as_true_color(&self) -> BGRA8888 { + pub const fn as_true_color(&self) -> ARGB8888 { let components = self.components(); let components = ColorComponents { a: Alpha8::OPAQUE, @@ -1082,11 +1113,11 @@ impl RGB555 { #[inline] const fn from_rgb(rgb: u32) -> Self { - Self::from_true_color(BGRA8888::from_rgb(rgb)) + Self::from_true_color(ARGB8888::from_rgb(rgb)) } #[inline] - pub const fn from_true_color(color: BGRA8888) -> Self { + pub const fn from_true_color(color: ARGB8888) -> Self { let components = color.components(); Self( ((components.b >> 3) as u16) @@ -1096,14 +1127,14 @@ impl RGB555 { } } -impl const From for RGB555 { +impl const From for RGB555 { #[inline] - fn from(color: BGRA8888) -> Self { + fn from(color: ARGB8888) -> Self { Self::from_true_color(color) } } -impl const From for BGRA8888 { +impl const From for ARGB8888 { #[inline] fn from(color: RGB555) -> Self { color.as_true_color() @@ -1129,7 +1160,7 @@ impl const From for Color { #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)] pub struct RGB565(pub u16); -impl ColorTrait for RGB565 {} +impl PixelColor for RGB565 {} impl PrimaryColor for RGB565 { const PRIMARY_BLACK: Self = Self::from_rgb(0x00_00_00); @@ -1157,7 +1188,7 @@ impl RGB565 { } #[inline] - pub const fn as_true_color(&self) -> BGRA8888 { + pub const fn as_true_color(&self) -> ARGB8888 { let components = self.components(); let components = ColorComponents { a: Alpha8::OPAQUE, @@ -1180,11 +1211,11 @@ impl RGB565 { #[inline] const fn from_rgb(rgb: u32) -> Self { - Self::from_true_color(BGRA8888::from_rgb(rgb)) + Self::from_true_color(ARGB8888::from_rgb(rgb)) } #[inline] - pub const fn from_true_color(color: BGRA8888) -> Self { + pub const fn from_true_color(color: ARGB8888) -> Self { let components = color.components(); Self( ((components.b >> 3) as u16) @@ -1194,14 +1225,14 @@ impl RGB565 { } } -impl const From for RGB565 { +impl const From for RGB565 { #[inline] - fn from(color: BGRA8888) -> Self { + fn from(color: ARGB8888) -> Self { Self::from_true_color(color) } } -impl const From for BGRA8888 { +impl const From for ARGB8888 { #[inline] fn from(color: RGB565) -> Self { color.as_true_color() @@ -1243,7 +1274,7 @@ pub enum IndexedColor4 { Color1111, } -impl const ColorTrait for IndexedColor4 { +impl const PixelColor for IndexedColor4 { #[inline] fn stride_for(width: isize) -> usize { (width as usize + 1) / 2 @@ -1333,19 +1364,19 @@ impl IndexedColorPair44 { } #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub enum OneBitColor { +pub enum Monochrome { Zero, One, } -impl const ColorTrait for OneBitColor { +impl const PixelColor for Monochrome { #[inline] fn stride_for(width: isize) -> usize { (width as usize + 7) / 8 } } -impl OneBitColor { +impl Monochrome { #[inline] pub const fn new(value: u8) -> Self { match value { @@ -1372,35 +1403,35 @@ impl OneBitColor { } } -impl const From for u8 { +impl const From for u8 { #[inline] - fn from(value: OneBitColor) -> Self { + fn from(value: Monochrome) -> Self { value.into_bool() as u8 } } -impl const From for OneBitColor { +impl const From for Monochrome { #[inline] fn from(value: u8) -> Self { Self::new(value) } } -impl const From for bool { +impl const From for bool { #[inline] - fn from(value: OneBitColor) -> Self { + fn from(value: Monochrome) -> Self { value.into_bool() } } -impl const From for OneBitColor { +impl const From for Monochrome { #[inline] fn from(value: bool) -> Self { Self::new(value as u8) } } -impl const Default for OneBitColor { +impl const Default for Monochrome { #[inline] fn default() -> Self { Self::Zero @@ -1423,12 +1454,12 @@ impl Octet { } #[inline] - pub fn get(&self, at: usize) -> OneBitColor { - OneBitColor::new(self.0 & 0x80u8 >> at) + pub fn get(&self, at: usize) -> Monochrome { + Monochrome::new(self.0 & (0x80u8 >> at)) } #[inline] - pub fn set(&mut self, at: usize, value: OneBitColor) { + pub fn set(&mut self, at: usize, value: Monochrome) { let mask = 0x80u8 >> at; if value.into_bool() { self.0 |= mask; @@ -1438,7 +1469,7 @@ impl Octet { } #[inline] - pub fn from_array(array: &[OneBitColor]) -> Self { + pub fn from_array(array: &[Monochrome]) -> Self { array .iter() .take(8) @@ -1450,16 +1481,16 @@ impl Octet { } #[inline] - pub fn iter(&self) -> impl Iterator { + pub fn iter(&self) -> impl Iterator { let raw = self.0; (0..8) .map(|v| 0x80u8 >> v) - .map(move |v| OneBitColor::new(raw & v)) + .map(move |v| Monochrome::new(raw & v)) } #[inline] - pub fn into_array(self) -> [OneBitColor; 8] { - let mut result = [OneBitColor::default(); 8]; + pub fn into_array(self) -> [Monochrome; 8] { + let mut result = [Monochrome::default(); 8]; result.iter_mut().zip(self.iter()).for_each(|(a, b)| *a = b); result } diff --git a/lib/meggl/src/drawable.rs b/lib/meggl/src/drawable.rs index a380a5b27..9febec774 100644 --- a/lib/meggl/src/drawable.rs +++ b/lib/meggl/src/drawable.rs @@ -4,7 +4,7 @@ use core::mem::transmute; #[const_trait] pub trait Drawable where - Self::ColorType: ColorTrait, + Self::ColorType: PixelColor, { type ColorType; @@ -32,6 +32,7 @@ pub trait GetPixel: Drawable { /// The point must be within the size range. unsafe fn get_pixel_unchecked(&self, point: Point) -> Self::ColorType; + #[inline] fn get_pixel(&self, point: Point) -> Option { if self.bounds().contains(point) { Some(unsafe { self.get_pixel_unchecked(point) }) @@ -104,6 +105,7 @@ pub trait SetPixel: Drawable { /// The point must be within the size range. unsafe fn set_pixel_unchecked(&mut self, point: Point, pixel: Self::ColorType); + #[inline] fn set_pixel(&mut self, point: Point, pixel: Self::ColorType) { if self.bounds().contains(point) { unsafe { diff --git a/lib/meggl/src/lib.rs b/lib/meggl/src/lib.rs index 1b081a254..6c3d24800 100644 --- a/lib/meggl/src/lib.rs +++ b/lib/meggl/src/lib.rs @@ -16,7 +16,6 @@ pub use bitmap::*; pub use color::*; pub use coords::*; pub use drawable::*; -pub mod vertex; #[cfg(test)] pub mod tests; diff --git a/lib/meggl/src/tests.rs b/lib/meggl/src/tests.rs index 4e9bc18b5..222899a9b 100644 --- a/lib/meggl/src/tests.rs +++ b/lib/meggl/src/tests.rs @@ -2,7 +2,7 @@ use super::*; #[test] fn components() { - let rgb = BGRA8888(0x12345678); + let rgb = ARGB8888(0x12345678); let components = rgb.components(); assert_eq!(rgb.components().a, Alpha8(0x12)); @@ -17,15 +17,15 @@ fn components() { #[test] fn rgb555() { - let tc_000 = BGRA8888::from_rgb(0x000000); - let tc_00f = BGRA8888::from_rgb(0x0000FF); - let tc_0f0 = BGRA8888::from_rgb(0x00FF00); - let tc_f00 = BGRA8888::from_rgb(0xFF0000); - let tc_fff = BGRA8888::from_rgb(0xFFFFFF); - let tc_555 = BGRA8888::from_rgb(0x555555); - let tc_aaa = BGRA8888::from_rgb(0xAAAAAA); - let tc_5a5 = BGRA8888::from_rgb(0x55AA55); - let tc_a5a = BGRA8888::from_rgb(0xAA55AA); + let tc_000 = ARGB8888::from_rgb(0x000000); + let tc_00f = ARGB8888::from_rgb(0x0000FF); + let tc_0f0 = ARGB8888::from_rgb(0x00FF00); + let tc_f00 = ARGB8888::from_rgb(0xFF0000); + let tc_fff = ARGB8888::from_rgb(0xFFFFFF); + let tc_555 = ARGB8888::from_rgb(0x555555); + let tc_aaa = ARGB8888::from_rgb(0xAAAAAA); + let tc_5a5 = ARGB8888::from_rgb(0x55AA55); + let tc_a5a = ARGB8888::from_rgb(0xAA55AA); assert_eq!(RGB555::from(tc_000).0, 0x0000); assert_eq!(RGB555::from(tc_00f).0, 0x001F); @@ -47,24 +47,24 @@ fn rgb555() { let hc_5a5 = RGB555(0x2AAA); let hc_a5a = RGB555(0x5555); - assert_eq!(BGRA8888::from(hc_000).rgb(), 0x000000); - assert_eq!(BGRA8888::from(hc_00f).rgb(), 0x0000FF); - assert_eq!(BGRA8888::from(hc_0f0).rgb(), 0x00FF00); - assert_eq!(BGRA8888::from(hc_f00).rgb(), 0xFF0000); - assert_eq!(BGRA8888::from(hc_fff).rgb(), 0xFFFFFF); - assert_eq!(BGRA8888::from(hc_555).rgb(), 0x525252); - assert_eq!(BGRA8888::from(hc_aaa).rgb(), 0xADADAD); - assert_eq!(BGRA8888::from(hc_5a5).rgb(), 0x52AD52); - assert_eq!(BGRA8888::from(hc_a5a).rgb(), 0xAD52AD); + assert_eq!(ARGB8888::from(hc_000).rgb(), 0x000000); + assert_eq!(ARGB8888::from(hc_00f).rgb(), 0x0000FF); + assert_eq!(ARGB8888::from(hc_0f0).rgb(), 0x00FF00); + assert_eq!(ARGB8888::from(hc_f00).rgb(), 0xFF0000); + assert_eq!(ARGB8888::from(hc_fff).rgb(), 0xFFFFFF); + assert_eq!(ARGB8888::from(hc_555).rgb(), 0x525252); + assert_eq!(ARGB8888::from(hc_aaa).rgb(), 0xADADAD); + assert_eq!(ARGB8888::from(hc_5a5).rgb(), 0x52AD52); + assert_eq!(ARGB8888::from(hc_a5a).rgb(), 0xAD52AD); } #[test] fn canvas() { - let true_color = BGRA8888::from_argb(0x12345678); + let true_color = ARGB8888::from_argb(0x12345678); let components1 = true_color.components(); let canvas_color = RGBA8888::from(true_color); let components2 = canvas_color.components(); - let true_color = BGRA8888::from(canvas_color); + let true_color = ARGB8888::from(canvas_color); assert_eq!(canvas_color.0, 0x12785634); assert_eq!(true_color.argb(), 0x12345678); @@ -77,211 +77,211 @@ fn canvas() { #[test] fn one_bit_colors() { - fn array_test(value: u8, array: &[OneBitColor]) { + fn array_test(value: u8, array: &[Monochrome]) { let value = Octet::new(value); assert_eq!(value, Octet::from_array(array)); assert_eq!(value.into_array(), array); } - fn array_test2(value: u8, array: &[OneBitColor], formal: &[OneBitColor]) { + fn array_test2(value: u8, array: &[Monochrome], formal: &[Monochrome]) { let value = Octet::new(value); assert_eq!(value, Octet::from_array(array)); assert_eq!(value.into_array(), formal); } - array_test2(0b00000000, &[], &[OneBitColor::Zero; 8]); + array_test2(0b00000000, &[], &[Monochrome::Zero; 8]); array_test2( 0b10000000, - &[OneBitColor::One], + &[Monochrome::One], &[ - OneBitColor::One, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::Zero, + Monochrome::One, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::Zero, ], ); array_test2( 0b10100000, - &[OneBitColor::One, OneBitColor::Zero, OneBitColor::One], + &[Monochrome::One, Monochrome::Zero, Monochrome::One], &[ - OneBitColor::One, - OneBitColor::Zero, - OneBitColor::One, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::Zero, + Monochrome::One, + Monochrome::Zero, + Monochrome::One, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::Zero, ], ); array_test2( 0b00001001, &[ - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::One, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::One, - OneBitColor::One, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::One, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::One, + Monochrome::One, ], &[ - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::One, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::One, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::One, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::One, ], ); array_test( 0b01010101, &[ - OneBitColor::Zero, - OneBitColor::One, - OneBitColor::Zero, - OneBitColor::One, - OneBitColor::Zero, - OneBitColor::One, - OneBitColor::Zero, - OneBitColor::One, + Monochrome::Zero, + Monochrome::One, + Monochrome::Zero, + Monochrome::One, + Monochrome::Zero, + Monochrome::One, + Monochrome::Zero, + Monochrome::One, ], ); array_test( 0b10101010, &[ - OneBitColor::One, - OneBitColor::Zero, - OneBitColor::One, - OneBitColor::Zero, - OneBitColor::One, - OneBitColor::Zero, - OneBitColor::One, - OneBitColor::Zero, + Monochrome::One, + Monochrome::Zero, + Monochrome::One, + Monochrome::Zero, + Monochrome::One, + Monochrome::Zero, + Monochrome::One, + Monochrome::Zero, ], ); array_test( 0b00010111, &[ - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::One, - OneBitColor::Zero, - OneBitColor::One, - OneBitColor::One, - OneBitColor::One, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::One, + Monochrome::Zero, + Monochrome::One, + Monochrome::One, + Monochrome::One, ], ); array_test( 0b11101000, &[ - OneBitColor::One, - OneBitColor::One, - OneBitColor::One, - OneBitColor::Zero, - OneBitColor::One, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::Zero, + Monochrome::One, + Monochrome::One, + Monochrome::One, + Monochrome::Zero, + Monochrome::One, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::Zero, ], ); array_test( 0b11000011, &[ - OneBitColor::One, - OneBitColor::One, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::One, - OneBitColor::One, + Monochrome::One, + Monochrome::One, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::One, + Monochrome::One, ], ); array_test( 0b00111100, &[ - OneBitColor::Zero, - OneBitColor::Zero, - OneBitColor::One, - OneBitColor::One, - OneBitColor::One, - OneBitColor::One, - OneBitColor::Zero, - OneBitColor::Zero, + Monochrome::Zero, + Monochrome::Zero, + Monochrome::One, + Monochrome::One, + Monochrome::One, + Monochrome::One, + Monochrome::Zero, + Monochrome::Zero, ], ); array_test( 0b11111111, &[ - OneBitColor::One, - OneBitColor::One, - OneBitColor::One, - OneBitColor::One, - OneBitColor::One, - OneBitColor::One, - OneBitColor::One, - OneBitColor::One, + Monochrome::One, + Monochrome::One, + Monochrome::One, + Monochrome::One, + Monochrome::One, + Monochrome::One, + Monochrome::One, + Monochrome::One, ], ); let mut canvas = Octet::default(); assert_eq!(canvas, Octet::new(0)); - canvas.set(0, OneBitColor::One); + canvas.set(0, Monochrome::One); assert_eq!(canvas, Octet::new(0b10000000)); - assert_eq!(canvas.get(0), OneBitColor::One); - assert_eq!(canvas.get(1), OneBitColor::Zero); - assert_eq!(canvas.get(2), OneBitColor::Zero); - assert_eq!(canvas.get(3), OneBitColor::Zero); - assert_eq!(canvas.get(4), OneBitColor::Zero); - assert_eq!(canvas.get(5), OneBitColor::Zero); - assert_eq!(canvas.get(6), OneBitColor::Zero); - assert_eq!(canvas.get(7), OneBitColor::Zero); + assert_eq!(canvas.get(0), Monochrome::One); + assert_eq!(canvas.get(1), Monochrome::Zero); + assert_eq!(canvas.get(2), Monochrome::Zero); + assert_eq!(canvas.get(3), Monochrome::Zero); + assert_eq!(canvas.get(4), Monochrome::Zero); + assert_eq!(canvas.get(5), Monochrome::Zero); + assert_eq!(canvas.get(6), Monochrome::Zero); + assert_eq!(canvas.get(7), Monochrome::Zero); - canvas.set(1, OneBitColor::One); + canvas.set(1, Monochrome::One); assert_eq!(canvas, Octet::new(0b11000000)); - assert_eq!(canvas.get(0), OneBitColor::One); - assert_eq!(canvas.get(1), OneBitColor::One); + assert_eq!(canvas.get(0), Monochrome::One); + assert_eq!(canvas.get(1), Monochrome::One); - canvas.set(2, OneBitColor::One); + canvas.set(2, Monochrome::One); assert_eq!(canvas, Octet::new(0b11100000)); - canvas.set(5, OneBitColor::One); + canvas.set(5, Monochrome::One); assert_eq!(canvas, Octet::new(0b11100100)); - assert_eq!(canvas.get(5), OneBitColor::One); + assert_eq!(canvas.get(5), Monochrome::One); - canvas.set(7, OneBitColor::One); + canvas.set(7, Monochrome::One); assert_eq!(canvas, Octet::new(0b11100101)); - assert_eq!(canvas.get(7), OneBitColor::One); + assert_eq!(canvas.get(7), Monochrome::One); - canvas.set(1, OneBitColor::Zero); + canvas.set(1, Monochrome::Zero); assert_eq!(canvas, Octet::new(0b10100101)); - assert_eq!(canvas.get(0), OneBitColor::One); - assert_eq!(canvas.get(1), OneBitColor::Zero); - assert_eq!(canvas.get(2), OneBitColor::One); - assert_eq!(canvas.get(3), OneBitColor::Zero); - assert_eq!(canvas.get(4), OneBitColor::Zero); - assert_eq!(canvas.get(5), OneBitColor::One); - assert_eq!(canvas.get(6), OneBitColor::Zero); - assert_eq!(canvas.get(7), OneBitColor::One); + assert_eq!(canvas.get(0), Monochrome::One); + assert_eq!(canvas.get(1), Monochrome::Zero); + assert_eq!(canvas.get(2), Monochrome::One); + assert_eq!(canvas.get(3), Monochrome::Zero); + assert_eq!(canvas.get(4), Monochrome::Zero); + assert_eq!(canvas.get(5), Monochrome::One); + assert_eq!(canvas.get(6), Monochrome::Zero); + assert_eq!(canvas.get(7), Monochrome::One); } diff --git a/lib/meggl/src/vertex.rs b/lib/meggl/src/vertex.rs deleted file mode 100644 index 2067d42ec..000000000 --- a/lib/meggl/src/vertex.rs +++ /dev/null @@ -1,431 +0,0 @@ -use crate::{Movement, Point}; - -pub type FloatType = f64; -use core::{ - f64::consts::{FRAC_PI_2, PI, TAU}, - ops::{Add, Div, Mul, Sub}, -}; - -#[inline] -fn cos(radian: Radian) -> FloatType { - libm::cos(radian.radian()) -} - -#[inline] -fn sin(radian: Radian) -> FloatType { - libm::sin(radian.radian()) -} - -#[repr(C)] -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct Vertex2d { - pub x: FloatType, - pub y: FloatType, -} - -#[repr(C)] -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct Vertex3d { - pub x: FloatType, - pub y: FloatType, - pub z: FloatType, -} - -#[repr(C)] -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct Vertex4d { - pub x: FloatType, - pub y: FloatType, - pub z: FloatType, - pub w: FloatType, -} - -impl Vertex2d { - #[inline] - pub const fn new(x: FloatType, y: FloatType) -> Self { - Self { x, y } - } - - #[inline] - pub const fn from_point(value: Point) -> Self { - Self { - x: value.x as FloatType, - y: value.y as FloatType, - } - } - - #[inline] - pub fn into_point(self) -> Point { - Point { - x: libm::round(self.x) as isize, - y: libm::round(self.y) as isize, - } - } - - #[inline] - pub fn transformed(&self, affine_matrix: &AffineMatrix2d) -> Self { - affine_matrix.transformed(*self) - } -} - -impl Transform for Vertex2d { - #[inline] - fn transform(&mut self, affine_matrix: &AffineMatrix2d) { - *self = self.transformed(affine_matrix) - } -} - -impl Transform for [Vertex2d] { - #[inline] - fn transform(&mut self, affine_matrix: &AffineMatrix2d) { - for vertex in self.iter_mut() { - vertex.transform(affine_matrix); - } - } -} - -impl const From for Vertex2d { - #[inline] - fn from(value: Point) -> Self { - Vertex2d::from_point(value) - } -} - -impl From for Point { - #[inline] - fn from(value: Vertex2d) -> Self { - value.into_point() - } -} - -impl Vertex3d { - #[inline] - pub const fn new(x: FloatType, y: FloatType, z: FloatType) -> Self { - Self { x, y, z } - } -} - -impl Vertex4d { - #[inline] - pub const fn new(x: FloatType, y: FloatType, z: FloatType, w: FloatType) -> Self { - Self { x, y, z, w } - } -} - -#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] -pub struct Radian(FloatType); - -impl Radian { - /// 0.0 = 0 degrees - pub const ZERO: Self = Self(0.0); - /// π/2 = 90 degrees - pub const FRAC_PI_2: Self = Self(FRAC_PI_2); - /// π = 180 degrees - pub const PI: Self = Self(PI); - /// τ (2π) = 360 degrees - pub const TAU: Self = Self(TAU); - - #[inline] - pub const fn new(radian: FloatType) -> Self { - Self(radian) - } - - #[inline] - pub const fn radian(&self) -> FloatType { - self.0 - } -} - -impl Add for Radian { - type Output = Self; - - #[inline] - fn add(self, rhs: Radian) -> Self::Output { - Self(self.0 + rhs.0) - } -} - -impl Add for Radian { - type Output = Self; - - #[inline] - fn add(self, rhs: FloatType) -> Self::Output { - Self(self.0 + rhs) - } -} - -impl Sub for Radian { - type Output = Self; - - #[inline] - fn sub(self, rhs: FloatType) -> Self::Output { - Self(self.0 - rhs) - } -} - -impl Sub for Radian { - type Output = Self; - - #[inline] - fn sub(self, rhs: Radian) -> Self::Output { - Self(self.0 - rhs.0) - } -} - -impl Mul for Radian { - type Output = Self; - - #[inline] - fn mul(self, rhs: FloatType) -> Self::Output { - Self(self.0 * rhs) - } -} - -impl Div for Radian { - type Output = Self; - - #[inline] - fn div(self, rhs: FloatType) -> Self::Output { - Self(self.0 / rhs) - } -} - -pub trait AffineMatrix {} - -pub trait Transform { - fn transform(&mut self, affine_matrix: &T); -} - -/// Affine Transformation -/// -/// ```plain -/// (x') (m11 m12 m13) (x) -/// (y') = (m21 m22 m23) (y) -/// (1) ( 0 0 1) (1) <- redundant -/// ``` -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct AffineMatrix2d { - pub m11: FloatType, - pub m12: FloatType, - pub m13: FloatType, - pub m21: FloatType, - pub m22: FloatType, - pub m23: FloatType, -} - -impl AffineMatrix2d { - #[inline] - pub fn new(translation: Movement, rotation: Radian, scale: FloatType) -> Self { - Self { - m11: cos(rotation) * scale, - m12: 0.0 - libm::sin(rotation.radian()) * scale, - m13: translation.x as FloatType, - m21: sin(rotation) * scale, - m22: cos(rotation) * scale, - m23: translation.y as FloatType, - } - } - - #[inline] - pub fn transformed(&self, vertex: Vertex2d) -> Vertex2d { - let x1 = vertex.x; - let y1 = vertex.y; - Vertex2d::new( - self.m11 * x1 + self.m12 * y1 + self.m13, - self.m21 * x1 + self.m22 * y1 + self.m23, - ) - } - - #[inline] - pub fn translation(translation: Movement) -> Self { - Self { - m11: 0.0, - m12: 0.0, - m13: translation.x as FloatType, - m21: 0.0, - m22: 0.0, - m23: translation.y as FloatType, - } - } - - #[inline] - pub fn rotation(rotation: Radian) -> Self { - Self { - m11: cos(rotation), - m12: 0.0 - sin(rotation), - m13: 0.0, - m21: sin(rotation), - m22: cos(rotation), - m23: 0.0, - } - } - - #[inline] - pub fn scaling(scale: FloatType) -> Self { - Self { - m11: scale, - m12: 0.0, - m13: 0.0, - m21: 0.0, - m22: scale, - m23: 0.0, - } - } -} - -impl AffineMatrix for AffineMatrix2d {} - -impl Mul for AffineMatrix2d { - type Output = Self; - - fn mul(self, rhs: AffineMatrix2d) -> Self::Output { - Self { - m11: self.m11 * rhs.m11 + self.m12 * rhs.m21, - m12: self.m11 * rhs.m12 + self.m12 * rhs.m22, - m13: self.m11 * rhs.m13 + self.m12 * rhs.m23 + self.m13, - m21: self.m21 * rhs.m11 + self.m22 * rhs.m21, - m22: self.m21 * rhs.m12 + self.m22 * rhs.m22, - m23: self.m21 * rhs.m13 + self.m22 * rhs.m23 + self.m23, - } - } -} - -/// 3D Affine Transformation -/// -/// ```plain -/// (x') (m11 m12 m13 m14) (x) -/// (y') = (m21 m22 m23 m24) (y) -/// (z') = (m31 m32 m33 m34) (z) -/// (1) ( 0 0 0 1) (1) <- redundant -/// ``` -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct AffineMatrix3d { - pub m11: FloatType, - pub m12: FloatType, - pub m13: FloatType, - pub m14: FloatType, - pub m21: FloatType, - pub m22: FloatType, - pub m23: FloatType, - pub m24: FloatType, - pub m31: FloatType, - pub m32: FloatType, - pub m33: FloatType, - pub m34: FloatType, -} - -impl AffineMatrix3d { - #[inline] - pub fn transformed(&self, vertex: &Vertex3d) -> Vertex3d { - let x1 = vertex.x; - let y1 = vertex.y; - let z1 = vertex.z; - Vertex3d::new( - self.m11 * x1 + self.m12 * y1 + self.m13 * z1 + self.m14, - self.m21 * x1 + self.m22 * y1 + self.m23 * z1 + self.m24, - self.m31 * x1 + self.m32 * y1 + self.m33 * z1 + self.m34, - ) - } - - #[inline] - pub fn x_axis_rotation(radian: Radian) -> Self { - Self { - m11: 1.0, - m12: 0.0, - m13: 0.0, - m14: 0.0, - - m21: 0.0, - m22: cos(radian), - m23: -sin(radian), - m24: 0.0, - - m31: 0.0, - m32: sin(radian), - m33: cos(radian), - m34: 0.0, - } - } - - #[inline] - pub fn y_axis_rotation(radian: Radian) -> Self { - Self { - m11: cos(radian), - m12: 0.0, - m13: sin(radian), - m14: 0.0, - - m21: 0.0, - m22: 1.0, - m23: 0.0, - m24: 0.0, - - m31: -sin(radian), - m32: 0.0, - m33: cos(radian), - m34: 0.0, - } - } - - #[inline] - pub fn z_axis_rotation(radian: Radian) -> Self { - Self { - m11: cos(radian), - m12: -sin(radian), - m13: 0.0, - m14: 0.0, - - m21: sin(radian), - m22: cos(radian), - m23: 0.0, - m24: 0.0, - - m31: 0.0, - m32: 0.0, - m33: 1.0, - m34: 0.0, - } - } - - #[inline] - pub fn translation(x: FloatType, y: FloatType, z: FloatType) -> Self { - Self { - m11: 0.0, - m12: 0.0, - m13: 0.0, - m14: x, - - m21: 0.0, - m22: 0.0, - m23: 0.0, - m24: y, - - m31: 0.0, - m32: 0.0, - m33: 0.0, - m34: z, - } - } - - #[inline] - pub fn scaling(scale: FloatType) -> Self { - Self { - m11: scale, - m12: 0.0, - m13: 0.0, - m14: 0.0, - - m21: 0.0, - m22: scale, - m23: 0.0, - m24: 0.0, - - m31: 0.0, - m32: 0.0, - m33: scale, - m34: 0.0, - } - } -} - -impl AffineMatrix for AffineMatrix3d {} diff --git a/lib/megstd/src/sys/kernel/fs_imp.rs b/lib/megstd/src/sys/kernel/fs_imp.rs index 3a526c90d..15b5b7623 100644 --- a/lib/megstd/src/sys/kernel/fs_imp.rs +++ b/lib/megstd/src/sys/kernel/fs_imp.rs @@ -26,7 +26,7 @@ impl File { } bitflags! { - #[derive(Clone, Copy)] + // #[derive(Clone, Copy)] pub struct OpenOptions: u32 { const READ = 0b0000_0001; const WRITE = 0b0000_0010; diff --git a/lib/megstd/src/sys/wasm/prelude.rs b/lib/megstd/src/sys/wasm/prelude.rs index 96a1c9ccf..8be62899b 100644 --- a/lib/megstd/src/sys/wasm/prelude.rs +++ b/lib/megstd/src/sys/wasm/prelude.rs @@ -1,24 +1,19 @@ use crate::sys::syscall::*; -pub use core::fmt; #[macro_export] macro_rules! print { - ($($arg:tt)*) => { - { - use core::fmt::Write; - let _ = write!(OsPrint(), $($arg)*); - } - }; + ($($arg:tt)*) => {{ + use core::fmt::Write; + write!(OsPrint(), $($arg)*).unwrap(); + }}; } #[macro_export] macro_rules! println { - ($fmt:expr) => { - print!(concat!($fmt, "\r\n")) - }; - ($fmt:expr, $($arg:tt)*) => { - print!(concat!($fmt, "\r\n"), $($arg)*) - }; + ($($arg:tt)*) => {{ + use core::fmt::Write; + writeln!(OsPrint(), $($arg)*).unwrap(); + }}; } #[cfg(not(test))] @@ -30,7 +25,7 @@ fn panic(_info: &core::panic::PanicInfo) -> ! { pub struct OsPrint(); -impl fmt::Write for OsPrint { +impl core::fmt::Write for OsPrint { #[inline] fn write_str(&mut self, s: &str) -> core::fmt::Result { os_print(s); diff --git a/lib/myacpi/src/madt.rs b/lib/myacpi/src/madt.rs index 4d1b69488..df90a6cec 100644 --- a/lib/myacpi/src/madt.rs +++ b/lib/myacpi/src/madt.rs @@ -213,6 +213,11 @@ impl LocalApic { self.apic_id } + #[inline] + pub const fn flags(&self) -> u32 { + self.flags + } + #[inline] pub const fn status(&self) -> ApicStatus { unsafe { transmute(self.flags & 0x0000_0003) } diff --git a/system/Cargo.lock b/system/Cargo.lock index b22ed8798..b17f50433 100644 --- a/system/Cargo.lock +++ b/system/Cargo.lock @@ -42,9 +42,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.0.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487f1e0fcbe47deb8b0574e646def1c903389d95241dd1bbcc6ce4a715dfc0c1" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" [[package]] name = "bootprot" @@ -123,6 +123,7 @@ dependencies = [ "rapid-qoi", "seq-macro", "wasm", + "zune-jpeg", ] [[package]] @@ -131,6 +132,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" +[[package]] +name = "log" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" + [[package]] name = "meggl" version = "0.1.0" @@ -145,7 +152,7 @@ dependencies = [ name = "megstd" version = "0.1.0" dependencies = [ - "bitflags 2.0.2", + "bitflags 1.3.2", "cfg-if", "meggl", "num-derive 0.3.3", @@ -352,3 +359,22 @@ dependencies = [ "num-derive 0.2.5", "num-traits", ] + +[[package]] +name = "zune-core" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ca36c2e02af0d8d7ee977542bfe33ed1c516be73d3c1faa4420af46e96ceee" +dependencies = [ + "bitflags 2.3.3", +] + +[[package]] +name = "zune-jpeg" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2848e8f4f29dbdcc79910ab3abdff22bb0bacef8556f2a983b5ca950d8b4991e" +dependencies = [ + "log", + "zune-core", +] diff --git a/system/Cargo.toml b/system/Cargo.toml index 4e73b3ade..7c170120e 100644 --- a/system/Cargo.toml +++ b/system/Cargo.toml @@ -28,6 +28,7 @@ libm = {} png-decoder = {default-features = false, git = "https://github.com/neri/png-decoder"} rapid-qoi = {default-features = false, features = ["alloc"]} +zune-jpeg = {version = "0.3.17", default-features = false} [profile.release] lto = true diff --git a/system/src/arch/x64/apic.rs b/system/src/arch/x64/apic.rs index 914d9b18e..690cb64d0 100644 --- a/system/src/arch/x64/apic.rs +++ b/system/src/arch/x64/apic.rs @@ -24,7 +24,7 @@ pub type AffinityBits = usize; pub type AtomicAffinityBits = AtomicUsize; /// Maximum number of supported cpu cores -const MAX_CPU: usize = size_of::(); +const MAX_CPU: usize = 8 * size_of::(); const STACK_CHUNK_SIZE: usize = 0x4000; @@ -70,6 +70,7 @@ unsafe extern "C" fn apic_start_ap() { Hal::cpu().enable_interrupt(); loop { + // assert!(Hal::cpu().is_interrupt_enabled()); Hal::cpu().wait_for_interrupt(); } } @@ -221,15 +222,7 @@ impl Apic { prepare_sipi(max_cpu, idle_stacks.as_ptr(), apic_start_ap); // start Application Processors - for (_index, lapic) in lapics.iter().enumerate() { - // log!( - // "CPU #{} {:02x} {:02x} {:?}", - // _index, - // cpu.uid(), - // cpu.apic_id(), - // cpu.status(), - // ); - + for lapic in lapics.iter().take(max_cpu) { let apic_id = ApicId(lapic.apic_id()); LocalApic::send_init_ipi(apic_id); Timer::new(Duration::from_millis(10)).repeat_until(|| Hal::cpu().wait_for_interrupt()); @@ -244,11 +237,10 @@ impl Apic { if !AP_BOOT_OK.load(Ordering::SeqCst) { panic!("SMP: Some application processors are not responding"); } - - // log!("CPU #{} OK", index,); } drop(idle_stacks); + // core::mem::forget(idle_stacks); for (index, cpu) in System::cpus().enumerate() { CURRENT_PROCESSOR_INDEXES[cpu.apic_id().0 as usize] = index as u8; @@ -346,6 +338,7 @@ impl Apic { let global_irq = msi.as_irq(); shared.idt[global_irq.0 as usize] = f as usize; shared.idt_params[global_irq.0 as usize] = arg; + fence(Ordering::SeqCst); let vec = msi.as_vec(); let addr = Self::MSI_BASE; let data = Self::MSI_DATA | vec.0 as u16; diff --git a/system/src/arch/x64/cpu.rs b/system/src/arch/x64/cpu.rs index 5c6098b62..74337747b 100644 --- a/system/src/arch/x64/cpu.rs +++ b/system/src/arch/x64/cpu.rs @@ -35,6 +35,7 @@ struct SharedCpu { max_cpuid_level_8: u32, smt_topology: u32, has_smt: AtomicBool, + is_hybrid: AtomicBool, max_physical_address_bits: usize, max_virtual_address_bits: usize, vram_base: PhysicalAddress, @@ -48,6 +49,7 @@ impl SharedCpu { max_cpuid_level_8: 0, smt_topology: 0, has_smt: AtomicBool::new(false), + is_hybrid: AtomicBool::new(false), max_physical_address_bits: 36, max_virtual_address_bits: 48, vram_base: PhysicalAddress::new(0), @@ -70,15 +72,20 @@ impl Cpu { shared.max_cpuid_level_0 = __cpuid_count(0, 0).eax; shared.max_cpuid_level_8 = __cpuid_count(0x8000_0000, 0).eax; - if shared.max_cpuid_level_0 >= 0x1F { - let cpuid1f = __cpuid_count(0x1F, 0); - if (cpuid1f.ecx & 0xFF00) == 0x0100 { - shared.smt_topology = (1 << (cpuid1f.eax & 0x1F)) - 1; + if shared.max_cpuid_level_0 >= 0x0B { + if Feature::F07D(F070D::HYBRID).has_feature() { + shared.is_hybrid.store(true, Ordering::SeqCst); } - } else if shared.max_cpuid_level_0 >= 0x0B { - let cpuid0b = __cpuid_count(0x0B, 0); - if (cpuid0b.ecx & 0xFF00) == 0x0100 { - shared.smt_topology = (1 << (cpuid0b.eax & 0x1F)) - 1; + if shared.max_cpuid_level_0 >= 0x1F { + let cpuid1f = __cpuid_count(0x1F, 0); + if (cpuid1f.ecx & 0xFF00) == 0x0100 { + shared.smt_topology = (1 << (cpuid1f.eax & 0x1F)) - 1; + } + } else { + let cpuid0b = __cpuid_count(0x0B, 0); + if (cpuid0b.ecx & 0xFF00) == 0x0100 { + shared.smt_topology = (1 << (cpuid0b.eax & 0x1F)) - 1; + } } } @@ -101,14 +108,19 @@ impl Cpu { let gdt = GlobalDescriptorTable::new(); InterruptDescriptorTable::load(); - let core_type = if (apic_id.as_u32() & Self::shared().smt_topology) == 0 { - ProcessorCoreType::Main + let shared = &*SHARED_CPU.get(); + + let is_normal = if (apic_id.as_u32() & Self::shared().smt_topology) == 0 { + true } else { Self::shared().has_smt.store(true, Ordering::SeqCst); - ProcessorCoreType::Sub + false }; - - let shared = &*SHARED_CPU.get(); + let is_efficient = matches!( + Cpu::native_model_core_type().unwrap_or(NativeModelCoreType::Performance), + NativeModelCoreType::Efficient + ); + let core_type = ProcessorCoreType::new(is_normal, is_efficient); let mtrr_items = Mtrr::items().filter(|v| v.is_enabled).collect::>(); let mut mtrr_new = Vec::new(); @@ -214,6 +226,22 @@ impl Cpu { unsafe { &*SHARED_CPU.get() } } + #[inline] + pub fn is_hybrid() -> bool { + let shared = Self::shared(); + shared.is_hybrid.load(Ordering::Relaxed) + } + + #[inline] + pub fn native_model_core_type() -> Option { + if Self::is_hybrid() { + let cpuid_1a = unsafe { __cpuid_count(0x1A, 0) }; + NativeModelCoreType::from_u8((cpuid_1a.eax >> 24) as u8) + } else { + None + } + } + #[inline] pub fn physical_address_mask() -> u64 { let shared = Self::shared(); @@ -1547,7 +1575,7 @@ pub enum F01C { HYPERVISOR = 31, } -/// CPUID Feature Function 0000_0007, EBX +/// CPUID Feature Function 0000_0007, 0, EBX #[allow(non_camel_case_types)] #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum F070B { @@ -1585,7 +1613,7 @@ pub enum F070B { AVX512_VL = 31, } -/// CPUID Feature Function 0000_0007, ECX +/// CPUID Feature Function 0000_0007, 0, ECX #[allow(non_camel_case_types)] #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum F070C { @@ -1613,7 +1641,7 @@ pub enum F070C { PKS = 31, } -/// CPUID Feature Function 0000_0007, EDX +/// CPUID Feature Function 0000_0007, 0, EDX #[allow(non_camel_case_types)] #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum F070D { @@ -1683,6 +1711,27 @@ pub enum F81C { PCX_L2I = 28, } +#[non_exhaustive] +#[derive(Debug, Clone, Copy)] +pub enum NativeModelCoreType { + Performance, + Efficient, +} + +impl NativeModelCoreType { + const CORE_TYPE_ATOM: u8 = 0x20; + const CORE_TYPE_CORE: u8 = 0x40; + + #[inline] + pub const fn from_u8(value: u8) -> Option { + match value { + Self::CORE_TYPE_ATOM => Some(Self::Efficient), + Self::CORE_TYPE_CORE => Some(Self::Performance), + _ => None, + } + } +} + #[repr(transparent)] #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct MSR(u32); @@ -1701,6 +1750,11 @@ impl MSR { pub const IA32_SYSENTER_EIP: Self = Self(0x0000_0176); pub const IA32_PAT: Self = Self(0x0000_0277); pub const IA32_MTRR_DEF_TYPE: Self = Self(0x0000_02FF); + pub const IA32_HW_FEEDBACK_PTR: Self = Self(0x0000_17D0); + pub const IA32_HW_FEEDBACK_CONFIG: Self = Self(0x0000_17D1); + pub const IA32_THREAD_FEEDBACK_CHAR: Self = Self(0x0000_17D2); + pub const IA32_HW_FEEDBACK_THREAD_CONFIG: Self = Self(0x0000_17D4); + pub const IA32_EFER: Self = Self(0xC000_0080); pub const IA32_STAR: Self = Self(0xC000_0081); pub const IA32_LSTAR: Self = Self(0xC000_0082); diff --git a/system/src/arch/x64/page.rs b/system/src/arch/x64/page.rs index c5b2536dc..564364742 100644 --- a/system/src/arch/x64/page.rs +++ b/system/src/arch/x64/page.rs @@ -68,13 +68,12 @@ impl PageManager { match request { MemoryMapRequest::Mmio(base, len) => { let Some(len) = NonZeroUsize::new(len) else { return 0 }; - let pa = base as PhysicalAddress; let va = Self::direct_map(base); match Self::_map( va, len, PageTableEntry::new( - pa, + base, PageAttribute::NO_EXECUTE | PageAttribute::PAT_UC | PageAttribute::WRITE @@ -87,13 +86,12 @@ impl PageManager { } MemoryMapRequest::Framebuffer(base, len) => { let Some(len) = NonZeroUsize::new(len) else { return 0 }; - let pa = base as PhysicalAddress; let va = Self::direct_map(base); match Self::_map( va, len, PageTableEntry::new( - pa, + base, PageAttribute::NO_EXECUTE | PageAttribute::LARGE_2M | PageAttribute::PAT_WC @@ -154,15 +152,15 @@ impl PageManager { #[track_caller] unsafe fn _map(va: usize, len: NonZeroUsize, template: PageTableEntry) -> Result<(), usize> { if template.contains(PageAttribute::LARGE_2M) { + // 2M Pages let page_size = Self::PAGE_SIZE_2M; let page_mask = page_size - 1; - // 2M Pages if (va & page_mask) != 0 { return Err(va); } let count = (len.get() + page_mask) / page_size; let mut template = template; - let fva = va; + let base_va = va; let mut va = va; for _ in 0..count { let mut parent_template = template; @@ -177,24 +175,25 @@ impl PageManager { { panic!( "INVALID PDT {:016x} {:016x} {:016x} {}", - va, pdte.0, fva, count + va, pdte.0, base_va, count ); } pdte_ptr.write_volatile(template); + Self::invalidate_tlb(va); va += page_size; template += page_size; } } else { + // 4K Pages let page_size = Self::PAGE_SIZE_4K; let page_mask = page_size - 1; - // 4K Pages if (va & page_mask) != 0 { return Err(va); } let count = (len.get() + page_mask) / page_size; let mut template = template; - let fva = va; + let base_va = va; let mut va = va; for _ in 0..count { let mut parent_template = template; @@ -207,12 +206,13 @@ impl PageManager { if pdte.contains(PageAttribute::LARGE_2M) { panic!( "LARGE PDT {:016x} {:016x} {:016x} {}", - va, pdte.0, fva, count + va, pdte.0, base_va, count ); } let pte_ptr = PageLevel::Level1.pte_of(va); pte_ptr.write_volatile(template); + Self::invalidate_tlb(va); va += page_size; template += page_size; diff --git a/system/src/drivers/hda/hdaudio.rs b/system/src/drivers/hda/hdaudio.rs index a50647a77..f46d22900 100644 --- a/system/src/drivers/hda/hdaudio.rs +++ b/system/src/drivers/hda/hdaudio.rs @@ -1,7 +1,10 @@ use crate::{ drivers::pci::*, io::audio::{AudioDriver, AudioManager}, - mem::{mmio::MmioSlice, MemoryManager}, + mem::{ + mmio::{MmioRegU16, MmioRegU32, MmioRegU8, MmioSlice}, + MemoryManager, + }, sync::{semaphore::Semaphore, Mutex}, task::scheduler::{Priority, SpawnOption, Timer}, *, @@ -13,7 +16,7 @@ use core::{ num::{NonZeroU8, NonZeroUsize}, ops::Add, slice, - sync::atomic::{fence, AtomicU16, AtomicU32, AtomicU8, AtomicUsize, Ordering}, + sync::atomic::{fence, AtomicUsize, Ordering}, time::Duration, }; @@ -219,7 +222,7 @@ impl HdAudioController { cmd.set_pcm_format(dac, stream_format).unwrap(); cmd.set_stream_id(dac, stream_id).unwrap(); - driver.global.ssync.store(1, Ordering::SeqCst); + driver.global.ssync.write_volatile(1); sd.run(); } else { @@ -246,6 +249,7 @@ impl HdAudioController { config.default_device(), ); } + panic!("todo"); } let driver = Arc::new(driver); @@ -361,16 +365,37 @@ impl HdAudioController { if self.output_pins.len() < 2 { self.output_pins.first().map(|v| *v) } else { - for &pin in &self.output_pins { - let widget = self.widgets.get(&pin).unwrap(); - let config = widget.configuration_default(); - if config.sequence() == 0 - && config.default_device() == DefaultDevice::Speaker - && config.port_connectivity() != PortConnectivity::NoPhysicalConnection - { - return Some(pin); + for device in [ + DefaultDevice::HPOut, + DefaultDevice::LineOut, + DefaultDevice::Speaker, + ] { + for &pin in &self.output_pins { + let widget = self.widgets.get(&pin).unwrap(); + let config = widget.configuration_default(); + if config.sequence() == 0 + && config.port_connectivity() != PortConnectivity::NoPhysicalConnection + && config.default_device() == device + { + return Some(pin); + } + } + } + + for device in [ + DefaultDevice::HPOut, + DefaultDevice::LineOut, + DefaultDevice::DigitalOtherOut, + ] { + for &pin in &self.output_pins { + let widget = self.widgets.get(&pin).unwrap(); + let config = widget.configuration_default(); + if config.sequence() == 0 && config.default_device() == device { + return Some(pin); + } } } + None } } @@ -1005,113 +1030,113 @@ impl> Add for Nid { #[repr(C)] #[allow(dead_code)] pub struct GlobalRegisterSet { - gcap: AtomicU16, - vmin: AtomicU8, - vmaj: AtomicU8, - outpay: AtomicU16, - inpay: AtomicU16, - gctl: AtomicU32, - wakeen: AtomicU16, - statests: AtomicU16, - gsts: AtomicU16, + gcap: MmioRegU16, + vmin: MmioRegU8, + vmaj: MmioRegU8, + outpay: MmioRegU16, + inpay: MmioRegU16, + gctl: MmioRegU32, + wakeen: MmioRegU16, + statests: MmioRegU16, + gsts: MmioRegU16, _rsrv_12_17: [u8; 6], - outstrmpay: AtomicU16, - instrmpay: AtomicU16, + outstrmpay: MmioRegU16, + instrmpay: MmioRegU16, _rsrv_1c_1f: [u8; 4], - intcnt: AtomicU32, - intsts: AtomicU32, + intcnt: MmioRegU32, + intsts: MmioRegU32, _rsrc_28_2f: [u8; 8], - counter: AtomicU32, - ssync: AtomicU32, + counter: MmioRegU32, + ssync: MmioRegU32, } impl GlobalRegisterSet { #[inline] pub fn capabilities(&self) -> GlobalCapabilities { - self.gcap.load(Ordering::Relaxed).into() + self.gcap.read_volatile().into() } #[inline] pub fn version(&self) -> (usize, usize) { ( - self.vmaj.load(Ordering::Relaxed) as usize, - self.vmin.load(Ordering::Relaxed) as usize, + self.vmaj.read_volatile() as usize, + self.vmin.read_volatile() as usize, ) } #[inline] pub fn output_payload_capability(&self) -> usize { - self.outpay.load(Ordering::Relaxed) as usize + self.outpay.read_volatile() as usize } #[inline] pub fn input_payload_capability(&self) -> usize { - self.inpay.load(Ordering::Relaxed) as usize + self.inpay.read_volatile() as usize } #[inline] pub fn get_control(&self) -> GlobalControl { - GlobalControl::from_bits_retain(self.gctl.load(Ordering::SeqCst)) + GlobalControl::from_bits_retain(self.gctl.read_volatile()) } #[inline] pub fn set_control(&self, val: GlobalControl) { - self.gctl.store(val.bits(), Ordering::SeqCst); + self.gctl.write_volatile(val.bits()); } #[inline] pub fn get_wake_enable(&self) -> u16 { - self.wakeen.load(Ordering::SeqCst) + self.wakeen.read_volatile() } #[inline] pub fn set_wake_enable(&self, val: u16) { - self.wakeen.store(val, Ordering::SeqCst); + self.wakeen.write_volatile(val); } #[inline] pub fn get_state_change_status(&self) -> u16 { - self.statests.load(Ordering::SeqCst) + self.statests.read_volatile() } #[inline] pub fn set_state_change_status(&self, val: u16) { - self.statests.store(val, Ordering::SeqCst); + self.statests.write_volatile(val); } #[inline] pub fn get_status(&self) -> GlobalStatus { - GlobalStatus::from_bits_retain(self.gsts.load(Ordering::SeqCst)) + GlobalStatus::from_bits_retain(self.gsts.read_volatile()) } #[inline] pub fn set_status(&self, val: GlobalStatus) { - self.gsts.store(val.bits(), Ordering::SeqCst); + self.gsts.write_volatile(val.bits()); } #[inline] pub fn output_stream_payload_capability(&self) -> usize { - self.outstrmpay.load(Ordering::Relaxed) as usize + self.outstrmpay.read_volatile() as usize } #[inline] pub fn input_stream_payload_capability(&self) -> usize { - self.instrmpay.load(Ordering::Relaxed) as usize + self.instrmpay.read_volatile() as usize } #[inline] pub fn interrupt_control(&self) -> u32 { - self.intcnt.load(Ordering::SeqCst) + self.intcnt.read_volatile() } #[inline] pub fn set_interrupt_control(&self, val: u32) { - self.intcnt.store(val, Ordering::SeqCst) + self.intcnt.write_volatile(val); } #[inline] pub fn interrupt_status(&self) -> u32 { - self.intsts.load(Ordering::SeqCst) + self.intsts.read_volatile() } } @@ -1170,13 +1195,13 @@ impl From for GlobalCapabilities { #[repr(C)] #[allow(dead_code)] pub struct CorbRegisterSet { - lbase: AtomicU32, - ubase: AtomicU32, - wp: AtomicU16, - rp: AtomicU16, - ctl: AtomicU8, - sts: AtomicU8, - size: AtomicU8, + lbase: MmioRegU32, + ubase: MmioRegU32, + wp: MmioRegU16, + rp: MmioRegU16, + ctl: MmioRegU8, + sts: MmioRegU8, + size: MmioRegU8, } my_bitflags! { @@ -1203,7 +1228,7 @@ impl CorbRegisterSet { self.set_write_pointer(0); - self.rp.store(Self::CORBRPRST, Ordering::SeqCst); + self.rp.write_volatile(Self::CORBRPRST); Timer::sleep(Duration::from_millis(100)); // self.rp.store(0, Ordering::SeqCst); @@ -1225,48 +1250,48 @@ impl CorbRegisterSet { #[inline] pub fn set_base(&self, base: PhysicalAddress) { let base = base.as_u64(); - self.lbase.store(base as u32, Ordering::SeqCst); - self.ubase.store((base >> 32) as u32, Ordering::SeqCst); + self.lbase.write_volatile(base as u32); + self.ubase.write_volatile((base >> 32) as u32); } #[inline] pub fn get_write_pointer(&self) -> usize { - (self.wp.load(Ordering::SeqCst) & 0xFF) as usize + (self.wp.read_volatile() & 0xFF) as usize } #[inline] pub fn set_write_pointer(&self, val: usize) { - self.wp.store((val & 0xFF) as u16, Ordering::SeqCst); + self.wp.write_volatile((val & 0xFF) as u16); } #[inline] pub fn get_read_pointer(&self) -> usize { - (self.rp.load(Ordering::SeqCst) & 0xFF) as usize + (self.rp.read_volatile() & 0xFF) as usize } #[inline] pub fn get_control(&self) -> CorbControl { - CorbControl::from_bits_retain(self.ctl.load(Ordering::SeqCst)) + CorbControl::from_bits_retain(self.ctl.read_volatile()) } #[inline] pub fn set_control(&self, val: CorbControl) { - self.ctl.store(val.bits(), Ordering::SeqCst); + self.ctl.write_volatile(val.bits()); } #[inline] pub fn get_status(&self) -> CorbStatus { - CorbStatus::from_bits_retain(self.sts.load(Ordering::SeqCst)) + CorbStatus::from_bits_retain(self.sts.read_volatile()) } #[inline] pub fn set_status(&self, val: CorbStatus) { - self.sts.store(val.bits(), Ordering::SeqCst); + self.sts.write_volatile(val.bits()); } #[inline] pub fn entries(&self) -> Option { - match self.size.load(Ordering::Relaxed) & 3 { + match self.size.read_volatile() & 3 { 0 => NonZeroUsize::new(2), 1 => NonZeroUsize::new(16), 2 => NonZeroUsize::new(256), @@ -1278,13 +1303,13 @@ impl CorbRegisterSet { #[repr(C)] #[allow(dead_code)] pub struct RirbRegisterSet { - lbase: AtomicU32, - ubase: AtomicU32, - wp: AtomicU16, - rintcnt: AtomicU16, - ctl: AtomicU8, - sts: AtomicU8, - size: AtomicU8, + lbase: MmioRegU32, + ubase: MmioRegU32, + wp: MmioRegU16, + rintcnt: MmioRegU16, + ctl: MmioRegU8, + sts: MmioRegU8, + size: MmioRegU8, } my_bitflags! { @@ -1330,53 +1355,53 @@ impl RirbRegisterSet { #[inline] pub fn set_base(&self, base: PhysicalAddress) { let base = base.as_u64(); - self.lbase.store(base as u32, Ordering::SeqCst); - self.ubase.store((base >> 32) as u32, Ordering::SeqCst); + self.lbase.write_volatile(base as u32); + self.ubase.write_volatile((base >> 32) as u32); } #[inline] pub fn get_write_pointer(&self) -> usize { - (self.wp.load(Ordering::SeqCst) & 0xFF) as usize + (self.wp.read_volatile() & 0xFF) as usize } #[inline] pub fn reset_write_pointer(&self) { - self.wp.store(Self::RIRBWPRST, Ordering::SeqCst); + self.wp.write_volatile(Self::RIRBWPRST); } #[inline] pub fn get_rintcnt(&self) -> usize { - (self.rintcnt.load(Ordering::SeqCst) & 0xFF) as usize + (self.rintcnt.read_volatile() & 0xFF) as usize } #[inline] pub fn set_rintcnt(&self, val: usize) { - self.rintcnt.store((val & 0xFF) as u16, Ordering::SeqCst); + self.rintcnt.write_volatile((val & 0xFF) as u16); } #[inline] pub fn get_control(&self) -> RirbControl { - RirbControl::from_bits_retain(self.ctl.load(Ordering::SeqCst)) + RirbControl::from_bits_retain(self.ctl.read_volatile()) } #[inline] pub fn set_control(&self, val: RirbControl) { - self.ctl.store(val.bits(), Ordering::SeqCst); + self.ctl.write_volatile(val.bits()); } #[inline] pub fn get_status(&self) -> RirbStatus { - RirbStatus::from_bits_retain(self.sts.load(Ordering::SeqCst)) + RirbStatus::from_bits_retain(self.sts.read_volatile()) } #[inline] pub fn set_status(&self, val: RirbStatus) { - self.sts.store(val.bits(), Ordering::SeqCst); + self.sts.write_volatile(val.bits()); } #[inline] pub fn entries(&self) -> Option { - match self.size.load(Ordering::Relaxed) & 3 { + match self.size.read_volatile() & 3 { 0 => NonZeroUsize::new(2), 1 => NonZeroUsize::new(16), 2 => NonZeroUsize::new(256), @@ -1388,9 +1413,9 @@ impl RirbRegisterSet { #[repr(C)] #[allow(dead_code)] pub struct ImmediateCommandRegisterSet { - ico: AtomicU32, - ici: AtomicU32, - ics: AtomicU16, + ico: MmioRegU32, + ici: MmioRegU32, + ics: MmioRegU16, } impl ImmediateCommandRegisterSet { @@ -1405,7 +1430,7 @@ impl ImmediateCommandRegisterSet { return Err(ControllerError::CommandBusy); } - self.ico.store(cmd.bits(), Ordering::SeqCst); + self.ico.write_volatile(cmd.bits()); self.set_status(ImmediateCommandStatus::ICB); @@ -1418,8 +1443,7 @@ impl ImmediateCommandRegisterSet { return Err(ControllerError::CommandNotResponding); } - let res = self.ici.load(Ordering::SeqCst) as u64 - | ((self.ici.load(Ordering::SeqCst) as u64) << 32); + let res = self.ici.read_volatile() as u64 | ((self.ici.read_volatile() as u64) << 32); self.set_status(ImmediateCommandStatus::IRV); @@ -1428,12 +1452,12 @@ impl ImmediateCommandRegisterSet { #[inline] pub fn get_status(&self) -> ImmediateCommandStatus { - unsafe { transmute(self.ics.load(Ordering::SeqCst)) } + unsafe { transmute(self.ics.read_volatile()) } } #[inline] pub fn set_status(&self, val: ImmediateCommandStatus) { - self.ics.store(val.bits(), Ordering::SeqCst); + self.ics.write_volatile(val.bits()); } } @@ -1455,26 +1479,25 @@ my_bitflags! { #[repr(C)] #[allow(dead_code)] pub struct StreamDescriptorRegisterSet { - ctl_lo: AtomicU16, - ctl_hi: AtomicU8, - sts: AtomicU8, - lpib: AtomicU32, - cbl: AtomicU32, - lvi: AtomicU16, + ctl_lo: MmioRegU16, + ctl_hi: MmioRegU8, + sts: MmioRegU8, + lpib: MmioRegU32, + cbl: MmioRegU32, + lvi: MmioRegU16, _rsrv_8e_8f: [u8; 2], - fifos: AtomicU16, - fmt: AtomicU16, + fifos: MmioRegU16, + fmt: MmioRegU16, _rsrv_94_97: [u8; 4], - bdpl: AtomicU32, - bdpu: AtomicU32, + bdpl: MmioRegU32, + bdpu: MmioRegU32, } impl StreamDescriptorRegisterSet { #[inline] pub fn get_control(&self) -> StreamDescriptorControl { StreamDescriptorControl::from_bits_retain( - self.ctl_lo.load(Ordering::SeqCst) as u32 - | ((self.ctl_hi.load(Ordering::SeqCst) as u32) << 16), + self.ctl_lo.read_volatile() as u32 | ((self.ctl_hi.read_volatile() as u32) << 16), ) } @@ -1487,19 +1510,18 @@ impl StreamDescriptorRegisterSet { #[inline] pub fn set_control(&self, val: StreamDescriptorControl) { - self.ctl_lo.store(val.bits() as u16, Ordering::SeqCst); - self.ctl_hi - .store((val.bits() >> 16) as u8, Ordering::SeqCst); + self.ctl_lo.write_volatile(val.bits() as u16); + self.ctl_hi.write_volatile((val.bits() >> 16) as u8); } #[inline] pub fn get_status(&self) -> StreamDescriptorStatus { - StreamDescriptorStatus::from_bits_retain(self.sts.load(Ordering::SeqCst)) + StreamDescriptorStatus::from_bits_retain(self.sts.read_volatile()) } #[inline] pub fn set_status(&self, val: StreamDescriptorStatus) { - self.sts.store(val.bits(), Ordering::SeqCst); + self.sts.write_volatile(val.bits()); } #[inline] @@ -1509,49 +1531,49 @@ impl StreamDescriptorRegisterSet { #[inline] pub fn link_position(&self) -> usize { - self.lpib.load(Ordering::SeqCst) as usize + self.lpib.read_volatile() as usize } #[inline] pub fn get_buffer_length(&self) -> usize { - self.cbl.load(Ordering::SeqCst) as usize + self.cbl.read_volatile() as usize } #[inline] pub fn set_buffer_length(&self, val: usize) { - self.cbl.store(val as u32, Ordering::SeqCst); + self.cbl.write_volatile(val as u32); } #[inline] pub fn get_last_valid_index(&self) -> usize { - self.lvi.load(Ordering::SeqCst) as usize + self.lvi.read_volatile() as usize } #[inline] pub fn set_last_valid_index(&self, val: usize) { - self.lvi.store(val as u16, Ordering::SeqCst); + self.lvi.write_volatile(val as u16); } #[inline] pub fn fifo_size(&self) -> usize { - self.fifos.load(Ordering::Relaxed) as usize + self.fifos.read_volatile() as usize } #[inline] pub fn set_pcm_format(&self, fmt: PcmFormat) { - self.fmt.store(fmt.bits(), Ordering::SeqCst); + self.fmt.write_volatile(fmt.bits()); } #[inline] pub fn get_format(&self) -> PcmFormat { - PcmFormat::from_bits(self.fmt.load(Ordering::SeqCst)) + PcmFormat::from_bits(self.fmt.read_volatile()) } #[inline] pub fn set_base(&self, base: PhysicalAddress) { let base = base.as_u64(); - self.bdpl.store(base as u32, Ordering::SeqCst); - self.bdpu.store((base >> 32) as u32, Ordering::SeqCst); + self.bdpl.write_volatile(base as u32); + self.bdpu.write_volatile((base >> 32) as u32); } } diff --git a/system/src/drivers/pci/pci.rs b/system/src/drivers/pci/pci.rs index 90b8bb6a7..67a04e45b 100644 --- a/system/src/drivers/pci/pci.rs +++ b/system/src/drivers/pci/pci.rs @@ -141,7 +141,6 @@ impl Pci { for registrar in &shared.registrars { match registrar.instantiate(&device) { Some(v) => { - // log!("PCI INIT {:?}", device.address()); shared.drivers.write().unwrap().insert(device.address(), v); } None => {} @@ -417,6 +416,14 @@ impl PciDevice { Hal::pci().write_pci(base + 3, msi_data as u32); Hal::pci().write_pci(base, (Hal::pci().read_pci(base) & 0xFF8FFFFF) | 0x00010000); + // log!( + // "MSI {:08x} {:04x} {:016x} {:016x}", + // msi_addr, + // msi_data, + // f as usize, + // arg + // ); + Ok(()) } diff --git a/system/src/drivers/usb/drivers/usb_hid.rs b/system/src/drivers/usb/drivers/usb_hid.rs index 561a5b43d..7300c57b3 100644 --- a/system/src/drivers/usb/drivers/usb_hid.rs +++ b/system/src/drivers/usb/drivers/usb_hid.rs @@ -49,15 +49,15 @@ impl UsbHidDriver { class: UsbClass, ) -> Result { let Some(interface) = device -.device() -.current_configuration() -.find_interface(if_no, None) -else { -return Err(UsbError::InvalidParameter) -}; + .device() + .current_configuration() + .find_interface(if_no, None) + else { + return Err(UsbError::InvalidParameter) + }; let Some(endpoint) = interface.endpoints().first() else { -return Err(UsbError::InvalidDescriptor) -}; + return Err(UsbError::InvalidDescriptor) + }; if !endpoint.is_dir_in() { return Err(UsbError::InvalidDescriptor); } @@ -131,8 +131,10 @@ return Err(UsbError::InvalidDescriptor) .chain(report_desc.applications()) { let mut data = Vec::new(); - data.resize((app.bit_count_for_feature() + 7) / 8, 0); - let empty_data = [0; Self::BUFFER_LEN]; + data.resize( + (app.bit_count_for_feature().max(app.bit_count_for_output()) + 7) / 8, + 0, + ); let mut writer = HidBitStreamWriter::new(data.as_mut_slice()); match app.usage() { HidUsage::KEYBOARD => { @@ -151,57 +153,66 @@ return Err(UsbError::InvalidDescriptor) } } - let _ = Self::set_report( + match Self::set_report( &device, if_no, HidReportType::Output, app.report_id(), len, - &data, + writer.data(), ) - .await; + .await + { + Ok(_) => (), + Err(_) => break, + } Timer::sleep_async(Duration::from_millis(100)).await; + writer.clear(); + let _ = Self::set_report( &device, if_no, HidReportType::Output, app.report_id(), len, - &empty_data, + writer.data(), ) - .await; + .await + .unwrap(); Timer::sleep_async(Duration::from_millis(50)).await; } } + // HidUsage::DEVICE_CONFIGURATION => { // let len = (app.bit_count_for_feature() + 7) / 8; - // if len > 0 { - // for item in app.features() { - // match item.usage_min() { - // HidUsage::DEVICE_MODE => { - // let _ = writer - // .write_item(item, DeviceMode::SingleInputDevice as u32); - // } - // HidUsage::SURFACE_SWITCH | HidUsage::BUTTON_SWITCH => { - // let _ = writer.write_item(item, 1); - // } - // _ => { - // writer.advance_by(item); - // } + // if len > 0 { + // for item in app.feature_items() { + // match item.usage_min() { + // HidUsage::DEVICE_MODE => { + // let _ = writer + // .write_item(item, DeviceMode::MultiInputDevice as u32); + // } + // // HidUsage::SURFACE_SWITCH | HidUsage::BUTTON_SWITCH => { + // // let _ = writer.write_item(item, 1); + // // } + // _ => { + // writer.advance_by(item); // } // } - - // let _ = Self::set_report( - // &device, - // if_no, - // HidReportType::Feature, - // app.report_id(), - // len, - // data.as_slice(), - // ) - // .await; // } + + // let _ = Self::set_report( + // &device, + // if_no, + // HidReportType::Feature, + // app.report_id(), + // len, + // data.as_slice(), + // ) + // .await + // .unwrap(); + // } // } _ => (), } @@ -213,7 +224,7 @@ return Err(UsbError::InvalidDescriptor) loop { match device.read_vec(ep, &mut buffer, 1, ps).await { Ok(_) => { - // if report_desc.has_report_id() && buffer.iter().fold(0, |a, b| a | *b) > 0 { + // if report_desc.has_report_id() && buffer.iter().fold(0, |a, b| a | *b) != 0 { // println!("HID {:?}", HexDump(&buffer)); // } @@ -227,7 +238,9 @@ return Err(UsbError::InvalidDescriptor) }; let Some(app) = app else { continue }; - if buffer.len() * 8 < app.bit_count_for_input() { + if buffer.len() * 8 + < report_desc.initial_bit_position() + app.bit_count_for_input() + { // Some devices send smaller garbage data continue; } diff --git a/system/src/drivers/usb/xhci/xhci.rs b/system/src/drivers/usb/xhci/xhci.rs index a72f1c8c5..85a59e4fc 100644 --- a/system/src/drivers/usb/xhci/xhci.rs +++ b/system/src/drivers/usb/xhci/xhci.rs @@ -135,6 +135,17 @@ impl Xhci { .unwrap() .get() as PhysicalAddress; + // log!( + // "XHCI {}.{}.{} PORTS {} SLOTS {} CTX {} INT {}", + // cap.version().0, + // cap.version().1, + // cap.version().2, + // cap.max_ports(), + // cap.max_device_slots(), + // context_size, + // cap.max_interrups(), + // ); + let driver = Arc::new(Self { addr: device.address(), mmio, @@ -188,6 +199,7 @@ impl Xhci { let mut xecp_base = xecp.get() as *mut u32; loop { let xecp = xecp_base.read_volatile(); + // log!("XECP {:02x} {:02x}", xecp & 0xFF, (xecp >> 8) & 0xFF); match xecp & 0xFF { 0x01 => { // USB Legacy Support @@ -195,6 +207,11 @@ impl Xhci { const USBLEGSUP_OS_OWNED: u32 = 0x0100_0000; let usb_leg_sup = xecp_base; let usb_leg_ctl_sts = xecp_base.add(1); + // log!( + // "USB leg_sup {:08x} {:08x}", + // usb_leg_sup.read_volatile(), + // usb_leg_ctl_sts.read_volatile() + // ); // Hand over ownership from BIOS to OS usb_leg_sup.write_volatile(xecp | USBLEGSUP_OS_OWNED); @@ -220,6 +237,28 @@ impl Xhci { 0x02 => { // Supported Protocol let ecap = XhciSupportedProtocolCapability(xecp_base); + // let psic = (xecp_base.add(2).read_volatile() >> 28) as usize; + + // let n = ecap.name(); + // let s = unsafe { + // core::str::from_utf8_unchecked(core::slice::from_raw_parts( + // n.as_ptr(), + // 4, + // )) + // }; + // log!( + // "XHCI_ECAP: {} {}.{:02x} {:2},{:2}", + // s, + // ecap.rev_major(), + // ecap.rev_minor(), + // ecap.compatible_port_offset(), + // ecap.compatible_port_count() + // ); + // for i in 0..psic { + // let psi_base = xecp_base.add(4 + i); + // let psi = psi_base.read_volatile(); + // log!("PSI {:08x}", psi); + // } match (ecap.name(), ecap.rev_major(), ecap.rev_minor()) { (XhciSupportedProtocolCapability::NAME_USB, 2, 0) => { @@ -333,10 +372,7 @@ impl Xhci { } pub fn ring_a_doorbell(&self, slot_id: Option, dci: Option) { - self.doorbells - .get(slot_id.map(|v| v.0.get() as usize).unwrap_or_default()) - .unwrap() - .set_target(dci); + self.doorbells[slot_id.map(|v| v.0.get() as usize).unwrap_or_default()].set_target(dci); } pub fn ring_a_doorbell_async( @@ -444,12 +480,9 @@ impl Xhci { } /// wait for CNR (Controller Not Ready) - #[inline] + #[inline(never)] pub fn wait_cnr(&self, _: usize) { - let mut wait = Hal::cpu().spin_wait(); - while self.opr.status().contains(UsbSts::CNR) { - wait.wait(); - } + while self.opr.status().contains(UsbSts::CNR) {} } pub fn ep_ring_index(&self, slot_id: Option, dci: Option) -> Option { @@ -569,6 +602,15 @@ impl Xhci { &self, trb: &Trb, ) -> Result { + // log!( + // "EXEC {:?} {:08x} {:08x} {:08x} {:08x}", + // trb.trb_type(), + // trb.raw_data()[0].load(Ordering::Relaxed), + // trb.raw_data()[1].load(Ordering::Relaxed), + // trb.raw_data()[2].load(Ordering::Relaxed), + // trb.raw_data()[3].load(Ordering::Relaxed), + // ); + let mut crb = DisposableRef::new(self.allocate_crb().unwrap()); self.issue_trb(Some(crb.as_mut()), trb, None, None); self.wait_cnr(0); @@ -946,6 +988,13 @@ impl Xhci { let port = self.port_by(port_id); self.wait_cnr(0); + // log!( + // "ATTACH_ROOT {:?} {:08x} PS {:04x}", + // port_id, + // port.status().bits(), + // port.status().speed_raw() + // ); + let trb = Trb::new(TrbType::ENABLE_SLOT_COMMAND); let slot_id = match self.execute_command(&trb) { Ok(result) => result.slot_id().unwrap(), @@ -1141,6 +1190,16 @@ impl Xhci { } TrbEvent::CommandCompletion(event) => { let event_trb = ScheduledTrb(event.ptr()); + + // unsafe { + // log!( + // "CCE {} {:?} {:?}", + // event.slot_id().map(|v| v.0.get()).unwrap_or(0), + // event_trb.peek().trb_type(), + // event.completion_code() + // ); + // } + if let Some(crb) = self.find_crb(event_trb, Some(RequestState::Scheduled)) { crb.set_response(event.as_trb()); } else { @@ -1149,6 +1208,7 @@ impl Xhci { } TrbEvent::PortStatusChange(event) => { let port_id = event.port_id().unwrap(); + // log!("PSC {:?}", port_id); self.port_status_change_queue.post(port_id).unwrap(); } TrbEvent::DeviceNotification(event) => { @@ -1218,49 +1278,17 @@ impl Xhci { async fn _root_hub_task(self: Arc) { self.focus_hub(None); - for (port_id, port) in self.usb3_ports() { + for (_port_id, port) in self.usb3_ports() { self.wait_cnr(0); - let status = port.status(); - if status.is_connected() { - self._process_port_change(port_id, true).await; - port.clear_changes(); - } else { - port.clear_changes(); - port.set(PortSc::PR); - } + port.set(PortSc::PR); } - for (port_id, port) in self.usb2_ports() { + for (_port_id, port) in self.usb2_ports() { self.wait_cnr(0); - let status = port.status(); - if status.is_connected() { - self._process_port_change(port_id, true).await; - port.clear_changes(); - } else { - port.clear_changes(); - port.set(PortSc::PR); - } + port.set(PortSc::PR); } - Timer::sleep_async(Duration::from_millis(1000)).await; - - // for (port_id, port) in self.ports() { - // self.wait_cnr(0); - // let status = port.status(); - // log!( - // "STATUS2: {:?} {:08x} {:?} {:?}", - // port_id, - // status.bits(), - // status.speed(), - // status.link_state(), - // ); - // } - self.unfocus_hub(None); - // log!("ALL PORT RESET DONE"); - - Timer::sleep_async(Duration::from_millis(1000)).await; - while let Some(port_id) = self.port_status_change_queue.wait_event().await { let mut ports = Vec::new(); ports.push(port_id); diff --git a/system/src/drivers/usb/xhci/xhci_r.rs b/system/src/drivers/usb/xhci/xhci_r.rs index eef4efb82..4c5b57862 100644 --- a/system/src/drivers/usb/xhci/xhci_r.rs +++ b/system/src/drivers/usb/xhci/xhci_r.rs @@ -1,39 +1,45 @@ //! xHCI MMIO Registers use super::*; -use crate::{drivers::usb::*, mem::MemoryManager, *}; +use crate::{ + drivers::usb::*, + mem::{ + mmio::{MmioRegU32, MmioRegU64}, + MemoryManager, + }, + *, +}; use core::{ ffi::c_void, mem::size_of, mem::transmute, num::{NonZeroU8, NonZeroUsize}, slice, - sync::atomic::*, }; /// xHC Capability Registers #[repr(C)] #[allow(dead_code)] pub struct CapabilityRegisters { - caplength: AtomicU32, - hcsparams1: AtomicU32, - hcsparams2: AtomicU32, - hcsparams3: AtomicU32, - hccparams1: AtomicU32, - dboff: AtomicU32, - rtsoff: AtomicU32, - hccparams2: AtomicU32, + caplength: MmioRegU32, + hcsparams1: MmioRegU32, + hcsparams2: MmioRegU32, + hcsparams3: MmioRegU32, + hccparams1: MmioRegU32, + dboff: MmioRegU32, + rtsoff: MmioRegU32, + hccparams2: MmioRegU32, } impl CapabilityRegisters { #[inline] pub fn length(&self) -> usize { - (self.caplength.load(Ordering::Relaxed) & 0xFF) as usize + (self.caplength.read_volatile() & 0xFF) as usize } #[inline] pub fn version(&self) -> (usize, usize, usize) { - let ver = self.caplength.load(Ordering::Relaxed) >> 16; + let ver = self.caplength.read_volatile() >> 16; let ver2 = (ver & 0x0F) as usize; let ver1 = ((ver >> 4) & 0x0F) as usize; let ver0 = (ver >> 8) as usize; @@ -42,37 +48,37 @@ impl CapabilityRegisters { #[inline] pub fn hcs_params1(&self) -> u32 { - self.hcsparams1.load(Ordering::Relaxed) + self.hcsparams1.read_volatile() } #[inline] pub fn hcs_params2(&self) -> u32 { - self.hcsparams2.load(Ordering::Relaxed) + self.hcsparams2.read_volatile() } #[inline] pub fn hcs_params3(&self) -> u32 { - self.hcsparams3.load(Ordering::Relaxed) + self.hcsparams3.read_volatile() } #[inline] pub fn hcc_params1(&self) -> HccParams1 { - HccParams1::from_bits_retain(self.hccparams1.load(Ordering::Relaxed)) + HccParams1::from_bits_retain(self.hccparams1.read_volatile()) } #[inline] pub fn hcc_params2(&self) -> u32 { - self.hccparams2.load(Ordering::Relaxed) + self.hccparams2.read_volatile() } #[inline] pub fn db_off(&self) -> usize { - (self.dboff.load(Ordering::Relaxed) & !0x03) as usize + (self.dboff.read_volatile() & !0x03) as usize } #[inline] pub fn rts_off(&self) -> usize { - (self.rtsoff.load(Ordering::Relaxed) & !0x1F) as usize + (self.rtsoff.read_volatile() & !0x1F) as usize } #[inline] @@ -189,20 +195,21 @@ impl HccParams1 { #[repr(C)] #[allow(dead_code)] pub struct OperationalRegisters { - usbcmd: AtomicU32, - usbsts: AtomicU32, - pagesize: AtomicU32, + usbcmd: MmioRegU32, + usbsts: MmioRegU32, + pagesize: MmioRegU32, _rsrv1: [u32; 2], - dnctrl: AtomicU32, - crcr: AtomicU64, + dnctrl: MmioRegU32, + crcr: MmioRegU64, _rsrv2: [u32; 4], - dcbaap: AtomicU64, - config: AtomicU32, + dcbaap: MmioRegU64, + config: MmioRegU32, } impl OperationalRegisters { + #[inline] pub fn page_size_raw(&self) -> u32 { - self.pagesize.load(Ordering::Relaxed) & 0xFFFF + self.pagesize.read_volatile() & 0xFFFF } #[inline] @@ -213,12 +220,12 @@ impl OperationalRegisters { #[inline] pub fn read_cmd(&self) -> UsbCmd { - UsbCmd::from_bits_retain(self.usbcmd.load(Ordering::SeqCst)) + UsbCmd::from_bits_retain(self.usbcmd.read_volatile()) } #[inline] pub fn write_cmd(&self, val: UsbCmd) { - self.usbcmd.store(val.bits(), Ordering::SeqCst); + self.usbcmd.write_volatile(val.bits()); } #[inline] @@ -228,45 +235,45 @@ impl OperationalRegisters { #[inline] pub fn status(&self) -> UsbSts { - UsbSts::from_bits_retain(self.usbsts.load(Ordering::SeqCst)) + UsbSts::from_bits_retain(self.usbsts.read_volatile()) } #[inline] pub fn reset_status(&self, val: UsbSts) { - self.usbsts.store(val.bits(), Ordering::SeqCst); + self.usbsts.write_volatile(val.bits()); } #[inline] pub fn set_crcr(&self, val: NonNullPhysicalAddress) { - self.crcr.store(val.get().as_u64(), Ordering::SeqCst); + self.crcr.write_volatile(val.get().as_u64()); } #[inline] pub fn dcbaap(&self) -> PhysicalAddress { - self.dcbaap.load(Ordering::SeqCst).into() + self.dcbaap.read_volatile().into() } #[inline] pub fn set_dcbaap(&self, val: NonNullPhysicalAddress) { - self.dcbaap.store(val.get().as_u64(), Ordering::SeqCst); + self.dcbaap.write_volatile(val.get().as_u64()); } #[inline] - pub fn set_config(&self, max_dev_slot: usize, u3e: bool, cie: bool) { + pub unsafe fn set_config(&self, max_dev_slot: usize, u3e: bool, cie: bool) { let val = (max_dev_slot & 0xFF) as u32 | if u3e { 0x100 } else { 0 } | if cie { 0x200 } else { 0 }; - self.config.store(val, Ordering::SeqCst); + self.config.write_volatile(val); } #[inline] pub fn device_notification_bitmap(&self) -> DeviceNotificationBitmap { - DeviceNotificationBitmap::from_bits_retain(self.dnctrl.load(Ordering::SeqCst)) + DeviceNotificationBitmap::from_bits_retain(self.dnctrl.read_volatile()) } #[inline] - pub fn set_device_notification_bitmap(&self, bitmap: DeviceNotificationBitmap) { - self.dnctrl.store(bitmap.bits(), Ordering::SeqCst); + pub unsafe fn set_device_notification_bitmap(&self, bitmap: DeviceNotificationBitmap) { + self.dnctrl.write_volatile(bitmap.bits()); } } @@ -317,16 +324,16 @@ impl DeviceNotificationBitmap { #[repr(C)] #[allow(dead_code)] pub struct PortRegisters { - portsc: AtomicU32, - portpmsc: AtomicU32, - portli: AtomicU32, - porthlpmc: AtomicU32, + portsc: MmioRegU32, + portpmsc: MmioRegU32, + portli: MmioRegU32, + porthlpmc: MmioRegU32, } impl PortRegisters { #[inline] pub fn status(&self) -> PortSc { - PortSc::from_bits_retain(self.portsc.load(Ordering::SeqCst)) + PortSc::from_bits_retain(self.portsc.read_volatile()) } #[inline] @@ -348,7 +355,7 @@ impl PortRegisters { #[inline] pub fn write(&self, val: PortSc) { - self.portsc.store(val.bits(), Ordering::SeqCst); + self.portsc.write_volatile(val.bits()); } } @@ -480,7 +487,7 @@ impl PortSc { /// xHC Runtime Registers #[repr(C)] pub struct RuntimeRegisters { - mfindex: AtomicU32, + mfindex: MmioRegU32, _rsrv1: [u32; 7], irs: [InterrupterRegisterSet; 1], } @@ -488,7 +495,7 @@ pub struct RuntimeRegisters { impl RuntimeRegisters { #[inline] pub fn mf_index(&self) -> u32 { - self.mfindex.load(Ordering::SeqCst) & 0x3FFF + self.mfindex.read_volatile() & 0x3FFF } #[inline] @@ -506,12 +513,12 @@ impl RuntimeRegisters { #[repr(C)] #[allow(dead_code)] pub struct InterrupterRegisterSet { - iman: AtomicU32, - imod: AtomicU32, - erstsz: AtomicU32, - _rsrv: u32, - erstba: AtomicU64, - erdp: AtomicU64, + iman: MmioRegU32, + imod: MmioRegU32, + erstsz: MmioRegU32, + _rsrv: MmioRegU32, + erstba: MmioRegU64, + erdp: MmioRegU64, } impl InterrupterRegisterSet { @@ -521,18 +528,18 @@ impl InterrupterRegisterSet { let count = 1; let (base, erst) = MemoryManager::alloc_dma(count).unwrap(); *erst = EventRingSegmentTableEntry::new(initial_dp, len as u16); - self.erstsz.store(count as u32, Ordering::SeqCst); - self.erdp.store(initial_dp.as_u64(), Ordering::SeqCst); - self.erstba.store(base.as_u64(), Ordering::SeqCst); + self.erstsz.write_volatile(count as u32); + self.erdp.write_volatile(initial_dp.as_u64()); + self.erstba.write_volatile(base.as_u64()); } #[inline] pub fn set_iman(&self, val: u32) { - self.iman.store(val, Ordering::SeqCst); + self.iman.write_volatile(val); } pub fn dequeue_event<'a>(&'a self, event_cycle: &'a CycleBit) -> Option<&'a Trb> { - let erdp = PhysicalAddress::from(self.erdp.load(Ordering::SeqCst)); + let erdp = PhysicalAddress::from(self.erdp.read_volatile()); let cycle = event_cycle.value(); let event = unsafe { &*(erdp & !15).direct_map::() }; if event.cycle_bit() == cycle { @@ -543,7 +550,7 @@ impl InterrupterRegisterSet { event_cycle.toggle(); } let new_erdp = er_base.as_u64() | (index * size_of::()) as u64 | 8; - self.erdp.store(new_erdp, Ordering::SeqCst); + self.erdp.write_volatile(new_erdp); Some(event) } else { @@ -554,17 +561,17 @@ impl InterrupterRegisterSet { /// xHC Doorbell Register #[repr(transparent)] -pub struct DoorbellRegister(AtomicU32); +pub struct DoorbellRegister(MmioRegU32); impl DoorbellRegister { #[inline] pub fn raw(&self) -> u32 { - self.0.load(Ordering::SeqCst) + self.0.read_volatile() } #[inline] pub fn set_raw(&self, val: u32) { - self.0.store(val, Ordering::SeqCst); + self.0.write_volatile(val); } #[inline] diff --git a/system/src/fs/ramfs.rs b/system/src/fs/ramfs.rs index 80649df0e..1ae864cf3 100644 --- a/system/src/fs/ramfs.rs +++ b/system/src/fs/ramfs.rs @@ -453,9 +453,7 @@ impl ThisFsDirectoryContent { fn find_index(&self, name: &str) -> Result { self.content .iter() - .enumerate() - .find(|(_, v)| ThisFs::compare_name(v.name(), name)) - .map(|(index, _)| index) + .position(|v| ThisFs::compare_name(v.name(), name)) .ok_or(ErrorKind::NotFound.into()) } @@ -539,12 +537,10 @@ impl ThisFsDirectoryContent { fn append_or_replace(&mut self, name: &str, entity: Arc) { match self .content - .iter() - .enumerate() - .find(|(_index, dir_ent)| ThisFs::compare_name(dir_ent.name(), name)) - .map(|(index, _)| index) + .iter_mut() + .find(|dir_ent| ThisFs::compare_name(dir_ent.name(), name)) { - Some(index) => self.content[index].entity = entity, + Some(dir_ent) => dir_ent.entity = entity, None => self.content.push(ThisFsDirEntry { name: name.to_owned(), entity, diff --git a/system/src/io/hid_mgr.rs b/system/src/io/hid_mgr.rs index 8d43ec453..5b732c073 100644 --- a/system/src/io/hid_mgr.rs +++ b/system/src/io/hid_mgr.rs @@ -560,7 +560,7 @@ impl ParsedReportApplication { } #[inline] - pub fn features(&self) -> impl Iterator { + pub fn feature_items(&self) -> impl Iterator { self.entries().flat_map(|v| match v { ParsedReportEntry::Feature(v) => Some(v), _ => None, @@ -578,12 +578,7 @@ impl ParsedReportApplication { } pub fn bit_count_for_input(&self) -> usize { - let acc = self.bit_count(|v| matches!(v, ParsedReportEntry::Input(_))); - if acc > 0 && self.report_id.is_some() { - acc + 8 - } else { - acc - } + self.bit_count(|v| matches!(v, ParsedReportEntry::Input(_))) } pub fn bit_count_for_output(&self) -> usize { @@ -1162,6 +1157,22 @@ impl<'a> HidBitStreamWriter<'a> { } impl HidBitStreamWriter<'_> { + #[inline] + pub fn data(&self) -> &[u8] { + &self.slice + } + + #[inline] + pub fn current_len(&self) -> usize { + (self.position + 7) / 8 + } + + #[inline] + pub fn clear(&mut self) { + self.position = 0; + self.slice.fill(0); + } + fn _write_bits( &mut self, position: usize, diff --git a/system/src/io/image.rs b/system/src/io/image.rs index 5473a2b81..18c4d9576 100644 --- a/system/src/io/image.rs +++ b/system/src/io/image.rs @@ -2,12 +2,18 @@ use alloc::vec::Vec; use byteorder::*; use megstd::drawing::*; use png_decoder; +use zune_jpeg::JpegDecoder; pub struct ImageLoader; impl ImageLoader { pub fn load(blob: &[u8]) -> Result { - let drivers = [Self::_from_qoi, Self::_from_png, Self::_from_msdib]; + let drivers = [ + Self::_from_jpeg, + Self::_from_msdib, + Self::_from_png, + Self::_from_qoi, + ]; for driver in drivers { match driver(blob) { Err(DecodeError::NotSupported) => continue, @@ -33,8 +39,7 @@ impl ImageLoader { }) .map_err(|err| match err { png_decoder::DecodeError::InvalidMagicBytes => DecodeError::NotSupported, - png_decoder::DecodeError::Decompress(_) => DecodeError::General, - _ => DecodeError::InvalidParameter, + _ => DecodeError::InvalidData, }) } @@ -63,9 +68,7 @@ impl ImageLoader { .map_err(|err| match err { rapid_qoi::DecodeError::NotEnoughData => DecodeError::OutOfMemory, rapid_qoi::DecodeError::InvalidMagic => DecodeError::NotSupported, - rapid_qoi::DecodeError::InvalidChannelsValue - | rapid_qoi::DecodeError::InvalidColorSpaceValue - | rapid_qoi::DecodeError::OutputIsTooSmall => DecodeError::InvalidParameter, + _ => DecodeError::InvalidData, }) } @@ -158,6 +161,27 @@ impl ImageLoader { } Ok(OwnedBitmap32::from_vec(vec, Size::new(width as isize, height as isize)).into()) } + + #[inline] + fn _from_jpeg(blob: &[u8]) -> Result { + let mut decoder = JpegDecoder::new(blob); + decoder + .decode_headers() + .map_err(|_| DecodeError::NotSupported)?; + let info = decoder.info().ok_or(DecodeError::InvalidData)?; + let pixels = decoder.decode().map_err(|_| DecodeError::InvalidData)?; + + let vec = pixels + .array_chunks::<3>() + .map(|v| (v[0], v[1], v[2], Alpha8::OPAQUE)) + .map(|(r, g, b, a)| ColorComponents::from_rgba(r, g, b, a).into_true_color()) + .collect::>(); + + Ok( + OwnedBitmap32::from_vec(vec, Size::new(info.width as isize, info.height as isize)) + .into(), + ) + } } #[derive(Debug)] @@ -166,4 +190,5 @@ pub enum DecodeError { OutOfMemory, NotSupported, InvalidParameter, + InvalidData, } diff --git a/system/src/lib.rs b/system/src/lib.rs index f962f9800..f06cc6c1c 100644 --- a/system/src/lib.rs +++ b/system/src/lib.rs @@ -63,26 +63,23 @@ extern crate alloc; #[macro_export] macro_rules! print { - ($($arg:tt)*) => { - write!(system::System::stdout(), $($arg)*).unwrap() - }; + ($($arg:tt)*) => {{ + let _ = write!(system::System::stdout(), $($arg)*); + }}; } #[macro_export] macro_rules! println { - ($fmt:expr) => { - print!(concat!($fmt, "\r\n")) - }; - ($fmt:expr, $($arg:tt)*) => { - print!(concat!($fmt, "\r\n"), $($arg)*) - }; + ($($arg:tt)*) => {{ + let _ = writeln!(system::System::stdout(), $($arg)*); + }}; } #[macro_export] macro_rules! log { - ($($arg:tt)*) => { - let _ = writeln!(log::Log::new(), $($arg)*).unwrap(); - }; + ($($arg:tt)*) => {{ + let _ = writeln!(log::Log::new(), $($arg)*); + }}; } static PANIC_GLOBAL_LOCK: Spinlock = Spinlock::new(); diff --git a/system/src/main.rs b/system/src/main.rs index 978d03179..4dac01e75 100644 --- a/system/src/main.rs +++ b/system/src/main.rs @@ -425,21 +425,41 @@ impl Shell { println!("memory:\tShow memory information"); return; } + + fn print_cpu_type(device: &DeviceInfo, new_line: bool) { + let n_threads = device.num_of_logical_cpus(); + let n_cores = device.num_of_physical_cpus(); + let n_pcores = device.num_of_main_cpus(); + let n_ecores = device.num_of_efficient_cpus(); + + match device.processor_system_type() { + ProcessorSystemType::Hybrid => { + print!( + "Hybrid {}P + {}E Core / {} Threads", + n_pcores, n_ecores, n_threads, + ); + } + ProcessorSystemType::SMT => { + print!("SMT {} Cores / {} Threads", n_cores, n_threads,); + } + ProcessorSystemType::SMP => { + print!("SMP {} Processors", n_cores,); + } + ProcessorSystemType::Uniprocessor => { + print!("Uniprocessor"); + } + } + + if new_line { + println!(""); + } + } + let subcmd = argv[1]; match subcmd { "device" => { let device = System::current_device(); - let n_cores = device.num_of_main_cpus(); - let n_threads = device.num_of_logical_cpus(); - if n_threads > 1 { - if n_cores != n_threads { - print!(" {} Cores {} Threads", n_cores, n_threads,); - } else { - print!(" {} Processors", n_cores,); - } - } else { - print!(" Uniprocessor system"); - } + print_cpu_type(device, false); let bytes = device.total_memory_size(); let gb = bytes >> 30; @@ -455,18 +475,7 @@ impl Shell { } "cpu" => { let device = System::current_device(); - - let n_cores = device.num_of_main_cpus(); - let n_threads = device.num_of_logical_cpus(); - if n_threads > 1 { - if n_cores != n_threads { - println!("{} Cores {} Threads", n_cores, n_threads,); - } else { - println!("{} Processors", n_cores,); - } - } else { - println!("Uniprocessor system"); - } + print_cpu_type(device, true); for (index, cpu) in System::cpus().enumerate() { println!( diff --git a/system/src/mem/mmio.rs b/system/src/mem/mmio.rs index ff65fcb61..0c8eaa4da 100644 --- a/system/src/mem/mmio.rs +++ b/system/src/mem/mmio.rs @@ -1,65 +1,52 @@ use super::*; use crate::{drivers::pci::PciBar, *}; use core::{ - marker::PhantomData, mem::{size_of, transmute}, num::NonZeroUsize, - ops::{Deref, DerefMut}, - slice, - sync::atomic::*, }; -#[repr(transparent)] -pub struct Mmio { - base: usize, - _phantom: PhantomData, +macro_rules! mmio_reg_declare { + ( + $( + $(#[$outer:meta])* + $vis:vis struct $class:ident: $ty:ty; + )* + ) => { + $( + $(#[$outer])* + #[repr(transparent)] + $vis struct $class(core::cell::UnsafeCell<$ty>); + + impl $class { + #[allow(dead_code)] + #[inline] + $vis fn read_volatile(&self) -> $ty { + unsafe { + self.0.get().read_volatile() + } + } + + #[allow(dead_code)] + #[inline] + $vis fn write_volatile(&self, val: $ty) { + unsafe { + self.0.get().write_volatile(val); + } + } + } + )* + }; } -impl Mmio { - #[inline] - pub unsafe fn from_phys(base: PhysicalAddress) -> Option { - MemoryManager::mmap(MemoryMapRequest::Mmio(base, size_of::())).map(|va| Self { - base: va.get(), - _phantom: PhantomData, - }) - } +mmio_reg_declare! { - #[inline] - pub unsafe fn from_bar(bar: PciBar) -> Option { - if bar.is_mmio() && size_of::() <= bar.size() { - Self::from_phys(bar.base()) - } else { - None - } - } + pub struct MmioRegU8: u8; - #[inline] - pub unsafe fn from_virt(base: NonZeroUsize) -> Self { - Self { - base: base.get(), - _phantom: PhantomData, - } - } -} + pub struct MmioRegU16: u16; -// impl Drop for Mmio { -// fn drop(&mut self) { -// // TODO: -// } -// } - -impl Deref for Mmio { - type Target = T; - - fn deref(&self) -> &Self::Target { - unsafe { &*(self.base as *const _) } - } -} + pub struct MmioRegU32: u32; -impl DerefMut for Mmio { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { &mut *(self.base as *mut _) } - } + pub struct MmioRegU64: u64; } #[derive(Debug, Copy, Clone)] @@ -121,69 +108,80 @@ impl MmioSlice { #[inline] #[track_caller] - #[cfg(target_has_atomic_load_store = "8")] pub fn read_u8(&self, offset: usize) -> u8 { - let slice = unsafe { slice::from_raw_parts(self.base as *const AtomicU8, self.size) }; - slice[offset].load(Ordering::SeqCst) + let mut result = 0; + self.check_limit(offset, &result); + unsafe { + let ptr: &MmioRegU8 = transmute(self.base + offset); + result = ptr.read_volatile(); + }; + result } #[inline] #[track_caller] - #[cfg(target_has_atomic_load_store = "8")] pub fn write_u8(&self, offset: usize, value: u8) { - let slice = unsafe { slice::from_raw_parts(self.base as *const AtomicU8, self.size) }; - slice[offset].store(value, Ordering::SeqCst); + self.check_limit(offset, &value); + unsafe { + let ptr: &MmioRegU8 = transmute(self.base + offset); + ptr.write_volatile(value); + }; } #[inline] #[track_caller] - #[cfg(target_has_atomic_load_store = "16")] pub fn read_u16(&self, offset: usize) -> u16 { let mut result = 0; self.check_limit(offset, &result); - let ptr: &AtomicU16 = unsafe { transmute(self.base + offset) }; - result = ptr.load(Ordering::SeqCst); + unsafe { + let ptr: &MmioRegU16 = transmute(self.base + offset); + result = ptr.read_volatile(); + }; result } #[inline] #[track_caller] - #[cfg(target_has_atomic_load_store = "32")] pub fn read_u32(&self, offset: usize) -> u32 { let mut result = 0; self.check_limit(offset, &result); - let ptr: &AtomicU32 = unsafe { transmute(self.base + offset) }; - result = ptr.load(Ordering::SeqCst); + unsafe { + let ptr: &MmioRegU32 = transmute(self.base + offset); + result = ptr.read_volatile(); + }; result } #[inline] #[track_caller] - #[cfg(target_has_atomic_load_store = "32")] pub fn write_u32(&self, offset: usize, value: u32) { self.check_limit(offset, &value); - let ptr: &AtomicU32 = unsafe { transmute(self.base + offset) }; - ptr.store(value, Ordering::SeqCst); + unsafe { + let ptr: &MmioRegU32 = transmute(self.base + offset); + ptr.write_volatile(value); + }; } #[inline] #[track_caller] - #[cfg(target_has_atomic_load_store = "64")] pub fn read_u64(&self, offset: usize) -> u64 { let mut result = 0; self.check_limit(offset, &result); - let ptr: &AtomicU64 = unsafe { transmute(self.base + offset) }; - result = ptr.load(Ordering::SeqCst); + unsafe { + let ptr: &MmioRegU64 = transmute(self.base + offset); + result = ptr.read_volatile(); + }; result } #[inline] #[track_caller] - #[cfg(target_has_atomic_load_store = "64")] pub fn write_u64(&self, offset: usize, value: u64) { self.check_limit(offset, &value); - let ptr: &AtomicU64 = unsafe { transmute(self.base + offset) }; - ptr.store(value, Ordering::SeqCst); + unsafe { + let ptr: &MmioRegU64 = transmute(self.base + offset); + ptr.write_volatile(value); + }; } #[inline] diff --git a/system/src/rt/haribote/hoe.rs b/system/src/rt/haribote/hoe.rs index d084365d3..0b7080cd2 100644 --- a/system/src/rt/haribote/hoe.rs +++ b/system/src/rt/haribote/hoe.rs @@ -65,7 +65,8 @@ impl HoeManager { pub(super) unsafe fn init() { let mut shared = &mut *HOE_MANAGER.get(); - if let Ok(mut file) = FileManager::open("/hari/nihongo.fnt", OpenOptions::new().read(true)) + if let Ok(mut file) = + FileManager::open("/boot/hari/nihongo.fnt", OpenOptions::new().read(true)) { let mut buf = Vec::new(); if let Ok(_) = file.read_to_end(&mut buf) { diff --git a/system/src/system.rs b/system/src/system.rs index f7600fa20..2a2d1d2f1 100644 --- a/system/src/system.rs +++ b/system/src/system.rs @@ -83,7 +83,7 @@ impl System { && info.screen_height > 0 { let stride = info.vram_stride as usize; - let vram_size = stride * info.screen_height as usize; + let vram_size = 4 * stride * info.screen_height as usize; let base = mem::MemoryManager::mmap(mem::MemoryMapRequest::Framebuffer( PhysicalAddress::new(info.vram_base), vram_size, @@ -125,18 +125,20 @@ impl System { let shared = Self::shared(); - if false { + if true { let device = System::current_device(); let bytes = device.total_memory_size(); let gb = bytes >> 30; let mb = (100 * (bytes & 0x3FFF_FFFF)) / 0x4000_0000; log!( - "{} v{} (codename {}) {} Cores {}.{:02} GB Memory", + "\n{} v{} (codename {}) {:?} {}C/{}T Memory {}.{:02}GB", System::name(), System::version(), System::codename(), - device.num_of_main_cpus(), + device.processor_system_type(), + device.num_of_physical_cpus(), + device.num_of_logical_cpus(), gb, mb ); @@ -230,9 +232,23 @@ impl System { shared.cpus.push(new_cpu); let device = &shared.current_device; device.num_of_logical_cpus.fetch_add(1, Ordering::AcqRel); - if processor_type == ProcessorCoreType::Main { - device.num_of_main_cpus.fetch_add(1, Ordering::AcqRel); + match processor_type { + ProcessorCoreType::Normal => { + device.num_of_main_cpus.fetch_add(1, Ordering::AcqRel); + device.num_of_physical_cpus.fetch_add(1, Ordering::AcqRel); + } + ProcessorCoreType::Efficient => { + device.num_of_effecient_cpus.fetch_add(1, Ordering::AcqRel); + device.num_of_physical_cpus.fetch_add(1, Ordering::AcqRel); + if device.num_of_main_cpus() > 0 { + device.is_hybrid.store(true, Ordering::SeqCst); + } + } + ProcessorCoreType::Sub | ProcessorCoreType::EfficientSub => { + device.has_smt.store(true, Ordering::SeqCst); + } } + fence(Ordering::SeqCst); } @@ -336,7 +352,11 @@ pub struct DeviceInfo { manufacturer_name: Option, model_name: Option, num_of_logical_cpus: AtomicUsize, + num_of_physical_cpus: AtomicUsize, num_of_main_cpus: AtomicUsize, + num_of_effecient_cpus: AtomicUsize, + is_hybrid: AtomicBool, + has_smt: AtomicBool, total_memory_size: usize, } @@ -347,7 +367,11 @@ impl DeviceInfo { manufacturer_name: None, model_name: None, num_of_logical_cpus: AtomicUsize::new(0), + num_of_physical_cpus: AtomicUsize::new(0), num_of_main_cpus: AtomicUsize::new(0), + num_of_effecient_cpus: AtomicUsize::new(0), + is_hybrid: AtomicBool::new(false), + has_smt: AtomicBool::new(false), total_memory_size: 0, } } @@ -376,12 +400,46 @@ impl DeviceInfo { self.num_of_logical_cpus.load(Ordering::SeqCst) } - /// Returns the number of performance CPU cores. + /// Returns the number of physical CPU cores. /// Returns less than `num_of_logical_cpus` for SMT-enabled processors. #[inline] + pub fn num_of_physical_cpus(&self) -> usize { + self.num_of_physical_cpus.load(Ordering::SeqCst) + } + + /// Returns the number of performance CPU cores. + #[inline] pub fn num_of_main_cpus(&self) -> usize { self.num_of_main_cpus.load(Ordering::SeqCst) } + + /// Returns the number of Highly efficient CPU cores. + #[inline] + pub fn num_of_efficient_cpus(&self) -> usize { + self.num_of_effecient_cpus.load(Ordering::SeqCst) + } + + #[inline] + pub fn processor_system_type(&self) -> ProcessorSystemType { + if self.is_hybrid.load(Ordering::Relaxed) { + ProcessorSystemType::Hybrid + } else if self.has_smt.load(Ordering::Relaxed) { + ProcessorSystemType::SMT + } else if self.num_of_logical_cpus() > 1 { + ProcessorSystemType::SMP + } else { + ProcessorSystemType::Uniprocessor + } + } +} + +#[derive(Debug, Clone, Copy)] +pub enum ProcessorSystemType { + /// System is a hybrid of performance and high-efficiency cores + Hybrid, + SMT, + SMP, + Uniprocessor, } #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] @@ -468,10 +526,50 @@ impl const From for ProcessorIndex { #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum ProcessorCoreType { - /// Main Processor - Main, + /// Normal Processor + Normal, /// Subprocessor of SMT enabled processor. Sub, - /// High-efficiency processor + /// Highly Efficient Processor Efficient, + /// Highly Efficient Subprocessor + EfficientSub, +} + +impl ProcessorCoreType { + #[inline] + pub fn new(is_normal: bool, is_efficient: bool) -> Self { + match (is_normal, is_efficient) { + (true, true) => Self::Efficient, + (true, false) => Self::Normal, + (false, true) => Self::EfficientSub, + (false, false) => Self::Sub, + } + } + + #[inline] + pub const fn is_normal_processor(&self) -> bool { + match *self { + Self::Normal | Self::Efficient => true, + Self::Sub | Self::EfficientSub => false, + } + } + + #[inline] + pub const fn is_sub_processor(&self) -> bool { + !self.is_normal_processor() + } + + #[inline] + pub const fn is_performance_processor(&self) -> bool { + !self.is_efficient_processor() + } + + #[inline] + pub const fn is_efficient_processor(&self) -> bool { + match *self { + Self::Efficient | Self::EfficientSub => true, + Self::Normal | Self::Sub => false, + } + } } diff --git a/system/src/task/scheduler.rs b/system/src/task/scheduler.rs index e903a99d8..80fe12b44 100644 --- a/system/src/task/scheduler.rs +++ b/system/src/task/scheduler.rs @@ -13,14 +13,17 @@ use crate::{ ui::window::{WindowHandle, WindowMessage}, *, }; -use alloc::format; +// use alloc::format; use core::{ cell::UnsafeCell, ffi::c_void, fmt, intrinsics::transmute, num::*, ops::*, sync::atomic::*, time::Duration, }; use megstd::{string::*, Arc, BTreeMap, Box, String, ToOwned, Vec}; -const THRESHOLD_ENTER_MAX: usize = 950; +const THRESHOLD_BUSY_THREAD: usize = 750; +const THRESHOLD_ENTER_SAVING: usize = 500; +const THRESHOLD_LEAVE_SAVING: usize = 750; +const THRESHOLD_ENTER_MAX: usize = 850; const THRESHOLD_LEAVE_MAX: usize = 666; static SCHEDULER_STATE: AtomicWrapper = AtomicWrapper::default(); @@ -53,6 +56,8 @@ pub enum SchedulerState { Disabled = 0, /// The scheduler is running. Normal, + /// The scheduler is running in energy-saving mode. + Saving, /// The scheduler is running at full throttle. FullThrottle, } @@ -129,12 +134,13 @@ impl Scheduler { })); } fence(Ordering::SeqCst); - SCHEDULER_STATE.store(SchedulerState::Normal); + SCHEDULER_STATE.store(SchedulerState::FullThrottle); SpawnOption::with_priority(Priority::High).start_process(f, args, "System"); loop { unsafe { + assert!(Hal::cpu().is_interrupt_enabled()); Hal::cpu().wait_for_interrupt(); } } @@ -149,16 +155,16 @@ impl Scheduler { "Scheduler Statistics", ); - for index in 0..System::current_device().num_of_logical_cpus() { - let cpuid = ProcessorIndex(index); - cpuid.get().map(|v| { - if v.processor_type() == ProcessorCoreType::Main { - SpawnOption::with_priority(Priority::High) - .strong_affinity(cpuid) - .start(Self::_dispatch, index, &format!("dispatch_#{}", index)); - } - }); - } + // for index in 0..System::current_device().num_of_logical_cpus() { + // let cpuid = ProcessorIndex(index); + // cpuid.get().map(|v| { + // if v.processor_type() == ProcessorCoreType::Main { + // SpawnOption::with_priority(Priority::High) + // .strong_affinity(cpuid) + // .start(Self::_dispatch, index, &format!("dispatch_#{}", index)); + // } + // }); + // } } #[inline] @@ -194,7 +200,7 @@ impl Scheduler { #[inline] fn set_current_state(val: SchedulerState) { - SCHEDULER_STATE.store(val) + SCHEDULER_STATE.store(val); } /// All threads will stop. @@ -331,16 +337,28 @@ impl Scheduler { /// Returns whether the specified processor is stalled or not. fn is_stalled_processor(index: ProcessorIndex) -> bool { - let shared = Self::shared(); - let state = Self::current_state(); - if shared.is_frozen.load(Ordering::SeqCst) - || (state != SchedulerState::FullThrottle - && System::cpu(index).processor_type() == ProcessorCoreType::Sub) - { - true - } else { - false + if Self::shared().is_frozen.load(Ordering::SeqCst) { + return true; } + let is_hybrid = matches!( + System::current_device().processor_system_type(), + ProcessorSystemType::Hybrid + ); + let processor_type = System::cpu(index).processor_type(); + let allowed = match Self::current_state() { + SchedulerState::Disabled => false, + SchedulerState::Saving => { + if is_hybrid { + processor_type.is_normal_processor() && processor_type.is_efficient_processor() + } else { + processor_type.is_normal_processor() + } + } + SchedulerState::Normal => processor_type.is_normal_processor(), + SchedulerState::FullThrottle => true, + }; + + !allowed } /// Get the next executable thread from the thread queue @@ -449,6 +467,7 @@ impl Scheduler { let actual = now.0 - measure.0; let actual1000 = actual as usize * 1000; + let mut n_busy_thread = 0; let mut usage = 0; for thread in ThreadPool::shared().data.lock().values() { let thread = thread.clone(); @@ -458,6 +477,9 @@ impl Scheduler { thread.load.store(load as u32, Ordering::SeqCst); if thread.priority != Priority::Idle { usage += load; + if load >= THRESHOLD_BUSY_THREAD { + n_busy_thread += 1; + } } let process = thread.pid.get().unwrap(); @@ -472,27 +494,44 @@ impl Scheduler { process.load.store(load, Ordering::SeqCst); } - let num_cpu = System::current_device().num_of_logical_cpus(); - let usage_total = usize::min(usage, num_cpu * 1000); - let usage_per_cpu = usize::min(usage / num_cpu, 1000); + let device = System::current_device(); + let num_physical_cpu = device.num_of_physical_cpus(); + let num_logical_cpu = device.num_of_logical_cpus(); + + let usage_total = usize::min(usage, num_logical_cpu * 1000); + let usage_per_cpu = usize::min(usage / num_logical_cpu, 1000); shared.usage_total.store(usage_total, Ordering::SeqCst); shared.usage.store(usage_per_cpu, Ordering::SeqCst); - - match Self::current_state() { - SchedulerState::Disabled => (), - SchedulerState::Normal => { - if usage_total - > (System::current_device().num_of_main_cpus() - 1) * 1000 - + THRESHOLD_ENTER_MAX - { - Self::set_current_state(SchedulerState::FullThrottle); + let num_low_cpu = + if matches!(device.processor_system_type(), ProcessorSystemType::Hybrid) { + device.num_of_efficient_cpus() + } else { + num_physical_cpu + }; + + if n_busy_thread >= num_physical_cpu { + Self::set_current_state(SchedulerState::FullThrottle); + } else if n_busy_thread >= num_low_cpu { + Self::set_current_state(SchedulerState::Normal); + } else { + match Self::current_state() { + SchedulerState::Disabled => (), + SchedulerState::Saving => { + if usage_total > num_low_cpu * THRESHOLD_LEAVE_SAVING { + Self::set_current_state(SchedulerState::Normal); + } } - } - SchedulerState::FullThrottle => { - if usage_total - < System::current_device().num_of_main_cpus() * THRESHOLD_LEAVE_MAX - { - Self::set_current_state(SchedulerState::Normal); + SchedulerState::Normal => { + if usage_total > num_physical_cpu * 1000 - 1000 + THRESHOLD_ENTER_MAX { + Self::set_current_state(SchedulerState::FullThrottle); + } else if usage_total < num_low_cpu * THRESHOLD_ENTER_SAVING { + Self::set_current_state(SchedulerState::Saving); + } + } + SchedulerState::FullThrottle => { + if usage_total < num_physical_cpu * THRESHOLD_LEAVE_MAX { + Self::set_current_state(SchedulerState::Normal); + } } } } diff --git a/system/src/ui/window.rs b/system/src/ui/window.rs index 70ee4c15f..e7da7c8a9 100644 --- a/system/src/ui/window.rs +++ b/system/src/ui/window.rs @@ -258,7 +258,7 @@ impl WindowManager<'_> { while let Some(event) = shared.system_event.dequeue() { match event { WindowSystemEvent::Key(w, e) => { - let _ = w.post(WindowMessage::Key(e)); + w.post(WindowMessage::Key(e)).unwrap(); } } } @@ -824,7 +824,7 @@ impl WindowManager<'_> { // ctrl alt del UserEnv::system_reset(false); } else if let Some(window) = shared.active.get() { - let _ = Self::post_system_event(WindowSystemEvent::Key(window, event)); + Self::post_system_event(WindowSystemEvent::Key(window, event)).unwrap(); } } diff --git a/system/src/user/userenv.rs b/system/src/user/userenv.rs index c8c809d75..29500e021 100644 --- a/system/src/user/userenv.rs +++ b/system/src/user/userenv.rs @@ -19,12 +19,7 @@ use core::{ mem::{transmute, MaybeUninit}, time::Duration, }; -use megstd::{ - drawing::{vertex::*, *}, - io::Read, - string::*, - Arc, String, Vec, -}; +use megstd::{drawing::*, io::Read, string::*, Arc, String, Vec}; static IS_GUI_BOOT: bool = true; static mut SHUTDOWN_COMMAND: MaybeUninit> = MaybeUninit::uninit(); @@ -36,8 +31,10 @@ impl UserEnv { pub fn start(f: fn()) { assert_call_once!(); + // sync::semaphore::Semaphore::new(0).wait(); + if !IS_GUI_BOOT { - let point = 16; + let point = 14; let font = FontDescriptor::new(FontFamily::Monospace, point) .unwrap_or(FontManager::monospace_font()); @@ -262,13 +259,19 @@ async fn slpash_task(f: fn()) { Scheduler::spawn_async(activity_monitor_main()); Scheduler::spawn_async(_notification_task()); - if let Ok(mut file) = FileManager::open("/boot/wall.png", OpenOptions::new().read(true)) { - let mut vec = Vec::new(); - file.read_to_end(&mut vec).unwrap(); - if let Ok(dib) = ImageLoader::load(vec.as_slice()) { - WindowManager::set_desktop_bitmap(&dib.as_const()); + let mut wall_loaded = false; + for path in ["/boot/wall.png", "/boot/wall.jpg"] { + if let Ok(mut file) = FileManager::open(path, OpenOptions::new().read(true)) { + let mut vec = Vec::new(); + file.read_to_end(&mut vec).unwrap(); + if let Ok(dib) = ImageLoader::load(vec.as_slice()) { + WindowManager::set_desktop_bitmap(&dib.as_const()); + wall_loaded = true; + break; + } } - } else { + } + if !wall_loaded { WindowManager::set_desktop_color(Theme::shared().default_desktop_color()); } @@ -403,9 +406,13 @@ fn format_bytes(sb: &mut dyn Write, val: usize) -> core::fmt::Result { let mb = (val >> 20) & 0x3FF; let gb = val >> 30; - if gb >= 10 { - // > 10G + if gb >= 100 { + // > 100G write!(sb, "{:4}G", gb) + } else if gb >= 10 { + // > 10G + let mb00 = (mb * 10) >> 10; + write!(sb, "{:2}.{}G", gb, mb00) } else if gb >= 1 { // 1G~10G let mb0 = (mb * 100) >> 10; @@ -619,12 +626,22 @@ async fn activity_monitor_main() { let usage1 = usage / 10; write!(sb, "CPU: {:3}.{}%", usage1, usage0,).unwrap(); - let n_cores = device.num_of_main_cpus(); let n_threads = device.num_of_logical_cpus(); - if n_cores != n_threads { - write!(sb, " {}Cores {}Threads", n_cores, n_threads,).unwrap(); - } else { - write!(sb, " {}Cores", n_cores,).unwrap(); + let n_cores = device.num_of_physical_cpus(); + let n_pcores = device.num_of_main_cpus(); + let n_ecores = device.num_of_efficient_cpus(); + + match device.processor_system_type() { + ProcessorSystemType::Hybrid => { + write!(sb, " {}P + {}E / {}T", n_pcores, n_ecores, n_threads,) + .unwrap(); + } + ProcessorSystemType::SMT => { + write!(sb, " {}C / {}T", n_cores, n_threads,).unwrap(); + } + ProcessorSystemType::SMP | ProcessorSystemType::Uniprocessor => { + write!(sb, " {}Cores", n_cores,).unwrap(); + } } writeln!(sb, " {:?}", Scheduler::current_state()).unwrap(); @@ -971,148 +988,3 @@ fn font_test( bounds.height() } - -#[allow(dead_code)] -async fn clock_task() { - let bg_color = Color::WHITE; - let fg_color = Color::DARK_GRAY; - - let width = 240; - let height = 240; - let window_size = Size::new(width, height); - let padding = 4; - let radius = ((isize::min(width, height) - padding) / 2) as f64; - let center = Point::new(width / 2, height / 2); - let scale = 1.0; - - let window = RawWindowBuilder::new() - .size(window_size) - .bg_color(bg_color) - .build("Retro Clock"); - - let mut work_bitmap = OperationalBitmap::new(window_size); - - window.create_timer(0, Duration::from_millis(1)); - - while let Some(message) = window.await_message().await { - match message { - WindowMessage::Timer(_id) => { - window.set_needs_display(); - window.create_timer(0, Duration::from_millis(100)); - } - WindowMessage::Draw => { - let time = System::system_time(); - let seconds = time.secs as f64 + (time.nanos as f64 / 1_000_000_000.0); - let h = time.secs as f64 / 3600.0 % 12.0; - let m = time.secs as f64 / 60.0 % 60.0; - let s = seconds % 60.0; - - work_bitmap.reset(); - - for i in 0..60 { - let affine = - AffineMatrix2d::new(center.into(), Radian::TAU * (i as f64 / 60.0), scale); - - if i % 15 == 0 { - let mut polygon = [ - Vertex2d::new(0.0, 0.0 - radius), - Vertex2d::new(2.0, 4.0 - radius), - Vertex2d::new(0.0, 8.0 - radius), - Vertex2d::new(-2.0, 4.0 - radius), - ]; - polygon.transform(&affine); - draw_polygon(&mut work_bitmap, &polygon, 0xFF); - } else if i % 5 == 0 { - let mut polygon = [ - Vertex2d::new(0.0, 1.0 - radius), - Vertex2d::new(0.0, 7.0 - radius), - ]; - polygon.transform(&affine); - draw_polygon(&mut work_bitmap, &polygon, 0xFF); - } else { - let mut polygon = [ - Vertex2d::new(0.0, 2.0 - radius), - Vertex2d::new(0.0, 6.0 - radius), - ]; - polygon.transform(&affine); - draw_polygon(&mut work_bitmap, &polygon, 0x55); - } - } - - let mut polygon = [ - Vertex2d::new(0.0, 0.0 - radius * 0.5), - Vertex2d::new(4.0, 0.0), - Vertex2d::new(0.0, 8.0), - Vertex2d::new(-4.0, 0.0), - ]; - polygon.transform(&AffineMatrix2d::new( - center.into(), - Radian::TAU * h / 12.0, - scale, - )); - draw_polygon(&mut work_bitmap, &polygon, 0xCC); - - let mut polygon = [ - Vertex2d::new(0.0, 16.0 - radius), - Vertex2d::new(2.0, 0.0), - Vertex2d::new(0.0, 4.0), - Vertex2d::new(-2.0, 0.0), - ]; - polygon.transform(&AffineMatrix2d::new( - center.into(), - Radian::TAU * m / 60.0, - scale, - )); - draw_polygon(&mut work_bitmap, &polygon, 0xCC); - - let mut polygon = [Vertex2d::new(0.0, 16.0 - radius), Vertex2d::new(0.0, 4.0)]; - polygon.transform(&AffineMatrix2d::new( - center.into(), - Radian::TAU * s / 60.0, - scale, - )); - draw_polygon(&mut work_bitmap, &polygon, 0xEE); - - window.draw(|bitmap| { - bitmap.fill_rect(bitmap.bounds(), bg_color); - - work_bitmap.draw_to(bitmap, Point::new(0, 0), work_bitmap.bounds(), fg_color); - }); - } - WindowMessage::Close => { - window.close(); - } - _ => window.handle_default_message(message), - } - } -} - -fn draw_polygon(bitmap: &mut OperationalBitmap, polygon: &[Vertex2d], color: u8) { - let mut polygon = polygon.iter(); - let len = polygon.len(); - let Some(vertex0) = polygon.next() else { return }; - let mut vertex1 = vertex0; - while let Some(vertex2) = polygon.next() { - bitmap.draw_line_anti_aliasing_f( - (*vertex1).into(), - (*vertex2).into(), - |bitmap, point, level| unsafe { - bitmap.process_pixel_unchecked(point, |c| { - c.saturating_add((color as f64 * level) as u8) - }); - }, - ); - vertex1 = vertex2; - } - if len > 2 { - bitmap.draw_line_anti_aliasing_f( - (*vertex0).into(), - (*vertex1).into(), - |bitmap, point, level| unsafe { - bitmap.process_pixel_unchecked(point, |c| { - c.saturating_add((color as f64 * level) as u8) - }); - }, - ); - } -}