mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:47:44 +00:00
Kernel: Make Kernel::VMObject allocation functions return KResultOr
This makes for nicer handling of errors compared to checking whether a RefPtr is null. Additionally, this will give way to return different types of errors in the future.
This commit is contained in:
parent
61c0e3ca92
commit
4bfd6e41b9
26 changed files with 194 additions and 122 deletions
|
@ -88,7 +88,8 @@ UNMAP_AFTER_INIT void BochsGraphicsAdapter::initialize_framebuffer_devices()
|
|||
{
|
||||
// FIXME: Find a better way to determine default resolution...
|
||||
m_framebuffer_device = FramebufferDevice::create(*this, 0, PhysicalAddress(PCI::get_BAR0(pci_address()) & 0xfffffff0), 1024, 768, 1024 * sizeof(u32));
|
||||
m_framebuffer_device->initialize();
|
||||
// FIXME: Would be nice to be able to return a KResult here.
|
||||
VERIFY(!m_framebuffer_device->initialize().is_error());
|
||||
}
|
||||
|
||||
GraphicsDevice::Type BochsGraphicsAdapter::type() const
|
||||
|
|
|
@ -36,18 +36,20 @@ KResultOr<Memory::Region*> FramebufferDevice::mmap(Process& process, FileDescrip
|
|||
if (range.size() != Memory::page_round_up(framebuffer_size_in_bytes()))
|
||||
return EOVERFLOW;
|
||||
|
||||
auto vmobject = Memory::AnonymousVMObject::try_create_for_physical_range(m_framebuffer_address, Memory::page_round_up(framebuffer_size_in_bytes()));
|
||||
if (!vmobject)
|
||||
return ENOMEM;
|
||||
m_userspace_real_framebuffer_vmobject = vmobject;
|
||||
auto maybe_vmobject = Memory::AnonymousVMObject::try_create_for_physical_range(m_framebuffer_address, Memory::page_round_up(framebuffer_size_in_bytes()));
|
||||
if (maybe_vmobject.is_error())
|
||||
return maybe_vmobject.error();
|
||||
m_userspace_real_framebuffer_vmobject = maybe_vmobject.release_value();
|
||||
|
||||
m_real_framebuffer_vmobject = Memory::AnonymousVMObject::try_create_for_physical_range(m_framebuffer_address, Memory::page_round_up(framebuffer_size_in_bytes()));
|
||||
if (!m_real_framebuffer_vmobject)
|
||||
return ENOMEM;
|
||||
auto maybe_real_framebuffer_vmobject = Memory::AnonymousVMObject::try_create_for_physical_range(m_framebuffer_address, Memory::page_round_up(framebuffer_size_in_bytes()));
|
||||
if (maybe_real_framebuffer_vmobject.is_error())
|
||||
return maybe_real_framebuffer_vmobject.error();
|
||||
m_real_framebuffer_vmobject = maybe_real_framebuffer_vmobject.release_value();
|
||||
|
||||
m_swapped_framebuffer_vmobject = Memory::AnonymousVMObject::try_create_with_size(Memory::page_round_up(framebuffer_size_in_bytes()), AllocationStrategy::AllocateNow);
|
||||
if (!m_swapped_framebuffer_vmobject)
|
||||
return ENOMEM;
|
||||
auto maybe_swapped_framebuffer_vmobject = Memory::AnonymousVMObject::try_create_with_size(Memory::page_round_up(framebuffer_size_in_bytes()), AllocationStrategy::AllocateNow);
|
||||
if (maybe_swapped_framebuffer_vmobject.is_error())
|
||||
return maybe_swapped_framebuffer_vmobject.error();
|
||||
m_swapped_framebuffer_vmobject = maybe_swapped_framebuffer_vmobject.release_value();
|
||||
|
||||
m_real_framebuffer_region = MM.allocate_kernel_region_with_vmobject(*m_real_framebuffer_vmobject, Memory::page_round_up(framebuffer_size_in_bytes()), "Framebuffer", Memory::Region::Access::ReadWrite);
|
||||
if (!m_real_framebuffer_region)
|
||||
|
@ -107,16 +109,29 @@ String FramebufferDevice::device_name() const
|
|||
return String::formatted("fb{}", minor());
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT void FramebufferDevice::initialize()
|
||||
UNMAP_AFTER_INIT KResult FramebufferDevice::initialize()
|
||||
{
|
||||
m_real_framebuffer_vmobject = Memory::AnonymousVMObject::try_create_for_physical_range(m_framebuffer_address, Memory::page_round_up(framebuffer_size_in_bytes()));
|
||||
VERIFY(m_real_framebuffer_vmobject);
|
||||
// FIXME: Would be nice to be able to unify this with mmap above, but this
|
||||
// function is UNMAP_AFTER_INIT for the time being.
|
||||
auto maybe_real_framebuffer_vmobject = Memory::AnonymousVMObject::try_create_for_physical_range(m_framebuffer_address, Memory::page_round_up(framebuffer_size_in_bytes()));
|
||||
if (maybe_real_framebuffer_vmobject.is_error())
|
||||
return maybe_real_framebuffer_vmobject.error();
|
||||
m_real_framebuffer_vmobject = maybe_real_framebuffer_vmobject.release_value();
|
||||
|
||||
auto maybe_swapped_framebuffer_vmobject = Memory::AnonymousVMObject::try_create_with_size(Memory::page_round_up(framebuffer_size_in_bytes()), AllocationStrategy::AllocateNow);
|
||||
if (maybe_swapped_framebuffer_vmobject.is_error())
|
||||
return maybe_swapped_framebuffer_vmobject.error();
|
||||
m_swapped_framebuffer_vmobject = maybe_swapped_framebuffer_vmobject.release_value();
|
||||
|
||||
m_real_framebuffer_region = MM.allocate_kernel_region_with_vmobject(*m_real_framebuffer_vmobject, Memory::page_round_up(framebuffer_size_in_bytes()), "Framebuffer", Memory::Region::Access::ReadWrite);
|
||||
VERIFY(m_real_framebuffer_region);
|
||||
m_swapped_framebuffer_vmobject = Memory::AnonymousVMObject::try_create_with_size(Memory::page_round_up(framebuffer_size_in_bytes()), AllocationStrategy::AllocateNow);
|
||||
VERIFY(m_swapped_framebuffer_vmobject);
|
||||
if (!m_real_framebuffer_region)
|
||||
return ENOMEM;
|
||||
|
||||
m_swapped_framebuffer_region = MM.allocate_kernel_region_with_vmobject(*m_swapped_framebuffer_vmobject, Memory::page_round_up(framebuffer_size_in_bytes()), "Framebuffer Swap (Blank)", Memory::Region::Access::ReadWrite);
|
||||
VERIFY(m_swapped_framebuffer_region);
|
||||
if (!m_swapped_framebuffer_region)
|
||||
return ENOMEM;
|
||||
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT FramebufferDevice::FramebufferDevice(const GraphicsDevice& adapter, size_t output_port_index, PhysicalAddress addr, size_t width, size_t height, size_t pitch)
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
size_t framebuffer_size_in_bytes() const;
|
||||
|
||||
virtual ~FramebufferDevice() {};
|
||||
void initialize();
|
||||
KResult initialize();
|
||||
|
||||
private:
|
||||
// ^File
|
||||
|
|
|
@ -639,6 +639,7 @@ void IntelNativeGraphicsAdapter::initialize_framebuffer_devices()
|
|||
VERIFY(m_framebuffer_height != 0);
|
||||
VERIFY(m_framebuffer_width != 0);
|
||||
m_framebuffer_device = FramebufferDevice::create(*this, 0, address, m_framebuffer_width, m_framebuffer_height, m_framebuffer_pitch);
|
||||
m_framebuffer_device->initialize();
|
||||
// FIXME: Would be nice to be able to return a KResult here.
|
||||
VERIFY(!m_framebuffer_device->initialize().is_error());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,8 @@ UNMAP_AFTER_INIT void VGACompatibleAdapter::initialize_framebuffer_devices()
|
|||
VERIFY(m_framebuffer_height != 0);
|
||||
VERIFY(m_framebuffer_pitch != 0);
|
||||
m_framebuffer_device = FramebufferDevice::create(*this, 0, m_framebuffer_address, m_framebuffer_width, m_framebuffer_height, m_framebuffer_pitch);
|
||||
m_framebuffer_device->initialize();
|
||||
// FIXME: Would be nice to be able to return KResult here.
|
||||
VERIFY(!m_framebuffer_device->initialize().is_error());
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT VGACompatibleAdapter::VGACompatibleAdapter(PCI::Address address)
|
||||
|
|
|
@ -15,15 +15,18 @@ FrameBufferDevice::FrameBufferDevice(GPU& virtio_gpu, ScanoutID scanout)
|
|||
, m_gpu(virtio_gpu)
|
||||
, m_scanout(scanout)
|
||||
{
|
||||
if (display_info().enabled)
|
||||
create_framebuffer();
|
||||
if (display_info().enabled) {
|
||||
// FIXME: This should be in a place where we can handle allocation failures.
|
||||
auto result = create_framebuffer();
|
||||
VERIFY(!result.is_error());
|
||||
}
|
||||
}
|
||||
|
||||
FrameBufferDevice::~FrameBufferDevice()
|
||||
{
|
||||
}
|
||||
|
||||
void FrameBufferDevice::create_framebuffer()
|
||||
KResult FrameBufferDevice::create_framebuffer()
|
||||
{
|
||||
// First delete any existing framebuffers to free the memory first
|
||||
m_framebuffer = nullptr;
|
||||
|
@ -40,12 +43,17 @@ void FrameBufferDevice::create_framebuffer()
|
|||
for (auto i = 0u; i < num_needed_pages; ++i) {
|
||||
pages.append(write_sink_page);
|
||||
}
|
||||
m_framebuffer_sink_vmobject = Memory::AnonymousVMObject::try_create_with_physical_pages(pages.span());
|
||||
auto maybe_framebuffer_sink_vmobject = Memory::AnonymousVMObject::try_create_with_physical_pages(pages.span());
|
||||
if (maybe_framebuffer_sink_vmobject.is_error())
|
||||
return maybe_framebuffer_sink_vmobject.error();
|
||||
m_framebuffer_sink_vmobject = maybe_framebuffer_sink_vmobject.release_value();
|
||||
|
||||
MutexLocker locker(m_gpu.operation_lock());
|
||||
m_current_buffer = &buffer_from_index(m_last_set_buffer_index.load());
|
||||
create_buffer(m_main_buffer, 0, m_buffer_size);
|
||||
create_buffer(m_back_buffer, m_buffer_size, m_buffer_size);
|
||||
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
void FrameBufferDevice::create_buffer(Buffer& buffer, size_t framebuffer_offset, size_t framebuffer_size)
|
||||
|
@ -124,7 +132,10 @@ bool FrameBufferDevice::try_to_set_resolution(size_t width, size_t height)
|
|||
.width = (u32)width,
|
||||
.height = (u32)height,
|
||||
};
|
||||
create_framebuffer();
|
||||
|
||||
// FIXME: Would be nice to be able to return KResultOr here.
|
||||
if (auto result = create_framebuffer(); result.is_error())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -255,9 +266,18 @@ KResultOr<Memory::Region*> FrameBufferDevice::mmap(Process& process, FileDescrip
|
|||
if (m_userspace_mmap_region)
|
||||
return ENOMEM;
|
||||
|
||||
auto vmobject = m_are_writes_active ? m_framebuffer->vmobject().try_clone() : m_framebuffer_sink_vmobject;
|
||||
if (vmobject.is_null())
|
||||
return ENOMEM;
|
||||
RefPtr<Memory::VMObject> vmobject;
|
||||
if (m_are_writes_active) {
|
||||
auto maybe_vmobject = m_framebuffer->vmobject().try_clone();
|
||||
if (maybe_vmobject.is_error())
|
||||
return maybe_vmobject.error();
|
||||
|
||||
vmobject = maybe_vmobject.release_value();
|
||||
} else {
|
||||
vmobject = m_framebuffer_sink_vmobject;
|
||||
if (vmobject.is_null())
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
auto result = process.address_space().allocate_region_with_vmobject(
|
||||
range,
|
||||
|
@ -277,9 +297,10 @@ void FrameBufferDevice::deactivate_writes()
|
|||
m_are_writes_active = false;
|
||||
if (m_userspace_mmap_region) {
|
||||
auto* region = m_userspace_mmap_region.unsafe_ptr();
|
||||
auto vm_object = m_framebuffer_sink_vmobject->try_clone();
|
||||
VERIFY(vm_object);
|
||||
region->set_vmobject(vm_object.release_nonnull());
|
||||
auto maybe_vm_object = m_framebuffer_sink_vmobject->try_clone();
|
||||
// FIXME: Would be nice to be able to return a KResult here.
|
||||
VERIFY(!maybe_vm_object.is_error());
|
||||
region->set_vmobject(maybe_vm_object.release_value());
|
||||
region->remap();
|
||||
}
|
||||
set_buffer(0);
|
||||
|
|
|
@ -56,7 +56,7 @@ private:
|
|||
Protocol::DisplayInfoResponse::Display const& display_info() const;
|
||||
Protocol::DisplayInfoResponse::Display& display_info();
|
||||
|
||||
void create_framebuffer();
|
||||
KResult create_framebuffer();
|
||||
void create_buffer(Buffer&, size_t, size_t);
|
||||
void set_buffer(int);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue