/*
- * Copyright (c) 2003 The Regents of The University of Michigan
+ * Copyright (c) 2004 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#define DMA_BACKOFF_PERIOD 200
-#define MAX_DMA_SIZE (131072) // 256 * SectorSize (512)
-#define MAX_MULTSECT (128)
+#define MAX_DMA_SIZE (65536) // 64K
+#define MAX_MULTSECT (128)
#define PRD_BASE_MASK 0xfffffffe
#define PRD_COUNT_MASK 0xfffe
return (entry.baseAddr & PRD_BASE_MASK);
}
- uint16_t getByteCount()
+ uint32_t getByteCount()
{
return ((entry.byteCount == 0) ? MAX_DMA_SIZE :
(entry.byteCount & PRD_COUNT_MASK));
#define STATUS_BSY_BIT 0x80
#define STATUS_DRDY_BIT 0x40
#define STATUS_DRQ_BIT 0x08
-#define DRIVE_LBA_BIT 0x40
+#define STATUS_SEEK_BIT 0x10
+#define STATUS_DF_BIT 0x20
+#define DRIVE_LBA_BIT 0x40
#define DEV0 (0)
#define DEV1 (1)
uint8_t drive;
uint8_t head;
};
- union {
- uint8_t status;
- uint8_t command;
- };
+ uint8_t command;
} CommandReg_t;
+typedef enum Events {
+ None = 0,
+ Transfer,
+ ReadWait,
+ WriteWait,
+ PrdRead,
+ DmaRead,
+ DmaWrite
+} Events_t;
+
typedef enum DevAction {
ACT_NONE = 0,
ACT_CMD_WRITE,
ACT_CMD_COMPLETE,
ACT_CMD_ERROR,
+ ACT_SELECT_WRITE,
ACT_STAT_READ,
ACT_DATA_READY,
ACT_DATA_READ_BYTE,
ACT_DATA_WRITE_BYTE,
ACT_DATA_WRITE_SHORT,
ACT_DMA_READY,
- ACT_DMA_DONE
+ ACT_DMA_DONE,
+ ACT_SRST_SET,
+ ACT_SRST_CLEAR
} DevAction_t;
typedef enum DevState {
Device_Idle_SI,
Device_Idle_NS,
+ // Software reset
+ Device_Srst,
+
// Non-data commands
Command_Execution,
PhysicalMemory *physmem;
protected:
- /** The disk delay in milliseconds. */
+ /** The disk delay in microseconds. */
int diskDelay;
private:
struct hd_driveid driveID;
/** Data buffer for transfers */
uint8_t *dataBuffer;
+ /** Number of bytes in command data transfer */
+ uint32_t cmdBytes;
/** Number of bytes left in command data transfer */
uint32_t cmdBytesLeft;
/** Number of bytes left in DRQ block */
uint32_t curSector;
/** Command block registers */
CommandReg_t cmdReg;
- /** Shadow of the current command code */
- uint8_t curCommand;
+ /** Status register */
+ uint8_t status;
/** Interrupt enable bit */
bool nIENBit;
/** Device state */
uint32_t curPrdAddr;
/** PRD entry */
PrdTableEntry curPrd;
+ /** Number of bytes transfered by DMA interface for current transfer */
+ uint32_t dmaInterfaceBytes;
/** Device ID (master=0/slave=1) */
int devID;
/** Interrupt pending */
*/
~IdeDisk();
+ /**
+ * Reset the device state
+ */
+ void reset(int id);
+
/**
* Set the controller for this device
* @param c The IDE controller
void updateState(DevAction_t action);
// Utility functions
- bool isBSYSet() { return (cmdReg.status & STATUS_BSY_BIT); }
+ bool isBSYSet() { return (status & STATUS_BSY_BIT); }
bool isIENSet() { return nIENBit; }
- bool isDEVSelect() { return ((cmdReg.drive & SELECT_DEV_BIT) == devID); }
+ bool isDEVSelect();
void setComplete()
{
// clear out the status byte
- cmdReg.status = 0;
-
+ status = 0;
// set the DRDY bit
- cmdReg.status |= STATUS_DRDY_BIT;
+ status |= STATUS_DRDY_BIT;
+ // set the SEEK bit
+ status |= STATUS_SEEK_BIT;
}
uint32_t getLBABase()
(cmdReg.cyl_low << 8) | (cmdReg.sec_num));
}
- inline Addr pciToDma(Addr &pciAddr);
+ inline Addr pciToDma(Addr pciAddr);
+
+ uint32_t bytesInDmaPage(Addr curAddr, uint32_t bytesLeft);
/**
* Serialize this object to the given output stream.