6#include <sys/kassert.h>
8#include <sys/spinlock.h>
18#define IDE_PRIMARY_BASE 0x1F0
19#define IDE_PRIMARY_DEVCTL 0x3F6
20#define IDE_PRIMARY_IRQ 14
22#define IDE_SECONDARY_BASE 0x170
23#define IDE_SECONDARY_DEVCTL 0x376
24#define IDE_SECONDARY_IRQ 15
29#define IDE_SECTORCOUNT 2
38#define IDE_CMD_READ 0x20
39#define IDE_CMD_READ_EXT 0x24
40#define IDE_CMD_WRITE 0x30
41#define IDE_CMD_WRITE_EXT 0x34
42#define IDE_CMD_FLUSH 0xE7
43#define IDE_CMD_IDENTIFY 0xEC
46#define IDE_STATUS_ERR 0x01
47#define IDE_STATUS_DRQ 0x08
48#define IDE_STATUS_SRV 0x10
49#define IDE_STATUS_DF 0x20
50#define IDE_STATUS_RDY 0x40
51#define IDE_STATUS_BSY 0x80
53#define IDE_CONTROL_SRST 0x04
55#define IDE_SECTOR_SIZE 512
96 kprintf(
"IDE: No controller detected\n");
154 Log(ide,
"Controller not ready!\n");
166 for (i = 0; i <
len/2; i++)
169 str[2*i] = str[2*i+1];
173 for (i =
len - 1; i > 0; i--) {
174 if (str[i] ==
' ' || str[i] ==
'\0')
188 ASSERT(drive == 0 || drive == 1);
199 Log(ide,
"Error selecting drive %d\n", drive);
212 Log(ide,
"Drive %d not present\n", drive);
224 Log(ide,
"Error trying to identify drive %d\n", drive);
228 insw(ide->
base, (
void *)&ident, 256);
242 Log(ide,
"Drive %d Model: %s Serial: %s\n", drive, model, serial);
243 Log(ide,
"Drive %d %llu Sectors (%llu MBs)\n",
254 Panic(
"IDE: No memory!\n");
279 for (i = 0; i < sga->
len; i++) {
301 for (i = 0; i < sga->
len; i++) {
324 if (idedrive->
drive == 0)
347 DLOG(ide,
"read %llx %llx\n", off,
len);
351 if (drive->
drive == 0)
352 driveCode = lba48 ? 0x40 : 0xE0;
354 driveCode = lba48 ? 0x50 : 0xF0;
366 Log(ide,
"Error selecting drive %d\n", drive->
drive);
391 Log(ide,
"Error trying read from drive %d\n", drive->
drive);
396 for (sectors = 0; sectors <
len; sectors++)
404 Log(ide,
"Error reading from drive %d\n", drive->
drive);
421 DLOG(ide,
"read %llx %llx\n", off,
len);
425 if (drive->
drive == 0)
426 driveCode = lba48 ? 0x40 : 0xE0;
428 driveCode = lba48 ? 0x50 : 0xF0;
440 Log(ide,
"Error selecting drive %d\n", drive->
drive);
465 Log(ide,
"Error trying read from drive %d\n", drive->
drive);
470 for (sectors = 0; sectors <
len; sectors++)
478 Log(ide,
"Error reading from drive %d\n", drive->
drive);
static INLINE uint8_t inb(uint16_t port)
static INLINE void outb(uint16_t port, uint8_t data)
void Disk_AddDisk(Disk *disk)
void(* DiskCB)(int, void *)
int IDE_Write(Disk *disk, void *buf, SGArray *sga, DiskCB, void *arg)
IDEDrive primaryDrives[2]
void IDE_Identify(IDE *ide, int drive)
int IDE_ReadOne(IDEDrive *drive, void *buf, uint64_t off, uint64_t len)
#define IDE_CMD_WRITE_EXT
int IDEWaitForBusy(IDE *ide, bool wait)
int IDE_Flush(Disk *disk, void *buf, SGArray *sga, DiskCB, void *arg)
bool IDE_HasController(IDE *ide)
int IDE_Read(Disk *disk, void *buf, SGArray *sga, DiskCB, void *arg)
int IDE_WriteOne(IDEDrive *drive, void *buf, uint64_t off, uint64_t len)
void IDE_SwapAndTruncateString(char *str, int len)
#define IDE_PRIMARY_DEVCTL
static __inline__ void outsw(int port, const void *buf, int cnt)
static __inline__ void insw(int port, void *buf, int cnt)
#define Log(_module, _format,...)
#define DLOG(_module, _format,...)
int kprintf(const char *fmt,...)
void * PAlloc_AllocPage()
SGEntry entries[SGARRAY_MAX_ENTRIES]
void Spinlock_Unlock(Spinlock *lock) __UNLOCK_EX(*lock)
#define SPINLOCK_TYPE_NORMAL
bool Spinlock_IsHeld(Spinlock *lock) __LOCK_EX_ASSERT(*lock)
void Spinlock_Lock(Spinlock *lock) __LOCK_EX(*lock)
void Spinlock_Init(Spinlock *lock, const char *name, uint64_t type)
void * memcpy(void *dst, const void *src, size_t len)
int(* write)(Disk *, void *, SGArray *, DiskCB, void *)
int(* flush)(Disk *, void *, SGArray *, DiskCB, void *)
int(* read)(Disk *, void *, SGArray *, DiskCB, void *)
void Panic(const char *str)