Skip to content
Snippets Groups Projects
Commit 39d45041 authored by adrian.spycher's avatar adrian.spycher
Browse files

feat!: add new peri (IDE)

parent 380ecb3a
Branches
No related tags found
No related merge requests found
#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_
#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++;
}
}
#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 *)&param_ide, sizeof(param_ide));
outb(HYPERCALL_PMIO_ADDR, HYPERCALL_CODE_IDE);
}
#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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment