diff options
author | Andreas Kling <kling@serenityos.org> | 2020-01-20 13:07:29 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-01-20 13:13:03 +0100 |
commit | b52d0afecf024f967319dc9ec73421c9f638e5f4 (patch) | |
tree | 4a3cc7d6d9f0c78e855e742d652b3b638d858cd9 /Kernel | |
parent | a0b716cfc5786ec646803b689fad6d3703ddb67a (diff) | |
download | serenity-b52d0afecf024f967319dc9ec73421c9f638e5f4.zip |
SB16: Map the DMA buffer in kernelspace so we can write to it
This broke with the >3GB paging overhaul. It's no longer possible to
write directly to physical addresses below the 8MB mark. Physical pages
need to be mapped into kernel VM by using a Region.
Fixes #1099.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Devices/SB16.cpp | 12 | ||||
-rw-r--r-- | Kernel/Devices/SB16.h | 2 |
2 files changed, 9 insertions, 5 deletions
diff --git a/Kernel/Devices/SB16.cpp b/Kernel/Devices/SB16.cpp index c8f60ab2f7..f015adcc10 100644 --- a/Kernel/Devices/SB16.cpp +++ b/Kernel/Devices/SB16.cpp @@ -27,6 +27,7 @@ #include <Kernel/Devices/SB16.h> #include <Kernel/IO.h> #include <Kernel/Thread.h> +#include <Kernel/VM/AnonymousVMObject.h> #include <Kernel/VM/MemoryManager.h> //#define SB16_DEBUG @@ -123,7 +124,7 @@ ssize_t SB16::read(FileDescription&, u8*, ssize_t) void SB16::dma_start(uint32_t length) { - const auto addr = m_dma_buffer_page->paddr().get(); + const auto addr = m_dma_region->vmobject().physical_pages()[0]->paddr().get(); const u8 channel = 5; // 16-bit samples use DMA channel 5 (on the master DMA controller) const u8 mode = 0; @@ -174,8 +175,11 @@ void SB16::wait_for_irq() ssize_t SB16::write(FileDescription&, const u8* data, ssize_t length) { - if (!m_dma_buffer_page) - m_dma_buffer_page = MM.allocate_supervisor_physical_page(); + if (!m_dma_region) { + auto page = MM.allocate_supervisor_physical_page(); + auto vmobject = AnonymousVMObject::create_with_physical_page(*page); + m_dma_region = MM.allocate_kernel_region_with_vmobject(*vmobject, PAGE_SIZE, "SB16 DMA buffer", Region::Access::Write); + } #ifdef SB16_DEBUG kprintf("SB16: Writing buffer of %d bytes\n", length); @@ -190,7 +194,7 @@ ssize_t SB16::write(FileDescription&, const u8* data, ssize_t length) const int sample_rate = 44100; set_sample_rate(sample_rate); - memcpy(m_dma_buffer_page->paddr().as_ptr(), data, length); + memcpy(m_dma_region->vaddr().as_ptr(), data, length); dma_start(length); // 16-bit single-cycle output. diff --git a/Kernel/Devices/SB16.h b/Kernel/Devices/SB16.h index 7bfc0ef37c..21df353222 100644 --- a/Kernel/Devices/SB16.h +++ b/Kernel/Devices/SB16.h @@ -63,7 +63,7 @@ private: void dsp_write(u8 value); u8 dsp_read(); - RefPtr<PhysicalPage> m_dma_buffer_page; + OwnPtr<Region> m_dma_region; int m_major_version { 0 }; WaitQueue m_irq_queue; |