diff options
Diffstat (limited to 'src/dev/ide_ctrl.hh')
-rw-r--r-- | src/dev/ide_ctrl.hh | 246 |
1 files changed, 85 insertions, 161 deletions
diff --git a/src/dev/ide_ctrl.hh b/src/dev/ide_ctrl.hh index f22d83e9c..89dc1ee9d 100644 --- a/src/dev/ide_ctrl.hh +++ b/src/dev/ide_ctrl.hh @@ -37,61 +37,13 @@ #ifndef __IDE_CTRL_HH__ #define __IDE_CTRL_HH__ +#include "base/bitunion.hh" #include "dev/pcidev.hh" #include "dev/pcireg.h" #include "dev/io_device.hh" #include "params/IdeController.hh" -#define BMIC0 0x0 // Bus master IDE command register -#define BMIS0 0x2 // Bus master IDE status register -#define BMIDTP0 0x4 // Bus master IDE descriptor table pointer register -#define BMIC1 0x8 // Bus master IDE command register -#define BMIS1 0xa // Bus master IDE status register -#define BMIDTP1 0xc // Bus master IDE descriptor table pointer register - -// Bus master IDE command register bit fields -#define RWCON 0x08 // Bus master read/write control -#define SSBM 0x01 // Start/stop bus master - -// Bus master IDE status register bit fields -#define DMA1CAP 0x40 // Drive 1 DMA capable -#define DMA0CAP 0x20 // Drive 0 DMA capable -#define IDEINTS 0x04 // IDE Interrupt Status -#define IDEDMAE 0x02 // IDE DMA error -#define BMIDEA 0x01 // Bus master IDE active - -// IDE Command byte fields -#define IDE_SELECT_OFFSET (6) -#define IDE_SELECT_DEV_BIT 0x10 - -#define IDE_FEATURE_OFFSET IDE_ERROR_OFFSET -#define IDE_COMMAND_OFFSET IDE_STATUS_OFFSET - -// IDE Timing Register bit fields -#define IDETIM_DECODE_EN 0x8000 - -// PCI device specific register byte offsets -#define IDE_CTRL_CONF_START 0x40 -#define IDE_CTRL_CONF_END ((IDE_CTRL_CONF_START) + sizeof(config_regs)) - -#define IDE_CTRL_CONF_PRIM_TIMING 0x40 -#define IDE_CTRL_CONF_SEC_TIMING 0x42 -#define IDE_CTRL_CONF_DEV_TIMING 0x44 -#define IDE_CTRL_CONF_UDMA_CNTRL 0x48 -#define IDE_CTRL_CONF_UDMA_TIMING 0x4A -#define IDE_CTRL_CONF_IDE_CONFIG 0x54 - - -enum IdeRegType { - COMMAND_BLOCK, - CONTROL_BLOCK, - BMI_BLOCK -}; - class IdeDisk; -class IntrControl; -class PciConfigAll; -class Platform; /** * Device model for an Intel PIIX4 IDE controller @@ -99,137 +51,109 @@ class Platform; class IdeController : public PciDev { - friend class IdeDisk; + private: + // Bus master IDE status register bit fields + BitUnion8(BMIStatusReg) + Bitfield<6> dmaCap0; + Bitfield<5> dmaCap1; + Bitfield<2> intStatus; + Bitfield<1> dmaError; + Bitfield<0> active; + EndBitUnion(BMIStatusReg) + + BitUnion8(BMICommandReg) + Bitfield<3> rw; + Bitfield<0> startStop; + EndBitUnion(BMICommandReg) + + struct Channel + { + std::string _name; + + const std::string + name() + { + return _name; + } + + /** Command and control block registers */ + Addr cmdAddr, cmdSize, ctrlAddr, ctrlSize; + + /** Registers used for bus master interface */ + struct BMIRegs + { + BMICommandReg command; + uint8_t reserved0; + BMIStatusReg status; + uint8_t reserved1; + uint32_t bmidtp; + } bmiRegs; - enum IdeChannel { - PRIMARY = 0, - SECONDARY = 1 - }; + /** IDE disks connected to this controller */ + IdeDisk *master, *slave; - private: - /** Primary command block registers */ - Addr pri_cmd_addr; - Addr pri_cmd_size; - /** Primary control block registers */ - Addr pri_ctrl_addr; - Addr pri_ctrl_size; - /** Secondary command block registers */ - Addr sec_cmd_addr; - Addr sec_cmd_size; - /** Secondary control block registers */ - Addr sec_ctrl_addr; - Addr sec_ctrl_size; - /** Bus master interface (BMI) registers */ - Addr bmi_addr; - Addr bmi_size; + /** Currently selected disk */ + IdeDisk *selected; - private: - /** Registers used for bus master interface */ - union { - uint8_t data[16]; - - struct { - uint8_t bmic0; - uint8_t reserved_0; - uint8_t bmis0; - uint8_t reserved_1; - uint32_t bmidtp0; - uint8_t bmic1; - uint8_t reserved_2; - uint8_t bmis1; - uint8_t reserved_3; - uint32_t bmidtp1; - }; - - struct { - uint8_t bmic; - uint8_t reserved_4; - uint8_t bmis; - uint8_t reserved_5; - uint32_t bmidtp; - } chan[2]; + bool selectBit; - } bmi_regs; - /** Shadows of the device select bit */ - uint8_t dev[2]; - /** Registers used in device specific PCI configuration */ - union { - uint8_t data[22]; - - struct { - uint16_t idetim0; - uint16_t idetim1; - uint8_t sidetim; - uint8_t reserved_0[3]; - uint8_t udmactl; - uint8_t reserved_1; - uint16_t udmatim; - uint8_t reserved_2[8]; - uint16_t ideconfig; - }; - } config_regs; + void + select(bool selSlave) + { + selectBit = selSlave; + selected = selectBit ? slave : master; + } - // Internal management variables - bool io_enabled; - bool bm_enabled; - bool cmd_in_progress[4]; + void accessCommand(Addr offset, int size, uint8_t *data, bool read); + void accessControl(Addr offset, int size, uint8_t *data, bool read); + void accessBMI(Addr offset, int size, uint8_t *data, bool read); - private: - /** IDE disks connected to controller */ - IdeDisk *disks[4]; + Channel(std::string newName, Addr _cmdSize, Addr _ctrlSize); + ~Channel(); - private: - /** Parse the access address to pass on to device */ - void parseAddr(const Addr &addr, Addr &offset, IdeChannel &channel, - IdeRegType ®_type); + void serialize(const std::string &base, std::ostream &os); + void unserialize(const std::string &base, Checkpoint *cp, + const std::string §ion); + }; - /** Select the disk based on the channel and device bit */ - int getDisk(IdeChannel channel); + Channel primary; + Channel secondary; - /** Select the disk based on a pointer */ - int getDisk(IdeDisk *diskPtr); + /** Bus master interface (BMI) registers */ + Addr bmiAddr, bmiSize; - public: - /** See if a disk is selected based on its pointer */ - bool isDiskSelected(IdeDisk *diskPtr); + /** Registers used in device specific PCI configuration */ + uint16_t primaryTiming, secondaryTiming; + uint8_t deviceTiming; + uint8_t udmaControl; + uint16_t udmaTiming; + uint16_t ideConfig; + + // Internal management variables + bool ioEnabled; + bool bmEnabled; + + void dispatchAccess(PacketPtr pkt, bool read); public: typedef IdeControllerParams Params; const Params *params() const { return (const Params *)_params; } IdeController(Params *p); - ~IdeController(); - virtual Tick writeConfig(PacketPtr pkt); - virtual Tick readConfig(PacketPtr pkt); + /** See if a disk is selected based on its pointer */ + bool isDiskSelected(IdeDisk *diskPtr); + + void intrPost(); + + Tick writeConfig(PacketPtr pkt); + Tick readConfig(PacketPtr pkt); void setDmaComplete(IdeDisk *disk); - /** - * Read a done field for a given target. - * @param pkt Packet describing what is to be read - * @return The amount of time to complete this request - */ - virtual Tick read(PacketPtr pkt); - - /** - * Write a done field for a given target. - * @param pkt Packet describing what is to be written - * @return The amount of time to complete this request - */ - virtual Tick write(PacketPtr pkt); - - /** - * Serialize this object to the given output stream. - * @param os The stream to serialize to. - */ - virtual void serialize(std::ostream &os); - - /** - * Reconstruct the state of this object from a checkpoint. - * @param cp The checkpoint use. - * @param section The section name of this object - */ - virtual void unserialize(Checkpoint *cp, const std::string §ion); + Tick read(PacketPtr pkt); + Tick write(PacketPtr pkt); + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); }; #endif // __IDE_CTRL_HH_ |