From 363eea1f6ea7fc0859be8c0bb5c3925e69ca31eb Mon Sep 17 00:00:00 2001 From: Malo Lecomte Date: Mon, 26 Jul 2021 14:55:13 +0200 Subject: [PATCH] feat(atapi): add drive discover functions --- k/atapi.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ k/atapi.h | 14 +++++++++++ 2 files changed, 89 insertions(+) create mode 100644 k/atapi.c create mode 100644 k/atapi.h diff --git a/k/atapi.c b/k/atapi.c new file mode 100644 index 0000000..3d03630 --- /dev/null +++ b/k/atapi.c @@ -0,0 +1,75 @@ +#include +#include + +#include "atapi.h" +#include "io.h" + +static struct atapi_drive drives[4] = { 0 }; + +static void select_drive(uint16_t bus, uint8_t slave) +{ + outb(ATA_REG_DRIVE(bus), slave); +} + +static void busy_wait(uint16_t drive) +{ + int res = 0; + while (res & BSY) + res = inb(ATA_REG_STATUS(drive)); +} + +static void wait_device_selection(uint16_t drive) +{ + for (int i = 0; i < 4; ++i) + inb(drive); +} + +static uint8_t is_atapi_driver(uint16_t bus, uint8_t slave) +{ + static uint8_t atapi_sig[] = { ATAPI_SIG_SC, ATAPI_SIG_LBA_LO, + ATAPI_SIG_LBA_MI, ATAPI_SIG_LBA_HI }; + uint8_t sig[4]; + + sig[0] = inb(ATA_REG_SECTOR_COUNT(bus)); + sig[1] = inb(ATA_REG_LBA_LO(bus)); + sig[2] = inb(ATA_REG_LBA_MI(bus)); + sig[3] = inb(ATA_REG_LBA_HI(bus)); + + if (!memcmp(sig, atapi_sig, 4)) + { + struct atapi_drive d = { bus, slave }; + if (bus == PRIMARY_REG) + { + if (slave) + drives[1] = d; + else + drives[0] = d; + } + else + { + if (slave) + drives[3] = d; + else + drives[2] = d; + } + + return 1; + } + + return 0; +} + +void discover_atapi_drive(void) +{ + // primary_reg + outb(PRIMARY_DCR, SRST); + outb(PRIMARY_DCR, INTERRUPT_DISABLE); + + select_drive(PRIMARY_REG, ATA_PORT_MASTER); + wait_device_selection(PRIMARY_REG); + is_atapi_driver(PRIMARY_REG, ATA_PORT_MASTER); + + // secondary_reg + outb(SECONDARY_DCR, SRST); + outb(SECONDARY_DCR, INTERRUPT_DISABLE); +} diff --git a/k/atapi.h b/k/atapi.h new file mode 100644 index 0000000..dc4ec58 --- /dev/null +++ b/k/atapi.h @@ -0,0 +1,14 @@ +#ifndef ATAPI_H +#define ATAPI_H + +#include + +struct atapi_drive +{ + uint8_t reg; + uint8_t drive; +}; + +void discover_atapi_drive(void); + +#endif /* !ATAPI_H */