summaryrefslogtreecommitdiff
path: root/Kernel/Devices
diff options
context:
space:
mode:
authorJesse Buhagiar <jesse.buhagiar@student.rmit.edu.au>2019-11-21 16:08:11 +1100
committerAndreas Kling <awesomekling@gmail.com>2019-11-22 16:23:23 +0100
commitbd33c6627394b2166e1419965dd3b2d2dc0c401f (patch)
treec1c8287e55ae218172560e5c7b991918ef645df6 /Kernel/Devices
parent61ba19f031360f4b6219204021c1ffb0d6932f4f (diff)
downloadserenity-bd33c6627394b2166e1419965dd3b2d2dc0c401f.zip
Kernel: Move Kernel mapping to 0xc0000000
The kernel is now no longer identity mapped to the bottom 8MiB of memory, and is now mapped at the higher address of `0xc0000000`. The lower ~1MiB of memory (from GRUB's mmap), however is still identity mapped to provide an easy way for the kernel to get physical pages for things such as DMA etc. These could later be mapped to the higher address too, as I'm not too sure how to go about doing this elegantly without a lot of address subtractions.
Diffstat (limited to 'Kernel/Devices')
-rw-r--r--Kernel/Devices/PATAChannel.cpp20
-rw-r--r--Kernel/Devices/PATAChannel.h4
2 files changed, 14 insertions, 10 deletions
diff --git a/Kernel/Devices/PATAChannel.cpp b/Kernel/Devices/PATAChannel.cpp
index 5e2fb84cb2..0cde8e7c9d 100644
--- a/Kernel/Devices/PATAChannel.cpp
+++ b/Kernel/Devices/PATAChannel.cpp
@@ -116,11 +116,13 @@ void PATAChannel::initialize(bool force_pio)
kprintf("PATAChannel: PATA Controller found! id=%w:%w\n", id.vendor_id, id.device_id);
}
});
+
+ m_prdt_page = MM.allocate_supervisor_physical_page();
m_force_pio.resource() = false;
if (!m_pci_address.is_null()) {
// Let's try to set up DMA transfers.
PCI::enable_bus_mastering(m_pci_address);
- m_prdt.end_of_table = 0x8000;
+ prdt().end_of_table = 0x8000;
m_bus_master_base = PCI::get_BAR4(m_pci_address) & 0xfffc;
m_dma_buffer_page = MM.allocate_supervisor_physical_page();
kprintf("PATAChannel: Bus master IDE: I/O @ %x\n", m_bus_master_base);
@@ -259,16 +261,16 @@ bool PATAChannel::ata_read_sectors_with_dma(u32 lba, u16 count, u8* outbuf, bool
disable_irq();
- m_prdt.offset = m_dma_buffer_page->paddr();
- m_prdt.size = 512 * count;
+ prdt().offset = m_dma_buffer_page->paddr();
+ prdt().size = 512 * count;
- ASSERT(m_prdt.size <= PAGE_SIZE);
+ ASSERT(prdt().size <= PAGE_SIZE);
// Stop bus master
IO::out8(m_bus_master_base, 0);
// Write the PRDT location
- IO::out32(m_bus_master_base + 4, (u32)&m_prdt);
+ IO::out32(m_bus_master_base + 4, (u32)&prdt());
// Turn on "Interrupt" and "Error" flag. The error flag should be cleared by hardware.
IO::out8(m_bus_master_base + 2, IO::in8(m_bus_master_base + 2) | 0x6);
@@ -338,18 +340,18 @@ bool PATAChannel::ata_write_sectors_with_dma(u32 lba, u16 count, const u8* inbuf
disable_irq();
- m_prdt.offset = m_dma_buffer_page->paddr();
- m_prdt.size = 512 * count;
+ prdt().offset = m_dma_buffer_page->paddr();
+ prdt().size = 512 * count;
memcpy(m_dma_buffer_page->paddr().as_ptr(), inbuf, 512 * count);
- ASSERT(m_prdt.size <= PAGE_SIZE);
+ ASSERT(prdt().size <= PAGE_SIZE);
// Stop bus master
IO::out8(m_bus_master_base, 0);
// Write the PRDT location
- IO::out32(m_bus_master_base + 4, (u32)&m_prdt);
+ IO::out32(m_bus_master_base + 4, (u32)&prdt());
// Turn on "Interrupt" and "Error" flag. The error flag should be cleared by hardware.
IO::out8(m_bus_master_base + 2, IO::in8(m_bus_master_base + 2) | 0x6);
diff --git a/Kernel/Devices/PATAChannel.h b/Kernel/Devices/PATAChannel.h
index 0806c2fa8c..7a1a4ca1a0 100644
--- a/Kernel/Devices/PATAChannel.h
+++ b/Kernel/Devices/PATAChannel.h
@@ -55,6 +55,8 @@ private:
bool ata_read_sectors(u32, u16, u8*, bool);
bool ata_write_sectors(u32, u16, const u8*, bool);
+ PhysicalRegionDescriptor& prdt() { return *reinterpret_cast<PhysicalRegionDescriptor*>(m_prdt_page->paddr().as_ptr()); }
+
// Data members
u8 m_channel_number { 0 }; // Channel number. 0 = master, 1 = slave
u16 m_io_base { 0x1F0 };
@@ -63,7 +65,7 @@ private:
volatile bool m_interrupted { false };
PCI::Address m_pci_address;
- PhysicalRegionDescriptor m_prdt;
+ RefPtr<PhysicalPage> m_prdt_page;
RefPtr<PhysicalPage> m_dma_buffer_page;
u16 m_bus_master_base { 0 };
Lockable<bool> m_dma_enabled;