mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 23:50:19 +00:00
Kernel: Use DMA helper everywhere
Port UCHI, AC97, SB16, BMIDEChannel and AHCIPort to use the helper to allocate DMA buffers.
This commit is contained in:
parent
59da9bd0bd
commit
0a1b34c753
Notes:
sideshowbarker
2024-07-17 21:23:07 +09:00
Author: https://github.com/Panky-codes Commit: https://github.com/SerenityOS/serenity/commit/0a1b34c753e Pull-request: https://github.com/SerenityOS/serenity/pull/11687 Reviewed-by: https://github.com/Quaker762 Reviewed-by: https://github.com/alimpfard
5 changed files with 13 additions and 33 deletions
|
@ -107,9 +107,7 @@ ErrorOr<void> UHCIController::reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let's allocate the physical page for the Frame List (which is 4KiB aligned)
|
// Let's allocate the physical page for the Frame List (which is 4KiB aligned)
|
||||||
auto vmobject = TRY(Memory::AnonymousVMObject::try_create_physically_contiguous_with_size(PAGE_SIZE));
|
m_framelist = TRY(MM.allocate_dma_buffer_page("UHCI Framelist", Memory::Region::Access::Write));
|
||||||
|
|
||||||
m_framelist = TRY(MM.allocate_kernel_region_with_vmobject(move(vmobject), PAGE_SIZE, "UHCI Framelist", Memory::Region::Access::Write));
|
|
||||||
dbgln("UHCI: Allocated framelist at physical address {}", m_framelist->physical_page(0)->paddr());
|
dbgln("UHCI: Allocated framelist at physical address {}", m_framelist->physical_page(0)->paddr());
|
||||||
dbgln("UHCI: Framelist is at virtual address {}", m_framelist->vaddr());
|
dbgln("UHCI: Framelist is at virtual address {}", m_framelist->vaddr());
|
||||||
write_sofmod(64); // 1mS frame time
|
write_sofmod(64); // 1mS frame time
|
||||||
|
@ -141,11 +139,9 @@ UNMAP_AFTER_INIT ErrorOr<void> UHCIController::create_structures()
|
||||||
m_dummy_qh = allocate_queue_head();
|
m_dummy_qh = allocate_queue_head();
|
||||||
|
|
||||||
// Now the Transfer Descriptor pool
|
// Now the Transfer Descriptor pool
|
||||||
auto td_pool_vmobject = TRY(Memory::AnonymousVMObject::try_create_physically_contiguous_with_size(PAGE_SIZE));
|
|
||||||
|
|
||||||
m_transfer_descriptor_pool = TRY(UHCIDescriptorPool<TransferDescriptor>::try_create("Transfer Descriptor Pool"sv));
|
m_transfer_descriptor_pool = TRY(UHCIDescriptorPool<TransferDescriptor>::try_create("Transfer Descriptor Pool"sv));
|
||||||
|
|
||||||
m_isochronous_transfer_pool = TRY(MM.allocate_kernel_region_with_vmobject(move(td_pool_vmobject), PAGE_SIZE, "UHCI Isochronous Descriptor Pool", Memory::Region::Access::ReadWrite));
|
m_isochronous_transfer_pool = TRY(MM.allocate_dma_buffer_page("UHCI Isochronous Descriptor Pool", Memory::Region::Access::ReadWrite));
|
||||||
|
|
||||||
// Set up the Isochronous Transfer Descriptor list
|
// Set up the Isochronous Transfer Descriptor list
|
||||||
m_iso_td_list.resize(UHCI_NUMBER_OF_ISOCHRONOUS_TDS);
|
m_iso_td_list.resize(UHCI_NUMBER_OF_ISOCHRONOUS_TDS);
|
||||||
|
|
|
@ -20,13 +20,6 @@ static constexpr u16 pcm_fixed_sample_rate = 48000;
|
||||||
static constexpr u16 pcm_sample_rate_minimum = 8000;
|
static constexpr u16 pcm_sample_rate_minimum = 8000;
|
||||||
static constexpr u16 pcm_sample_rate_maximum = 48000;
|
static constexpr u16 pcm_sample_rate_maximum = 48000;
|
||||||
|
|
||||||
static ErrorOr<OwnPtr<Memory::Region>> allocate_physical_buffer(size_t size, StringView name)
|
|
||||||
{
|
|
||||||
auto rounded_size = TRY(Memory::page_round_up(size));
|
|
||||||
auto vmobject = TRY(Memory::AnonymousVMObject::try_create_physically_contiguous_with_size(rounded_size));
|
|
||||||
return TRY(MM.allocate_kernel_region_with_vmobject(move(vmobject), vmobject->size(), name, Memory::Region::Access::Write));
|
|
||||||
}
|
|
||||||
|
|
||||||
UNMAP_AFTER_INIT void AC97::detect()
|
UNMAP_AFTER_INIT void AC97::detect()
|
||||||
{
|
{
|
||||||
PCI::enumerate([&](PCI::DeviceIdentifier const& device_identifier) {
|
PCI::enumerate([&](PCI::DeviceIdentifier const& device_identifier) {
|
||||||
|
@ -204,11 +197,11 @@ void AC97::set_pcm_output_volume(u8 left_channel, u8 right_channel, Muted mute)
|
||||||
ErrorOr<size_t> AC97::write(OpenFileDescription&, u64, UserOrKernelBuffer const& data, size_t length)
|
ErrorOr<size_t> AC97::write(OpenFileDescription&, u64, UserOrKernelBuffer const& data, size_t length)
|
||||||
{
|
{
|
||||||
if (!m_output_buffer) {
|
if (!m_output_buffer) {
|
||||||
m_output_buffer = TRY(allocate_physical_buffer(m_output_buffer_page_count * PAGE_SIZE, "AC97 Output buffer"sv));
|
m_output_buffer = TRY(MM.allocate_dma_buffer_pages(m_output_buffer_page_count * PAGE_SIZE, "AC97 Output buffer"sv, Memory::Region::Access::Write));
|
||||||
}
|
}
|
||||||
if (!m_buffer_descriptor_list) {
|
if (!m_buffer_descriptor_list) {
|
||||||
constexpr size_t buffer_descriptor_list_size = buffer_descriptor_list_max_entries * sizeof(BufferDescriptorListEntry);
|
constexpr size_t buffer_descriptor_list_size = buffer_descriptor_list_max_entries * sizeof(BufferDescriptorListEntry);
|
||||||
m_buffer_descriptor_list = TRY(allocate_physical_buffer(buffer_descriptor_list_size, "AC97 Buffer Descriptor List"sv));
|
m_buffer_descriptor_list = TRY(MM.allocate_dma_buffer_pages(buffer_descriptor_list_size, "AC97 Buffer Descriptor List"sv, Memory::Region::Access::Write));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto remaining = length;
|
auto remaining = length;
|
||||||
|
|
|
@ -252,12 +252,7 @@ void SB16::wait_for_irq()
|
||||||
ErrorOr<size_t> SB16::write(OpenFileDescription&, u64, UserOrKernelBuffer const& data, size_t length)
|
ErrorOr<size_t> SB16::write(OpenFileDescription&, u64, UserOrKernelBuffer const& data, size_t length)
|
||||||
{
|
{
|
||||||
if (!m_dma_region) {
|
if (!m_dma_region) {
|
||||||
auto page = MM.allocate_supervisor_physical_page();
|
m_dma_region = TRY(MM.allocate_dma_buffer_page("SB16 DMA buffer", Memory::Region::Access::Write));
|
||||||
if (!page)
|
|
||||||
return ENOMEM;
|
|
||||||
auto nonnull_page = page.release_nonnull();
|
|
||||||
auto vmobject = TRY(Memory::AnonymousVMObject::try_create_with_physical_pages({ &nonnull_page, 1 }));
|
|
||||||
m_dma_region = TRY(MM.allocate_kernel_region_with_vmobject(move(vmobject), PAGE_SIZE, "SB16 DMA buffer", Memory::Region::Access::Write));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dbgln_if(SB16_DEBUG, "SB16: Writing buffer of {} bytes", length);
|
dbgln_if(SB16_DEBUG, "SB16: Writing buffer of {} bytes", length);
|
||||||
|
|
|
@ -37,14 +37,10 @@ AHCIPort::AHCIPort(const AHCIPortHandler& handler, volatile AHCI::PortRegisters&
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_command_list_page = MM.allocate_supervisor_physical_page();
|
|
||||||
m_fis_receive_page = MM.allocate_supervisor_physical_page();
|
m_fis_receive_page = MM.allocate_supervisor_physical_page();
|
||||||
if (m_command_list_page.is_null() || m_fis_receive_page.is_null())
|
if (m_fis_receive_page.is_null())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dbgln_if(AHCI_DEBUG, "AHCI Port {}: Command list page at {}", representative_port_index(), m_command_list_page->paddr());
|
|
||||||
dbgln_if(AHCI_DEBUG, "AHCI Port {}: FIS receive page at {}", representative_port_index(), m_command_list_page->paddr());
|
|
||||||
|
|
||||||
for (size_t index = 0; index < 1; index++) {
|
for (size_t index = 0; index < 1; index++) {
|
||||||
m_dma_buffers.append(MM.allocate_supervisor_physical_page().release_nonnull());
|
m_dma_buffers.append(MM.allocate_supervisor_physical_page().release_nonnull());
|
||||||
}
|
}
|
||||||
|
@ -52,7 +48,11 @@ AHCIPort::AHCIPort(const AHCIPortHandler& handler, volatile AHCI::PortRegisters&
|
||||||
m_command_table_pages.append(MM.allocate_supervisor_physical_page().release_nonnull());
|
m_command_table_pages.append(MM.allocate_supervisor_physical_page().release_nonnull());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto region_or_error = MM.allocate_kernel_region(m_command_list_page->paddr(), PAGE_SIZE, "AHCI Port Command List", Memory::Region::Access::ReadWrite, Memory::Region::Cacheable::No);
|
auto region_or_error = MM.allocate_dma_buffer_page("AHCI Port Command List", Memory::Region::Access::ReadWrite, m_command_list_page);
|
||||||
|
|
||||||
|
dbgln_if(AHCI_DEBUG, "AHCI Port {}: Command list page at {}", representative_port_index(), m_command_list_page->paddr());
|
||||||
|
dbgln_if(AHCI_DEBUG, "AHCI Port {}: FIS receive page at {}", representative_port_index(), m_fis_receive_page->paddr());
|
||||||
|
|
||||||
if (region_or_error.is_error())
|
if (region_or_error.is_error())
|
||||||
TODO();
|
TODO();
|
||||||
m_command_list_region = region_or_error.release_value();
|
m_command_list_region = region_or_error.release_value();
|
||||||
|
|
|
@ -40,18 +40,14 @@ UNMAP_AFTER_INIT void BMIDEChannel::initialize()
|
||||||
VERIFY(m_io_group.bus_master_base().has_value());
|
VERIFY(m_io_group.bus_master_base().has_value());
|
||||||
// Let's try to set up DMA transfers.
|
// Let's try to set up DMA transfers.
|
||||||
PCI::enable_bus_mastering(m_parent_controller->pci_address());
|
PCI::enable_bus_mastering(m_parent_controller->pci_address());
|
||||||
m_prdt_page = MM.allocate_supervisor_physical_page();
|
|
||||||
m_dma_buffer_page = MM.allocate_supervisor_physical_page();
|
|
||||||
if (m_dma_buffer_page.is_null() || m_prdt_page.is_null())
|
|
||||||
return;
|
|
||||||
{
|
{
|
||||||
auto region_or_error = MM.allocate_kernel_region(m_prdt_page->paddr(), PAGE_SIZE, "IDE PRDT", Memory::Region::Access::ReadWrite);
|
auto region_or_error = MM.allocate_dma_buffer_page("IDE PRDT", Memory::Region::Access::ReadWrite, m_prdt_page);
|
||||||
if (region_or_error.is_error())
|
if (region_or_error.is_error())
|
||||||
TODO();
|
TODO();
|
||||||
m_prdt_region = region_or_error.release_value();
|
m_prdt_region = region_or_error.release_value();
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto region_or_error = MM.allocate_kernel_region(m_dma_buffer_page->paddr(), PAGE_SIZE, "IDE DMA region", Memory::Region::Access::ReadWrite);
|
auto region_or_error = MM.allocate_dma_buffer_page("IDE DMA region", Memory::Region::Access::ReadWrite, m_dma_buffer_page);
|
||||||
if (region_or_error.is_error())
|
if (region_or_error.is_error())
|
||||||
TODO();
|
TODO();
|
||||||
m_dma_buffer_region = region_or_error.release_value();
|
m_dma_buffer_region = region_or_error.release_value();
|
||||||
|
|
Loading…
Reference in a new issue