Go to the documentation of this file.
55 #include "debug/IdeDisk.hh"
62 :
SimObject(
p), ctrl(NULL), image(
p->image), diskDelay(
p->delay),
65 dmaReadWaitEvent([
this]{ doDmaRead(); },
name()),
67 dmaWriteWaitEvent([
this]{ doDmaWrite(); },
name()),
68 dmaPrdReadEvent([
this]{ dmaPrdReadDone(); },
name()),
69 dmaReadEvent([
this]{ dmaReadDone(); },
name()),
70 dmaWriteEvent([
this]{ dmaWriteDone(); },
name())
76 memset(&driveID, 0,
sizeof(
struct ataparams));
83 uint32_t lba_size = image->size();
84 if (lba_size >= 16383*16*63) {
91 else if (lba_size == 0)
92 panic(
"Bad IDE image size: 0\n");
96 if ((lba_size / sectors) >= 16)
99 heads = (lba_size / sectors);
101 cylinders = lba_size / (heads * sectors);
105 strncpy((
char *)driveID.atap_model,
"5MI EDD si k",
106 sizeof(driveID.atap_model));
110 driveID.atap_capabilities1 = 0x7;
112 driveID.atap_extensions = 0x6;
114 driveID.atap_cylinders = cylinders;
115 driveID.atap_sectors = sectors;
116 driveID.atap_heads = heads;
119 driveID.atap_curmulti_valid = 0x1;
121 driveID.atap_capacity = lba_size;
123 driveID.atap_dmamode_supp = 0x4;
125 driveID.atap_piomode_supp = 0x3;
127 driveID.atap_udmamode_supp = 0x1f;
129 driveID.atap_hwreset_res = 0x4001;
166 }
else if (
id ==
DEV1) {
170 panic(
"Invalid device ID: %#x\n",
id);
197 panic(
"Access to unset controller!\n");
208 if (size ==
sizeof(uint16_t)) {
210 }
else if (size ==
sizeof(uint32_t)) {
215 panic(
"Data read of unsupported size %d.\n", size);
220 assert(size ==
sizeof(uint8_t));
245 panic(
"Invalid IDE command register offset: %#x\n",
offset);
253 assert(size ==
sizeof(uint8_t));
256 panic(
"Invalid IDE control register offset: %#x\n",
offset);
264 if (size ==
sizeof(uint16_t)) {
266 }
else if (size ==
sizeof(uint32_t)) {
271 panic(
"Data write of unsupported size %d.\n", size);
277 assert(size ==
sizeof(uint8_t));
302 panic(
"Invalid IDE command register offset: %#x\n",
offset);
312 panic(
"Invalid IDE control register offset: %#x\n",
offset);
342 panic(
"Inconsistent DMA transfer state: dmaState = %d devState = %d\n",
363 "PRD: baseAddr:%#x (%#x) byteCount:%d (%d) eot:%#x sector:%d\n",
394 using namespace Stats;
396 .
name(
name() +
".dma_read_full_pages")
397 .
desc(
"Number of full page size DMA reads (not PRD).")
401 .
desc(
"Number of bytes transfered via DMA reads (not PRD).")
405 .
desc(
"Number of DMA read transactions (not PRD).")
409 .
name(
name() +
".dma_write_full_pages")
410 .
desc(
"Number of full page size DMA writes.")
414 .
desc(
"Number of bytes transfered via DMA writes.")
418 .
desc(
"Number of DMA write transactions.")
464 uint32_t bytesWritten = 0;
489 uint32_t bytesRead = 0;
491 DPRINTF(
IdeDisk,
"doDmaWrite, diskDelay: %d totalDiskDelay: %d\n",
531 DPRINTF(
IdeDisk,
"doDmaWrite: not done curPrd byte count %d, eot %#x\n",
539 DPRINTF(
IdeDisk,
"doDmaWrite: done curPrd byte count %d, eot %#x\n",
551 DPRINTF(
IdeDisk,
"doWriteDone: curPrd byte count %d, eot %#x cmd bytes left:%d\n",
573 panic(
"Can't read from %s. Only %d of %d read. errno=%d\n",
583 panic(
"Can't write to %s. Only %d of %d written. errno=%d\n",
595 panic(
"Inconsistent DMA state, should be in Dma_Start!\n");
598 panic(
"Inconsistent device state for DMA start!\n");
613 panic(
"Inconsistent DMA state, should be Start or Transfer!");
616 panic(
"Inconsistent device state, should be Transfer or Prepare!\n");
666 panic(
"Attempt to perform CHS access, only supports LBA\n");
684 panic(
"Attempt to perform CHS access, only supports LBA\n");
703 panic(
"Attempt to perform CHS access, only supports LBA\n");
742 panic(
"Attempt to post an interrupt with one pending\n");
757 panic(
"Attempt to clear a non-pending interrupt\n");
891 panic(
"DEBUG: READING DATA ONE BYTE AT A TIME!\n");
967 panic(
"DEBUG: WRITING DATA ONE BYTE AT A TIME!\n");
1018 panic(
"Inconsistent DMA state, should be Dma_Idle\n");
1061 DPRINTF(
IdeDisk,
"Disk still busy aborting previous DMA command\n");
1111 assert(eventCount <= 1);
1202 IdeDiskParams::create()
void serialize(CheckpointOut &cp) const override
Serialize an object.
Stats::Scalar dmaReadBytes
virtual void regStats()
Callback to set stat parameters.
virtual std::streampos write(const uint8_t *data, std::streampos offset)=0
bool scheduled() const
Determine if the current event is scheduled.
uint32_t curPrdAddr
PRD table base address.
unsigned complete() const
Number of bytes we have already chunked up.
@ Running
Running normally.
#define UNSERIALIZE_SCALAR(scalar)
uint8_t status
Status register.
EventFunctionWrapper dmaPrdReadEvent
~IdeDisk()
Delete the data buffer.
void reschedule(Event &event, Tick when, bool always=false)
#define WDSF_READ_NATIVE_MAX
uint64_t Tick
Tick count type.
void updateState(DevAction_t action)
PrdTableEntry curPrd
PRD entry.
EventFunctionWrapper dmaReadWaitEvent
int diskDelay
The disk delay in microseconds.
void startDma(const uint32_t &prdTableBase)
Tick when() const
Get the time that the event is scheduled.
virtual std::streampos size() const =0
Addr pageBytes
Size of OS pages.
ChunkGenerator * dmaReadCG
DevState_t devState
Device state.
void writeDisk(uint32_t sector, uint8_t *data)
#define SERIALIZE_ENUM(scalar)
unsigned size() const
Return size in bytes of current chunk.
uint32_t cmdBytes
Number of bytes in command data transfer.
CommandReg_t cmdReg
Command block registers.
Addr addr() const
Return starting address of current chunk.
DmaState_t dmaState
Dma state.
void dmaRead(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
bool isDiskSelected(IdeDisk *diskPtr)
See if a disk is selected based on its pointer.
void readControl(const Addr offset, int size, uint8_t *data)
EventFunctionWrapper dmaWriteEvent
void schedule(Event &event, Tick when)
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
void regStats() override
Register Statistics.
Addr pciToDma(Addr pciAddr)
void writeControl(const Addr offset, int size, const uint8_t *data)
Stats::Scalar dmaReadFullPages
void setDmaComplete(IdeDisk *disk)
uint32_t curSector
Current sector in access.
Stats::Scalar dmaWriteTxs
struct PrdEntry PrdEntry_t
void reset(int id)
Reset the device state.
bool next()
Advance generator to next chunk.
#define SERIALIZE_ARRAY(member, size)
bool dmaAborted
DMA Aborted.
EventFunctionWrapper dmaReadEvent
Stats::Scalar dmaWriteFullPages
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
#define DMA_BACKOFF_PERIOD
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
bool done() const
Are we done? That is, did the last call to next() advance past the end of the region?
const std::string & name()
#define SERIALIZE_SCALAR(scalar)
bool intrPending
Interrupt pending.
struct ataparams driveID
Drive identification structure for this disk.
DrainState drainState() const
Return the current drain state of an object.
virtual const std::string name() const
IdeController * ctrl
The IDE controller for this disk.
int devID
Device ID (device0=0/device1=1)
DiskImage * image
The image that contains the data of this disk.
#define UNSERIALIZE_ARRAY(member, size)
void readCommand(const Addr offset, int size, uint8_t *data)
enum DevAction DevAction_t
#define ATAPI_IDENTIFY_DEVICE
#define WDCC_STANDBY_IMMED
bool dmaRead
Dma transaction is a read.
virtual std::streampos read(uint8_t *data, std::streampos offset) const =0
std::ostream CheckpointOut
void unserialize(CheckpointIn &cp) override
Unserialize an object.
#define UNSERIALIZE_ENUM(scalar)
This class takes an arbitrary memory region (address/length pair) and generates a series of appropria...
bool nIENBit
Interrupt enable bit.
uint32_t cmdBytesLeft
Number of bytes left in command data transfer.
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
uint8_t * dataBuffer
Data buffer for transfers.
void writeCommand(const Addr offset, int size, const uint8_t *data)
uint32_t drqBytesLeft
Number of bytes left in DRQ block.
#define ULL(N)
uint64_t constant
Stats::Scalar dmaWriteBytes
Addr pciToDma(Addr pci_addr) const
EventFunctionWrapper dmaTransferEvent
ChunkGenerator * dmaWriteCG
#define panic(...)
This implements a cprintf based panic() function.
EventFunctionWrapper dmaWriteWaitEvent
void readDisk(uint32_t sector, uint8_t *data)
Tick curTick()
The current simulated tick.
Abstract superclass for simulation objects.
Generated on Wed Sep 30 2020 14:02:11 for gem5 by doxygen 1.8.17