summaryrefslogtreecommitdiff
path: root/Kernel/Devices
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-01-20 13:07:29 +0100
committerAndreas Kling <kling@serenityos.org>2020-01-20 13:13:03 +0100
commitb52d0afecf024f967319dc9ec73421c9f638e5f4 (patch)
tree4a3cc7d6d9f0c78e855e742d652b3b638d858cd9 /Kernel/Devices
parenta0b716cfc5786ec646803b689fad6d3703ddb67a (diff)
downloadserenity-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/Devices')
-rw-r--r--Kernel/Devices/SB16.cpp12
-rw-r--r--Kernel/Devices/SB16.h2
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;