mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:47:44 +00:00
Kernel/Graphics: Allocate 16 MiB framebuffer if failed allocating larger
We try our best to ensure a DisplayConnector initialization succeeds, and this makes the Intel driver to work again, because if we can't allocate a Region for the whole PCI BAR mapped region, then we will try to allocate a Region with 16 MiB window size, so it doesn't eat the entire Kernel-allocated virtual memory space.
This commit is contained in:
parent
25bb293629
commit
7625f7db73
2 changed files with 29 additions and 12 deletions
|
@ -74,6 +74,23 @@ void DisplayConnector::will_be_destroyed()
|
||||||
before_will_be_destroyed_remove_from_device_management();
|
before_will_be_destroyed_remove_from_device_management();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorOr<void> DisplayConnector::allocate_framebuffer_resources(size_t rounded_size)
|
||||||
|
{
|
||||||
|
VERIFY((rounded_size % PAGE_SIZE) == 0);
|
||||||
|
if (!m_framebuffer_at_arbitrary_physical_range) {
|
||||||
|
VERIFY(m_framebuffer_address.value().page_base() == m_framebuffer_address.value());
|
||||||
|
m_shared_framebuffer_vmobject = TRY(Memory::SharedFramebufferVMObject::try_create_for_physical_range(m_framebuffer_address.value(), rounded_size));
|
||||||
|
m_framebuffer_region = TRY(MM.allocate_kernel_region(m_framebuffer_address.value().page_base(), rounded_size, "Framebuffer"sv, Memory::Region::Access::ReadWrite));
|
||||||
|
} else {
|
||||||
|
m_shared_framebuffer_vmobject = TRY(Memory::SharedFramebufferVMObject::try_create_at_arbitrary_physical_range(rounded_size));
|
||||||
|
m_framebuffer_region = TRY(MM.allocate_kernel_region_with_vmobject(m_shared_framebuffer_vmobject->real_writes_framebuffer_vmobject(), rounded_size, "Framebuffer"sv, Memory::Region::Access::ReadWrite));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_framebuffer_data = m_framebuffer_region->vaddr().as_ptr();
|
||||||
|
m_fake_writes_framebuffer_region = TRY(MM.allocate_kernel_region_with_vmobject(m_shared_framebuffer_vmobject->fake_writes_framebuffer_vmobject(), rounded_size, "Fake Writes Framebuffer"sv, Memory::Region::Access::ReadWrite));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
ErrorOr<void> DisplayConnector::after_inserting()
|
ErrorOr<void> DisplayConnector::after_inserting()
|
||||||
{
|
{
|
||||||
after_inserting_add_to_device_management();
|
after_inserting_add_to_device_management();
|
||||||
|
@ -99,20 +116,18 @@ ErrorOr<void> DisplayConnector::after_inserting()
|
||||||
m_symlink_sysfs_component.clear();
|
m_symlink_sysfs_component.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
auto rounded_size = TRY(Memory::page_round_up(m_framebuffer_resource_size));
|
if (auto result_or_error = Memory::page_round_up(m_framebuffer_resource_size); result_or_error.is_error()) {
|
||||||
|
// NOTE: The amount of framebuffer resource being specified is erroneous, then default to 16 MiB.
|
||||||
if (!m_framebuffer_at_arbitrary_physical_range) {
|
TRY(allocate_framebuffer_resources(16 * MiB));
|
||||||
VERIFY(m_framebuffer_address.value().page_base() == m_framebuffer_address.value());
|
m_framebuffer_resource_size = 16 * MiB;
|
||||||
m_shared_framebuffer_vmobject = TRY(Memory::SharedFramebufferVMObject::try_create_for_physical_range(m_framebuffer_address.value(), rounded_size));
|
|
||||||
m_framebuffer_region = TRY(MM.allocate_kernel_region(m_framebuffer_address.value().page_base(), rounded_size, "Framebuffer"sv, Memory::Region::Access::ReadWrite));
|
|
||||||
} else {
|
} else {
|
||||||
m_shared_framebuffer_vmobject = TRY(Memory::SharedFramebufferVMObject::try_create_at_arbitrary_physical_range(rounded_size));
|
if (auto allocation_result = allocate_framebuffer_resources(result_or_error.release_value()); allocation_result.is_error()) {
|
||||||
m_framebuffer_region = TRY(MM.allocate_kernel_region_with_vmobject(m_shared_framebuffer_vmobject->real_writes_framebuffer_vmobject(), rounded_size, "Framebuffer"sv, Memory::Region::Access::ReadWrite));
|
// NOTE: The amount of framebuffer resource being specified is too big, use 16 MiB just to get going.
|
||||||
|
TRY(allocate_framebuffer_resources(16 * MiB));
|
||||||
|
m_framebuffer_resource_size = 16 * MiB;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_framebuffer_data = m_framebuffer_region->vaddr().as_ptr();
|
|
||||||
m_fake_writes_framebuffer_region = TRY(MM.allocate_kernel_region_with_vmobject(m_shared_framebuffer_vmobject->fake_writes_framebuffer_vmobject(), rounded_size, "Fake Writes Framebuffer"sv, Memory::Region::Access::ReadWrite));
|
|
||||||
|
|
||||||
clean_from_device_management.disarm();
|
clean_from_device_management.disarm();
|
||||||
clean_from_sysfs_display_connector_device_directory.disarm();
|
clean_from_sysfs_display_connector_device_directory.disarm();
|
||||||
clean_symlink_to_device_identifier_directory.disarm();
|
clean_symlink_to_device_identifier_directory.disarm();
|
||||||
|
|
|
@ -148,6 +148,8 @@ private:
|
||||||
virtual void will_be_destroyed() override;
|
virtual void will_be_destroyed() override;
|
||||||
virtual ErrorOr<void> after_inserting() override;
|
virtual ErrorOr<void> after_inserting() override;
|
||||||
|
|
||||||
|
ErrorOr<void> allocate_framebuffer_resources(size_t rounded_size);
|
||||||
|
|
||||||
ErrorOr<bool> ioctl_requires_ownership(unsigned request) const;
|
ErrorOr<bool> ioctl_requires_ownership(unsigned request) const;
|
||||||
|
|
||||||
OwnPtr<Memory::Region> m_framebuffer_region;
|
OwnPtr<Memory::Region> m_framebuffer_region;
|
||||||
|
@ -159,7 +161,7 @@ private:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Optional<PhysicalAddress> const m_framebuffer_address;
|
Optional<PhysicalAddress> const m_framebuffer_address;
|
||||||
size_t const m_framebuffer_resource_size;
|
size_t m_framebuffer_resource_size;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LockRefPtr<Memory::SharedFramebufferVMObject> m_shared_framebuffer_vmobject;
|
LockRefPtr<Memory::SharedFramebufferVMObject> m_shared_framebuffer_vmobject;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue