ide_disk.hh
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· HH 代码 · 共 372 行
HH
372 行
/* * Copyright (c) 2004, 2005 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Andrew L. Schultz *//** @file * Device model for an IDE disk */#ifndef __IDE_DISK_HH__#define __IDE_DISK_HH__#include "base/statistics.hh"#include "dev/disk_image.hh"#include "dev/ide_atareg.h"#include "dev/ide_ctrl.hh"#include "dev/ide_wdcreg.h"#include "dev/io_device.hh"#include "sim/eventq.hh"#include "params/IdeDisk.hh"class ChunkGenerator;#define DMA_BACKOFF_PERIOD 200#define MAX_DMA_SIZE (131072) // 128K#define MAX_MULTSECT (128)#define PRD_BASE_MASK 0xfffffffe#define PRD_COUNT_MASK 0xfffe#define PRD_EOT_MASK 0x8000typedef struct PrdEntry { uint32_t baseAddr; uint16_t byteCount; uint16_t endOfTable;} PrdEntry_t;class PrdTableEntry { public: PrdEntry_t entry; uint32_t getBaseAddr() { return (entry.baseAddr & PRD_BASE_MASK); } uint32_t getByteCount() { return ((entry.byteCount == 0) ? MAX_DMA_SIZE : (entry.byteCount & PRD_COUNT_MASK)); } uint16_t getEOT() { return (entry.endOfTable & PRD_EOT_MASK); }};#define DATA_OFFSET (0)#define ERROR_OFFSET (1)#define FEATURES_OFFSET (1)#define NSECTOR_OFFSET (2)#define SECTOR_OFFSET (3)#define LCYL_OFFSET (4)#define HCYL_OFFSET (5)#define SELECT_OFFSET (6)#define DRIVE_OFFSET (6)#define STATUS_OFFSET (7)#define COMMAND_OFFSET (7)#define CONTROL_OFFSET (2)#define ALTSTAT_OFFSET (2)#define SELECT_DEV_BIT 0x10#define CONTROL_RST_BIT 0x04#define CONTROL_IEN_BIT 0x02#define STATUS_BSY_BIT 0x80#define STATUS_DRDY_BIT 0x40#define STATUS_DRQ_BIT 0x08#define STATUS_SEEK_BIT 0x10#define STATUS_DF_BIT 0x20#define DRIVE_LBA_BIT 0x40#define DEV0 (0)#define DEV1 (1)typedef struct CommandReg { uint16_t data; uint8_t error; uint8_t sec_count; uint8_t sec_num; uint8_t cyl_low; uint8_t cyl_high; union { uint8_t drive; uint8_t head; }; 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_READ_SHORT, ACT_DATA_WRITE_BYTE, ACT_DATA_WRITE_SHORT, ACT_DMA_READY, ACT_DMA_DONE, ACT_SRST_SET, ACT_SRST_CLEAR} DevAction_t;typedef enum DevState { // Device idle Device_Idle_S = 0, Device_Idle_SI, Device_Idle_NS, // Software reset Device_Srst, // Non-data commands Command_Execution, // PIO data-in (data to host) Prepare_Data_In, Data_Ready_INTRQ_In, Transfer_Data_In, // PIO data-out (data from host) Prepare_Data_Out, Data_Ready_INTRQ_Out, Transfer_Data_Out, // DMA protocol Prepare_Data_Dma, Transfer_Data_Dma} DevState_t;typedef enum DmaState { Dma_Idle = 0, Dma_Start, Dma_Transfer} DmaState_t;class PhysicalMemory;class IdeController;/** * IDE Disk device model */class IdeDisk : public SimObject{ protected: /** The IDE controller for this disk. */ IdeController *ctrl; /** The image that contains the data of this disk. */ DiskImage *image; protected: /** The disk delay in microseconds. */ int diskDelay; private: /** Drive identification structure for this disk */ struct ataparams 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 drqBytesLeft; /** Current sector in access */ uint32_t curSector; /** Command block registers */ CommandReg_t cmdReg; /** Status register */ uint8_t status; /** Interrupt enable bit */ bool nIENBit; /** Device state */ DevState_t devState; /** Dma state */ DmaState_t dmaState; /** Dma transaction is a read */ bool dmaRead; /** PRD table base address */ uint32_t curPrdAddr; /** PRD entry */ PrdTableEntry curPrd; /** Device ID (master=0/slave=1) */ int devID; /** Interrupt pending */ bool intrPending; Stats::Scalar<> dmaReadFullPages; Stats::Scalar<> dmaReadBytes; Stats::Scalar<> dmaReadTxs; Stats::Scalar<> dmaWriteFullPages; Stats::Scalar<> dmaWriteBytes; Stats::Scalar<> dmaWriteTxs; Stats::Formula rdBandwidth; Stats::Formula wrBandwidth; Stats::Formula totBandwidth; Stats::Formula totBytes; public: typedef IdeDiskParams Params; IdeDisk(const Params *p); /** * Delete the data buffer. */ ~IdeDisk(); /** * Reset the device state */ void reset(int id); /** * Register Statistics */ void regStats(); /** * Set the controller for this device * @param c The IDE controller */ void setController(IdeController *c) { if (ctrl) panic("Cannot change the controller once set!\n"); ctrl = c; } // Device register read/write void read(const Addr &offset, IdeRegType regtype, uint8_t *data); void write(const Addr &offset, IdeRegType regtype, const uint8_t *data); // Start/abort functions void startDma(const uint32_t &prdTableBase); void abortDma(); private: void startCommand(); // Interrupt management void intrPost(); void intrClear(); // DMA stuff void doDmaTransfer(); friend class EventWrapper<IdeDisk, &IdeDisk::doDmaTransfer>; EventWrapper<IdeDisk, &IdeDisk::doDmaTransfer> dmaTransferEvent; void doDmaDataRead(); void doDmaRead(); ChunkGenerator *dmaReadCG; friend class EventWrapper<IdeDisk, &IdeDisk::doDmaRead>; EventWrapper<IdeDisk, &IdeDisk::doDmaRead> dmaReadWaitEvent; void doDmaDataWrite(); void doDmaWrite(); ChunkGenerator *dmaWriteCG; friend class EventWrapper<IdeDisk, &IdeDisk::doDmaWrite>; EventWrapper<IdeDisk, &IdeDisk::doDmaWrite> dmaWriteWaitEvent; void dmaPrdReadDone(); friend class EventWrapper<IdeDisk, &IdeDisk::dmaPrdReadDone>; EventWrapper<IdeDisk, &IdeDisk::dmaPrdReadDone> dmaPrdReadEvent; void dmaReadDone(); friend class EventWrapper<IdeDisk, &IdeDisk::dmaReadDone>; EventWrapper<IdeDisk, &IdeDisk::dmaReadDone> dmaReadEvent; void dmaWriteDone(); friend class EventWrapper<IdeDisk, &IdeDisk::dmaWriteDone>; EventWrapper<IdeDisk, &IdeDisk::dmaWriteDone> dmaWriteEvent; // Disk image read/write void readDisk(uint32_t sector, uint8_t *data); void writeDisk(uint32_t sector, uint8_t *data); // State machine management void updateState(DevAction_t action); // Utility functions bool isBSYSet() { return (status & STATUS_BSY_BIT); } bool isIENSet() { return nIENBit; } bool isDEVSelect(); void setComplete() { // clear out the status byte status = 0; // set the DRDY bit status |= STATUS_DRDY_BIT; // set the SEEK bit status |= STATUS_SEEK_BIT; } uint32_t getLBABase() { return (Addr)(((cmdReg.head & 0xf) << 24) | (cmdReg.cyl_high << 16) | (cmdReg.cyl_low << 8) | (cmdReg.sec_num)); } inline Addr pciToDma(Addr pciAddr); /** * Serialize this object to the given output stream. * @param os The stream to serialize to. */ void serialize(std::ostream &os); /** * Reconstruct the state of this object from a checkpoint. * @param cp The checkpoint to use. * @param section The section name describing this object. */ void unserialize(Checkpoint *cp, const std::string §ion);};#endif // __IDE_DISK_HH__
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?