diff --git a/Kernel/Graphics/Bochs/GraphicsAdapter.cpp b/Kernel/Graphics/Bochs/GraphicsAdapter.cpp index 177192a90d..b0da4e6d4c 100644 --- a/Kernel/Graphics/Bochs/GraphicsAdapter.cpp +++ b/Kernel/Graphics/Bochs/GraphicsAdapter.cpp @@ -32,6 +32,8 @@ #define VBE_DISPI_DISABLED 0x00 #define VBE_DISPI_ENABLED 0x01 #define VBE_DISPI_LFB_ENABLED 0x40 +#define BOCHS_DISPLAY_LITTLE_ENDIAN 0x1e1e1e1e +#define BOCHS_DISPLAY_BIG_ENDIAN 0xbebebebe namespace Kernel { @@ -48,11 +50,18 @@ struct [[gnu::packed]] DISPIInterface { u16 y_offset; }; +struct [[gnu::packed]] ExtensionRegisters { + u32 region_size; + u32 framebuffer_byteorder; +}; + struct [[gnu::packed]] BochsDisplayMMIORegisters { u8 edid_data[0x400]; u16 vga_ioports[0x10]; u8 reserved[0xE0]; DISPIInterface bochs_regs; + u8 reserved2[0x100 - sizeof(DISPIInterface)]; + ExtensionRegisters extension_regs; }; UNMAP_AFTER_INIT NonnullRefPtr BochsGraphicsAdapter::initialize(PCI::Address address) @@ -62,6 +71,28 @@ UNMAP_AFTER_INIT NonnullRefPtr BochsGraphicsAdapter::initi return adopt_ref(*new BochsGraphicsAdapter(address)); } +void BochsGraphicsAdapter::set_framebuffer_to_big_endian_format() +{ + dbgln_if(BXVGA_DEBUG, "BochsGraphicsAdapter set_framebuffer_to_big_endian_format"); + full_memory_barrier(); + if (m_registers->extension_regs.region_size == 0xFFFFFFFF || m_registers->extension_regs.region_size == 0) + return; + full_memory_barrier(); + m_registers->extension_regs.framebuffer_byteorder = BOCHS_DISPLAY_BIG_ENDIAN; + full_memory_barrier(); +} + +void BochsGraphicsAdapter::set_framebuffer_to_little_endian_format() +{ + dbgln_if(BXVGA_DEBUG, "BochsGraphicsAdapter set_framebuffer_to_little_endian_format"); + full_memory_barrier(); + if (m_registers->extension_regs.region_size == 0xFFFFFFFF || m_registers->extension_regs.region_size == 0) + return; + full_memory_barrier(); + m_registers->extension_regs.framebuffer_byteorder = BOCHS_DISPLAY_LITTLE_ENDIAN; + full_memory_barrier(); +} + UNMAP_AFTER_INIT BochsGraphicsAdapter::BochsGraphicsAdapter(PCI::Address pci_address) : PCI::Device(pci_address) , m_mmio_registers(PCI::get_BAR2(pci_address) & 0xfffffff0) @@ -153,6 +184,7 @@ void BochsGraphicsAdapter::set_resolution_registers(size_t width, size_t height) m_registers->bochs_regs.enable = VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED; full_memory_barrier(); m_registers->bochs_regs.bank = 0; + set_framebuffer_to_little_endian_format(); } bool BochsGraphicsAdapter::try_to_set_resolution(size_t output_port_index, size_t width, size_t height) diff --git a/Kernel/Graphics/Bochs/GraphicsAdapter.h b/Kernel/Graphics/Bochs/GraphicsAdapter.h index 1d94163687..531d5f568f 100644 --- a/Kernel/Graphics/Bochs/GraphicsAdapter.h +++ b/Kernel/Graphics/Bochs/GraphicsAdapter.h @@ -56,6 +56,9 @@ private: bool validate_setup_resolution_with_io(size_t width, size_t height); void set_y_offset(size_t); + void set_framebuffer_to_big_endian_format(); + void set_framebuffer_to_little_endian_format(); + PhysicalAddress m_mmio_registers; Memory::TypedMapping m_registers; RefPtr m_framebuffer_device;