miniOS
x86_64 hobby kernel with SMP, VFS, and POSIX process model
Loading...
Searching...
No Matches
ata.c File Reference
#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>
Include dependency graph for ata.c:

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_tg_dma_buf = NULL
static uint32_t g_dma_phys = 0
static prd_entry_t g_prd [1]

Function Documentation

◆ ata_delay_400ns()

void ata_delay_400ns ( void )
inlinestatic
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ata_flush()

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).

Returns
: 0 on success, -1 on timeout.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ata_init()

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().

Returns
: 0 on success, -1 if no PCI IDE controller found in pci_devices[].
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ata_read_sectors()

int ata_read_sectors ( uint64_t lba,
uint16_t count,
void * buf )

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.

Returns
: 0 on success, -1 on DMA or ATA drive error.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ata_wait_dma()

int ata_wait_dma ( void )
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ata_wait_ready()

int ata_wait_ready ( void )
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ata_write_sectors()

int ata_write_sectors ( uint64_t lba,
uint16_t count,
const void * buf )

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.

Returns
: 0 on success, -1 on DMA or ATA drive error.
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ g_bmr_base

uint16_t g_bmr_base = 0
static

◆ g_dma_buf

uint8_t* g_dma_buf = NULL
static

◆ g_dma_phys

uint32_t g_dma_phys = 0
static

◆ g_prd

prd_entry_t g_prd[1]
static