diff --git a/guest/ide/ide.h b/guest/ide/ide.h index d6e7c5a8c24303adfb9345e89518c2e30307dfe1..8186e2bd75f0ef72b4fb78a261cb2085fd9a8355 100644 --- a/guest/ide/ide.h +++ b/guest/ide/ide.h @@ -1,10 +1,22 @@ #ifndef _IDE_H_ #define _IDE_H_ -#define SECTOR_SIZE 512 +#include <stdint.h> -// Write a sector. -// Implement a device driver for the true physical hardware. -void ide_write_sector_phys(int sector_idx, void *data); +// --- DEFINE --- -#endif +// ... + +// --- FUNCTION --- + +/** + * Read a sector from the first disk. + * @param first sector to read (0-indexed) + * @param dst address to store to read data + * Based on the assembly code at http://wiki.osdev.org/ATA_read/write_sectors + */ +void ide_phys_write_sector(uint32_t sector_idx, void *data); + +void ide_pv_write_sector(uint32_t sector_idx, void *data); + +#endif // _IDE_H_ diff --git a/guest/ide/ide_phys.c b/guest/ide/ide_phys.c index 0a49e4a8c5c3962304fb7f590336c736120b31d0..84f23728f463ed1a56f010e73024565c7d21736c 100644 --- a/guest/ide/ide_phys.c +++ b/guest/ide/ide_phys.c @@ -1,14 +1,20 @@ -#include <stdint.h> #include "ide.h" + +#include "guest/pmio.h" #include "shared/ide_regs.h" -#include "../pmio.h" +#include <stdint.h> + +// --- DEFINE --- -// IDE controler is programmed in PMIO. +// ... + +// --- STATIC FUNCTION --- /** * Wait for the disk drive to be ready. */ static void wait_drive() { + while ((inb(IDE_STATUS_REG) & 0xC0) != 0x40); } @@ -16,29 +22,31 @@ static void wait_drive() { * Prepare the disk drive for read/write at the specified sector in 28-bit LBA mode. * @param sector the sector to read or write */ -static void pio_prepare(int sector) { +static void pio_prepare(uint32_t sector) { + wait_drive(); - outb(IDE_DATA_BASE_REG+2, 1); // sector count - outb(IDE_DATA_BASE_REG+3, sector & 0xff); // send bits 0-7 of LBA - outb(IDE_DATA_BASE_REG+4, (sector >> 8) & 0xff); // send bits 8-15 of LBA - outb(IDE_DATA_BASE_REG+5, (sector >> 16) & 0xff); // send bits 16-23 of LBA + + outb(IDE_DATA_BASE_REG+2, 1); // sector count + outb(IDE_DATA_BASE_REG+3, sector & 0xff); // send bits 0-7 of LBA + outb(IDE_DATA_BASE_REG+4, (sector >> 8) & 0xff); // send bits 8-15 of LBA + outb(IDE_DATA_BASE_REG+5, (sector >> 16) & 0xff); // send bits 16-23 of LBA outb(IDE_DATA_BASE_REG+6, ((sector >> 24) & 0x0f) | 0xe0); // send bits 24-27 of LBA + set LBA mode; 0xe0 = 11100000b; } -/** - * Read a sector from the first disk. - * @param first sector to read (0-indexed) - * @param dst address to store to read data - * Based on the assembly code at http://wiki.osdev.org/ATA_read/write_sectors - */ -void ide_write_sector_phys(int sector, void *data) { +// --- FUNCTION --- + +void ide_phys_write_sector(uint32_t sector, void *data) { + pio_prepare(sector); + outb(IDE_CMD_REG, 0x30); // command port: write with retry wait_drive(); uint16_t *d = (uint16_t *)data; - for (int i = 0; i < SECTOR_SIZE/2; i++) { + for (int i = 0; i < MAX_LOOP_IDE_DATA; i++) { + outw(IDE_DATA_BASE_REG, *d); d++; } } + diff --git a/guest/ide/ide_pv.c b/guest/ide/ide_pv.c new file mode 100644 index 0000000000000000000000000000000000000000..811cab878eb27fc73b6d3c9e4e6061e8961746cc --- /dev/null +++ b/guest/ide/ide_pv.c @@ -0,0 +1,22 @@ +#include "ide.h" + +#include "guest/pmio.h" +#include "guest/utils.h" +#include "shared/hypercall_params.h" + +// --- DEFINE --- + +// ... + +// --- FUNCTION --- + +void ide_pv_write_sector(uint32_t sector_idx, void *data) { + + hyper_ide_params_t param_ide; + param_ide.sector_idx = sector_idx; + param_ide.data = (uint64_t)data; + memcpy((void *)HYPERCALL_SHARED_ADDR, (void *)¶m_ide, sizeof(param_ide)); + + outb(HYPERCALL_PMIO_ADDR, HYPERCALL_CODE_IDE); +} + diff --git a/shared/ide_regs.h b/shared/ide_regs.h index a85c915f888dab636f800a5bc97167cd78d8e814..bbf52a23c39b7746ec586921069b163158c5eff6 100644 --- a/shared/ide_regs.h +++ b/shared/ide_regs.h @@ -1,13 +1,12 @@ #ifndef _IDE_REGS_H_ #define _IDE_REGS_H_ -// Status register on the primary bus (read-only) -#define IDE_STATUS_REG 0x1F7 +#define IDE_STATUS_REG 0x1F7 // Status register on the primary bus (read-only) +#define IDE_CMD_REG 0x1F7 // Command register on the primary bus (write-only) +#define IDE_DATA_BASE_REG 0x1F0 // Base port on primary bus (write-only) -// Command register on the primary bus (write-only) -#define IDE_CMD_REG 0x1F7 - -// Base port on primary bus (write-only) -#define IDE_DATA_BASE_REG 0x1F0 +#define SECTOR_SIZE 512 +#define MAX_SECTOR_NUM ((1UL << 28) - 1) +#define MAX_LOOP_IDE_DATA (SECTOR_SIZE / 2) #endif