aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/include
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2015-02-24 15:08:01 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2015-02-24 15:08:01 +0100
commit7e908dabaaf6c67ef5000406a0bb3a6a29beca01 (patch)
treeb0516cc4771ca3a8e202327d2864804afefe4cfc /src/kernel/include
parent91c5969cdddf2241418082998e76bdbb836ed03e (diff)
downloadkogata-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.h7
-rw-r--r--src/kernel/include/dev/pci.h12
-rw-r--r--src/kernel/include/dev/pciide.h114
-rw-r--r--src/kernel/include/sys.h31
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");
}