diff options
author | Alex Auvolat <alex.auvolat@ens.fr> | 2015-02-24 15:08:01 +0100 |
---|---|---|
committer | Alex Auvolat <alex.auvolat@ens.fr> | 2015-02-24 15:08:01 +0100 |
commit | 7e908dabaaf6c67ef5000406a0bb3a6a29beca01 (patch) | |
tree | b0516cc4771ca3a8e202327d2864804afefe4cfc /src/kernel/include | |
parent | 91c5969cdddf2241418082998e76bdbb836ed03e (diff) | |
download | kogata-7e908dabaaf6c67ef5000406a0bb3a6a29beca01.tar.gz kogata-7e908dabaaf6c67ef5000406a0bb3a6a29beca01.zip |
Add PCI IDE driver (only PIO mode, no DMA yet.)
Diffstat (limited to 'src/kernel/include')
-rw-r--r-- | src/kernel/include/dev/ata.h | 7 | ||||
-rw-r--r-- | src/kernel/include/dev/pci.h | 12 | ||||
-rw-r--r-- | src/kernel/include/dev/pciide.h | 114 | ||||
-rw-r--r-- | src/kernel/include/sys.h | 31 |
4 files changed, 155 insertions, 9 deletions
diff --git a/src/kernel/include/dev/ata.h b/src/kernel/include/dev/ata.h deleted file mode 100644 index c0a4bff..0000000 --- a/src/kernel/include/dev/ata.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include <vfs.h> - - - -/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/kernel/include/dev/pci.h b/src/kernel/include/dev/pci.h index 9fe0f3b..c1dfa99 100644 --- a/src/kernel/include/dev/pci.h +++ b/src/kernel/include/dev/pci.h @@ -12,11 +12,18 @@ #define PCI_IRQ_NETWORK 11 #define PCI_IRQ_DISABLE 0xFF -#define PCI_CONFIG_DEVICE_ID 0x02 #define PCI_CONFIG_VENDOR_ID 0x00 +#define PCI_CONFIG_DEVICE_ID 0x02 +#define PCI_CONFIG_PROG_IF 0x09 #define PCI_CONFIG_CLASS 0x0B #define PCI_CONFIG_SUBCLASS 0x0A #define PCI_CONFIG_HEADER_TYPE 0x0E +#define PCI_CONFIG_BAR0 0x10 +#define PCI_CONFIG_BAR1 0x14 +#define PCI_CONFIG_BAR2 0x18 +#define PCI_CONFIG_BAR3 0x1C +#define PCI_CONFIG_BAR4 0x20 +#define PCI_CONFIG_BAR5 0x24 #define PCI_CONFIG_SECONDARY_BUS 0x19 #define PCI_CONFIG_INTERRUPT_LINE 0x3C @@ -28,7 +35,7 @@ #define PCI_SC_IDE 0x01 #define PCI_SC_PCI_TO_PCI 0x04 -typedef void (*pci_irq_handler_t)(); +typedef void (*pci_irq_handler_t)(int dev_id); typedef struct { uint8_t bus; @@ -43,6 +50,7 @@ typedef struct { uint8_t irq; pci_irq_handler_t irq_handler; + void* data; // data block for use by specific driver } pci_device_t; extern pci_device_t pci_devices[PCI_MAX_DEVICES]; diff --git a/src/kernel/include/dev/pciide.h b/src/kernel/include/dev/pciide.h new file mode 100644 index 0000000..ca65ca8 --- /dev/null +++ b/src/kernel/include/dev/pciide.h @@ -0,0 +1,114 @@ +#pragma once + +#include <vfs.h> + +#define ATA_SR_BSY 0x80 +#define ATA_SR_DRDY 0x40 +#define ATA_SR_DF 0x20 +#define ATA_SR_DSC 0x10 +#define ATA_SR_DRQ 0x08 +#define ATA_SR_CORR 0x04 +#define ATA_SR_IDX 0x02 +#define ATA_SR_ERR 0x01 + +#define ATA_ER_BBK 0x80 +#define ATA_ER_UNC 0x40 +#define ATA_ER_MC 0x20 +#define ATA_ER_IDNF 0x10 +#define ATA_ER_MCR 0x08 +#define ATA_ER_ABRT 0x04 +#define ATA_ER_TK0NF 0x02 +#define ATA_ER_AMNF 0x01 + +#define ATA_CMD_READ_PIO 0x20 +#define ATA_CMD_READ_PIO_EXT 0x24 +#define ATA_CMD_READ_DMA 0xC8 +#define ATA_CMD_READ_DMA_EXT 0x25 +#define ATA_CMD_WRITE_PIO 0x30 +#define ATA_CMD_WRITE_PIO_EXT 0x34 +#define ATA_CMD_WRITE_DMA 0xCA +#define ATA_CMD_WRITE_DMA_EXT 0x35 +#define ATA_CMD_CACHE_FLUSH 0xE7 +#define ATA_CMD_CACHE_FLUSH_EXT 0xEA +#define ATA_CMD_PACKET 0xA0 +#define ATA_CMD_IDENTIFY_PACKET 0xA1 +#define ATA_CMD_IDENTIFY 0xEC + +#define ATAPI_CMD_READ 0xA8 +#define ATAPI_CMD_EJECT 0x1B + +#define ATA_IDENT_DEVICETYPE 0 +#define ATA_IDENT_CYLINDERS 2 +#define ATA_IDENT_HEADS 6 +#define ATA_IDENT_SECTORS 12 +#define ATA_IDENT_SERIAL 20 +#define ATA_IDENT_MODEL 54 +#define ATA_IDENT_CAPABILITIES 98 +#define ATA_IDENT_FIELDVALID 106 +#define ATA_IDENT_MAX_LBA 120 +#define ATA_IDENT_COMMANDSETS 164 +#define ATA_IDENT_MAX_LBA_EXT 200 + +#define IDE_ATA 0x00 +#define IDE_ATAPI 0x01 + +#define ATA_MASTER 0x00 +#define ATA_SLAVE 0x01 + +#define ATA_REG_DATA 0x00 +#define ATA_REG_ERROR 0x01 +#define ATA_REG_FEATURES 0x01 +#define ATA_REG_SECCOUNT0 0x02 +#define ATA_REG_LBA0 0x03 +#define ATA_REG_LBA1 0x04 +#define ATA_REG_LBA2 0x05 +#define ATA_REG_HDDEVSEL 0x06 +#define ATA_REG_COMMAND 0x07 +#define ATA_REG_STATUS 0x07 +#define ATA_REG_SECCOUNT1 0x08 +#define ATA_REG_LBA3 0x09 +#define ATA_REG_LBA4 0x0A +#define ATA_REG_LBA5 0x0B +#define ATA_REG_CONTROL 0x0C +#define ATA_REG_ALTSTATUS 0x0C +#define ATA_REG_DEVADDRESS 0x0D + +// Channels: +#define ATA_PRIMARY 0x00 +#define ATA_SECONDARY 0x01 + +// Directions: +#define ATA_READ 0x00 +#define ATA_WRITE 0x01 + +typedef struct { + uint16_t base; // IO base + uint16_t ctrl; // Control base + uint16_t bmide; // Bus Master IDE + uint8_t nIEN; // do not use interrupt + uint8_t irq; // which irq to wait for +} ide_channels_regs_t; + +typedef struct { + uint8_t present; // 0 : empty, 1 : present + uint8_t channel; // 0 : primary, 1 : secondary + uint8_t drive; // 0 : master, 1 : slave + uint16_t type; // 0 : ATA, 1 : ATAPI + uint16_t sig; // drive signature + uint16_t cap; // features (capabilities) + uint32_t cmdset; // supported command set + uint32_t size; // size in sectors + char model[41]; // model string +} ide_device_t; + +typedef struct { + ide_channels_regs_t channels[2]; + ide_device_t devices[4]; + bool irq_invoked; + char atapi_packet[12]; + int pci_id; +} ide_controller_t; + +void pciide_detect(fs_t *iofs); // iofs = where to add ATA drives + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/kernel/include/sys.h b/src/kernel/include/sys.h index 365e709..944df96 100644 --- a/src/kernel/include/sys.h +++ b/src/kernel/include/sys.h @@ -15,6 +15,22 @@ static inline void outl(uint16_t port, uint32_t value) { asm volatile("outl %1, %0" : : "dN"(port), "a"(value)); } +static inline void outsb(uint16_t port, const void *addr, size_t cnt) { + // write cnt bytes to port + asm volatile ("rep outsb" : "+S" (addr), "+c" (cnt) : "d" (port)); +} + +static inline void outsw(uint16_t port, const void *addr, size_t cnt) { + // write cnt words to port + asm volatile ("rep outsw" : "+S" (addr), "+c" (cnt) : "d" (port)); +} + +static inline void outsl (uint16_t port, const void *addr, size_t cnt) { + // write cnt longwords to port + asm volatile ("rep outsl" : "+S" (addr), "+c" (cnt) : "d" (port)); +} + + static inline uint8_t inb(uint16_t port) { uint8_t ret; asm volatile("inb %1, %0" : "=a"(ret) : "dN"(port)); @@ -33,6 +49,21 @@ static inline uint32_t inl(uint16_t port) { return ret; } +static inline void insb(uint16_t port, void *addr, size_t cnt) { + // read cnt bytes from port and put them at addr + asm volatile ("rep insb" : "+D" (addr), "+c" (cnt) : "d" (port) : "memory"); +} + +static inline void insw(uint16_t port, void *addr, size_t cnt) { + // read cnt words from port and put them at addr + asm volatile ("rep insw" : "+D" (addr), "+c" (cnt) : "d" (port) : "memory"); +} + +static inline void insl(uint16_t port, void *addr, size_t cnt) { + // read cnt longwords from port and put them at addr + asm volatile ("rep insl" : "+D" (addr), "+c" (cnt) : "d" (port) : "memory"); +} + static inline void invlpg(void* addr) { asm volatile("invlpg (%0)" : : "r"(addr) : "memory"); } |