|
miniOS
x86_64 hobby kernel with SMP, VFS, and POSIX process model
|
#include <miniOS/drivers/ata.h>#include <miniOS/drivers/pci.h>#include <miniOS/arch/x86_64/port.h>#include <miniOS/mm/pmm.h>#include <miniOS/mm/vmm.h>#include <miniOS/drivers/console.h>#include <miniOS/io.h>#include <miniOS/types.h>
Functions | |
| static void | ata_delay_400ns (void) |
| static int | ata_wait_ready (void) |
| static int | ata_wait_dma (void) |
| int | ata_init (void) |
| int | ata_read_sectors (uint64_t lba, uint16_t count, void *buf) |
| int | ata_write_sectors (uint64_t lba, uint16_t count, const void *buf) |
| int | ata_flush (void) |
Variables | |
| static uint16_t | g_bmr_base = 0 |
| static uint8_t * | g_dma_buf = NULL |
| static uint32_t | g_dma_phys = 0 |
| static prd_entry_t | g_prd [1] |
|
inlinestatic |


| int ata_flush | ( | void | ) |
ata_flush() - Issue CACHE FLUSH EXT to force write-back cache to disk.
Waits for drive ready, issues CACHE FLUSH EXT (0xEA), then waits for BSY=0. Must be called after all ext2 write operations to guarantee EXT2W-07 (data survives power-off / QEMU restart).
ata_flush() - Flush the ATA drive's write-back cache to stable storage.
Issues CACHE FLUSH EXT command (0xEA) to the primary master ATA drive. Waits for BSY=0 after issuing the command. Required after write sequences to guarantee persistence across power-off.


| int ata_init | ( | void | ) |
ata_init() - Locate IDE controller in pci_devices[] and set up DMA infrastructure.
Searches pci_devices[] (populated by pci_init()) for class=0x01 subclass=0x01 (IDE controller). Reads BAR4 for Bus Master Register base port (g_bmr_base). Enables PCI bus mastering via command register bit 2. Maps the DMA bounce buffer: vmm_map_page(0xFFFF830000000000, pmm_alloc_frame(), PAGE_PRESENT|PAGE_WRITE). Stores bounce buffer kernel VA in g_dma_buf and physical address in g_dma_phys. Sets up g_prd[0] with phys_addr=g_dma_phys, byte_count=4096, flags=0x8000 (last entry).
Must be called after pci_init().
ata_init() - Initialise the ATA driver via PCI Bus Mastering DMA.
Scans PCI configuration space (bus 0, devices 0-31, function 0) for a PCI IDE controller (class 0x01, subclass 0x01). Reads the Bus Master Register (BMR) base from BAR4. Allocates a 4 KiB DMA bounce buffer at the fixed virtual address 0xFFFF830000000000 (PML4 slot 262). Sets up a single Physical Region Descriptor (PRD) entry pointing to the bounce buffer's physical address.


ata_read_sectors() - Read sectors from primary master ATA drive via Bus Mastering DMA. @lba: 48-bit LBA of the first sector. @count: Number of 512-byte sectors (1-8; 4 KiB bounce buffer limits to 8 max). @buf: Destination buffer (at least @count * 512 bytes).
Programs the primary ATA controller (base port 0x1F0): selects master drive (0xA0), writes high and low bytes of sector count and 48-bit LBA to LBA registers, issues READ DMA EXT command (0x25). Writes g_prd physical address to BMR_PRDT, clears BMR_STATUS interrupt/error bits, and sets BMR_CMD bit 0 to start DMA. Polls BMR_STATUS until bit 2 (IRQ) is set or bit 1 (error) is set. Stops DMA via BMR_CMD. Copies from g_dma_buf to @buf.
Context: Polling-based; not ISR-safe.
ata_read_sectors() - Read sectors from the primary master ATA drive via DMA. @lba: 48-bit Logical Block Address of the first sector to read. @count: Number of 512-byte sectors to read. Maximum 8 (4 KiB bounce buffer limit). @buf: Destination buffer. Must be at least @count * 512 bytes.
Programs the ATA controller with 48-bit LBA addressing, starts a Bus Mastering DMA read into the bounce buffer at 0xFFFF830000000000, waits for the DMA IRQ (polling BMR_STATUS bit 2), then copies from bounce buffer to @buf.
Context: Polling-based (no interrupts used for synchronisation in this implementation). Not ISR-safe.


|
static |


|
static |


ata_write_sectors() - Write sectors to the primary master ATA drive via DMA. @lba: 48-bit LBA of the first sector. @count: Number of 512-byte sectors (1-8; 4 KiB bounce buffer limits to 8 max). @buf: Source buffer (at least @count * 512 bytes).
Copies @buf into the DMA bounce buffer (write direction: caller → g_dma_buf). Programs the ATA controller with 48-bit LBA, sets BMR direction bit 3=1 (write), issues WRITE DMA EXT (0x35). Polls BMR_STATUS until completion.
Context: Polling-based; not ISR-safe.
ata_write_sectors() - Write sectors to the primary master ATA drive via DMA. @lba: 48-bit Logical Block Address of the first sector to write. @count: Number of 512-byte sectors to write. Maximum 8 (4 KiB bounce buffer limit). @buf: Source buffer. Must be at least @count * 512 bytes.
Copies @buf into the DMA bounce buffer, programs the ATA controller with 48-bit LBA, starts a Bus Mastering DMA write (BMR_CMD direction bit 3 = 1), issues WRITE DMA EXT (0x35), waits for DMA completion, then stops DMA.
Context: Polling-based. Not ISR-safe.


|
static |
|
static |
|
static |