mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 20:42:43 +00:00 
			
		
		
		
	Kernel: Don't remap BochsGraphicsAdapter MMIO registers on every access
We were creating a new memory mapping every time WindowServer performed a buffer flip. This was very visible in whole-system profiles, as the mapping and unmapping of MMIO registers caused quite a bit of kmalloc() and kfree() churn. Avoid this problem by simply keeping the MMIO registers mapped.
This commit is contained in:
		
							parent
							
								
									eda5ab2d0f
								
							
						
					
					
						commit
						7e4bc04057
					
				
					 2 changed files with 18 additions and 19 deletions
				
			
		|  | @ -55,6 +55,7 @@ UNMAP_AFTER_INIT NonnullRefPtr<BochsGraphicsAdapter> BochsGraphicsAdapter::initi | ||||||
| UNMAP_AFTER_INIT BochsGraphicsAdapter::BochsGraphicsAdapter(PCI::Address pci_address) | UNMAP_AFTER_INIT BochsGraphicsAdapter::BochsGraphicsAdapter(PCI::Address pci_address) | ||||||
|     : PCI::DeviceController(pci_address) |     : PCI::DeviceController(pci_address) | ||||||
|     , m_mmio_registers(PCI::get_BAR2(pci_address) & 0xfffffff0) |     , m_mmio_registers(PCI::get_BAR2(pci_address) & 0xfffffff0) | ||||||
|  |     , m_registers(map_typed_writable<BochsDisplayMMIORegisters volatile>(m_mmio_registers)) | ||||||
| { | { | ||||||
|     // We assume safe resolutio is 1024x768x32
 |     // We assume safe resolutio is 1024x768x32
 | ||||||
|     m_framebuffer_console = Graphics::ContiguousFramebufferConsole::initialize(PhysicalAddress(PCI::get_BAR0(pci_address) & 0xfffffff0), 1024, 768, 1024 * sizeof(u32)); |     m_framebuffer_console = Graphics::ContiguousFramebufferConsole::initialize(PhysicalAddress(PCI::get_BAR0(pci_address) & 0xfffffff0), 1024, 768, 1024 * sizeof(u32)); | ||||||
|  | @ -89,9 +90,8 @@ GraphicsDevice::Type BochsGraphicsAdapter::type() const | ||||||
| 
 | 
 | ||||||
| void BochsGraphicsAdapter::unblank() | void BochsGraphicsAdapter::unblank() | ||||||
| { | { | ||||||
|     auto registers = map_typed_writable<volatile BochsDisplayMMIORegisters>(m_mmio_registers); |  | ||||||
|     full_memory_barrier(); |     full_memory_barrier(); | ||||||
|     registers->vga_ioports[0] = 0x20; |     m_registers->vga_ioports[0] = 0x20; | ||||||
|     full_memory_barrier(); |     full_memory_barrier(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -131,18 +131,17 @@ void BochsGraphicsAdapter::set_resolution_registers_via_io(size_t width, size_t | ||||||
| void BochsGraphicsAdapter::set_resolution_registers(size_t width, size_t height) | void BochsGraphicsAdapter::set_resolution_registers(size_t width, size_t height) | ||||||
| { | { | ||||||
|     dbgln_if(BXVGA_DEBUG, "BochsGraphicsAdapter resolution registers set to - {}x{}", width, height); |     dbgln_if(BXVGA_DEBUG, "BochsGraphicsAdapter resolution registers set to - {}x{}", width, height); | ||||||
|     auto registers = map_typed_writable<volatile BochsDisplayMMIORegisters>(m_mmio_registers); |     m_registers->bochs_regs.enable = VBE_DISPI_DISABLED; | ||||||
|     registers->bochs_regs.enable = VBE_DISPI_DISABLED; |  | ||||||
|     full_memory_barrier(); |     full_memory_barrier(); | ||||||
|     registers->bochs_regs.xres = width; |     m_registers->bochs_regs.xres = width; | ||||||
|     registers->bochs_regs.yres = height; |     m_registers->bochs_regs.yres = height; | ||||||
|     registers->bochs_regs.virt_width = width; |     m_registers->bochs_regs.virt_width = width; | ||||||
|     registers->bochs_regs.virt_height = height * 2; |     m_registers->bochs_regs.virt_height = height * 2; | ||||||
|     registers->bochs_regs.bpp = 32; |     m_registers->bochs_regs.bpp = 32; | ||||||
|     full_memory_barrier(); |     full_memory_barrier(); | ||||||
|     registers->bochs_regs.enable = VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED; |     m_registers->bochs_regs.enable = VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED; | ||||||
|     full_memory_barrier(); |     full_memory_barrier(); | ||||||
|     registers->bochs_regs.bank = 0; |     m_registers->bochs_regs.bank = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool BochsGraphicsAdapter::try_to_set_resolution(size_t output_port_index, size_t width, size_t height) | bool BochsGraphicsAdapter::try_to_set_resolution(size_t output_port_index, size_t width, size_t height) | ||||||
|  | @ -181,8 +180,7 @@ bool BochsGraphicsAdapter::validate_setup_resolution_with_io(size_t width, size_ | ||||||
| 
 | 
 | ||||||
| bool BochsGraphicsAdapter::validate_setup_resolution(size_t width, size_t height) | bool BochsGraphicsAdapter::validate_setup_resolution(size_t width, size_t height) | ||||||
| { | { | ||||||
|     auto registers = map_typed_writable<volatile BochsDisplayMMIORegisters>(m_mmio_registers); |     if ((u16)width != m_registers->bochs_regs.xres || (u16)height != m_registers->bochs_regs.yres) { | ||||||
|     if ((u16)width != registers->bochs_regs.xres || (u16)height != registers->bochs_regs.yres) { |  | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|     return true; |     return true; | ||||||
|  | @ -193,8 +191,7 @@ bool BochsGraphicsAdapter::set_y_offset(size_t output_port_index, size_t y_offse | ||||||
|     VERIFY(output_port_index == 0); |     VERIFY(output_port_index == 0); | ||||||
|     if (m_console_enabled) |     if (m_console_enabled) | ||||||
|         return false; |         return false; | ||||||
|     auto registers = map_typed_writable<volatile BochsDisplayMMIORegisters>(m_mmio_registers); |     m_registers->bochs_regs.y_offset = y_offset; | ||||||
|     registers->bochs_regs.y_offset = y_offset; |  | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -203,8 +200,7 @@ void BochsGraphicsAdapter::enable_consoles() | ||||||
|     ScopedSpinLock lock(m_console_mode_switch_lock); |     ScopedSpinLock lock(m_console_mode_switch_lock); | ||||||
|     VERIFY(m_framebuffer_console); |     VERIFY(m_framebuffer_console); | ||||||
|     m_console_enabled = true; |     m_console_enabled = true; | ||||||
|     auto registers = map_typed_writable<volatile BochsDisplayMMIORegisters>(m_mmio_registers); |     m_registers->bochs_regs.y_offset = 0; | ||||||
|     registers->bochs_regs.y_offset = 0; |  | ||||||
|     if (m_framebuffer_device) |     if (m_framebuffer_device) | ||||||
|         m_framebuffer_device->deactivate_writes(); |         m_framebuffer_device->deactivate_writes(); | ||||||
|     m_framebuffer_console->enable(); |     m_framebuffer_console->enable(); | ||||||
|  | @ -215,8 +211,7 @@ void BochsGraphicsAdapter::disable_consoles() | ||||||
|     VERIFY(m_framebuffer_console); |     VERIFY(m_framebuffer_console); | ||||||
|     VERIFY(m_framebuffer_device); |     VERIFY(m_framebuffer_device); | ||||||
|     m_console_enabled = false; |     m_console_enabled = false; | ||||||
|     auto registers = map_typed_writable<volatile BochsDisplayMMIORegisters>(m_mmio_registers); |     m_registers->bochs_regs.y_offset = 0; | ||||||
|     registers->bochs_regs.y_offset = 0; |  | ||||||
|     m_framebuffer_console->disable(); |     m_framebuffer_console->disable(); | ||||||
|     m_framebuffer_device->activate_writes(); |     m_framebuffer_device->activate_writes(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -13,11 +13,14 @@ | ||||||
| #include <Kernel/Graphics/FramebufferDevice.h> | #include <Kernel/Graphics/FramebufferDevice.h> | ||||||
| #include <Kernel/Graphics/GraphicsDevice.h> | #include <Kernel/Graphics/GraphicsDevice.h> | ||||||
| #include <Kernel/PhysicalAddress.h> | #include <Kernel/PhysicalAddress.h> | ||||||
|  | #include <Kernel/VM/TypedMapping.h> | ||||||
| 
 | 
 | ||||||
| namespace Kernel { | namespace Kernel { | ||||||
| 
 | 
 | ||||||
| class BochsFramebufferDevice; | class BochsFramebufferDevice; | ||||||
| class GraphicsManagement; | class GraphicsManagement; | ||||||
|  | struct BochsDisplayMMIORegisters; | ||||||
|  | 
 | ||||||
| class BochsGraphicsAdapter final : public GraphicsDevice | class BochsGraphicsAdapter final : public GraphicsDevice | ||||||
|     , public PCI::DeviceController { |     , public PCI::DeviceController { | ||||||
|     AK_MAKE_ETERNAL |     AK_MAKE_ETERNAL | ||||||
|  | @ -56,6 +59,7 @@ private: | ||||||
|     void set_y_offset(size_t); |     void set_y_offset(size_t); | ||||||
| 
 | 
 | ||||||
|     PhysicalAddress m_mmio_registers; |     PhysicalAddress m_mmio_registers; | ||||||
|  |     TypedMapping<BochsDisplayMMIORegisters volatile> m_registers; | ||||||
|     RefPtr<FramebufferDevice> m_framebuffer_device; |     RefPtr<FramebufferDevice> m_framebuffer_device; | ||||||
|     RefPtr<Graphics::GenericFramebufferConsole> m_framebuffer_console; |     RefPtr<Graphics::GenericFramebufferConsole> m_framebuffer_console; | ||||||
|     SpinLock<u8> m_console_mode_switch_lock; |     SpinLock<u8> m_console_mode_switch_lock; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling