55 #include "arch/isa_traits.hh"
59 #include "config/the_isa.hh"
60 #include "debug/IdeDisk.hh"
67 using namespace TheISA;
70 :
SimObject(p), ctrl(NULL), image(p->image), diskDelay(p->delay),
71 dmaTransferEvent(this), dmaReadCG(NULL), dmaReadWaitEvent(this),
72 dmaWriteCG(NULL), dmaWriteWaitEvent(this), dmaPrdReadEvent(this),
73 dmaReadEvent(this), dmaWriteEvent(this)
87 if (lba_size >= 16383*16*63) {
94 else if (lba_size == 0)
95 panic(
"Bad IDE image size: 0\n");
99 if ((lba_size / sectors) >= 16)
102 heads = (lba_size / sectors);
104 cylinders = lba_size / (heads * sectors);
169 }
else if (
id ==
DEV1) {
173 panic(
"Invalid device ID: %#x\n",
id);
200 panic(
"Access to unset controller!\n");
211 if (size ==
sizeof(uint16_t)) {
213 }
else if (size ==
sizeof(uint32_t)) {
218 panic(
"Data read of unsupported size %d.\n", size);
223 assert(size ==
sizeof(uint8_t));
248 panic(
"Invalid IDE command register offset: %#x\n", offset);
250 DPRINTF(
IdeDisk,
"Read to disk at offset: %#x data %#x\n", offset, *data);
256 assert(size ==
sizeof(uint8_t));
259 panic(
"Invalid IDE control register offset: %#x\n", offset);
260 DPRINTF(
IdeDisk,
"Read to disk at offset: %#x data %#x\n", offset, *data);
267 if (size ==
sizeof(uint16_t)) {
269 }
else if (size ==
sizeof(uint32_t)) {
274 panic(
"Data write of unsupported size %d.\n", size);
280 assert(size ==
sizeof(uint8_t));
305 panic(
"Invalid IDE command register offset: %#x\n", offset);
307 DPRINTF(
IdeDisk,
"Write to disk at offset: %#x data %#x\n", offset,
315 panic(
"Invalid IDE control register offset: %#x\n", offset);
327 DPRINTF(
IdeDisk,
"Write to disk at offset: %#x data %#x\n", offset,
345 panic(
"Inconsistent DMA transfer state: dmaState = %d devState = %d\n",
366 "PRD: baseAddr:%#x (%#x) byteCount:%d (%d) eot:%#x sector:%d\n",
397 using namespace Stats;
399 .
name(
name() +
".dma_read_full_pages")
400 .
desc(
"Number of full page size DMA reads (not PRD).")
404 .
desc(
"Number of bytes transfered via DMA reads (not PRD).")
408 .
desc(
"Number of DMA read transactions (not PRD).")
412 .
name(
name() +
".dma_write_full_pages")
413 .
desc(
"Number of full page size DMA writes.")
417 .
desc(
"Number of bytes transfered via DMA writes.")
421 .
desc(
"Number of DMA write transactions.")
467 uint32_t bytesWritten = 0;
492 uint32_t bytesRead = 0;
494 DPRINTF(
IdeDisk,
"doDmaWrite, diskDelay: %d totalDiskDelay: %d\n",
534 DPRINTF(
IdeDisk,
"doDmaWrite: not done curPrd byte count %d, eot %#x\n",
542 DPRINTF(
IdeDisk,
"doDmaWrite: done curPrd byte count %d, eot %#x\n",
554 DPRINTF(
IdeDisk,
"doWriteDone: curPrd byte count %d, eot %#x cmd bytes left:%d\n",
573 uint32_t bytesRead =
image->
read(data, sector);
576 panic(
"Can't read from %s. Only %d of %d read. errno=%d\n",
583 uint32_t bytesWritten =
image->
write(data, sector);
586 panic(
"Can't write to %s. Only %d of %d written. errno=%d\n",
598 panic(
"Inconsistent DMA state, should be in Dma_Start!\n");
601 panic(
"Inconsistent device state for DMA start!\n");
616 panic(
"Inconsistent DMA state, should be Start or Transfer!");
619 panic(
"Inconsistent device state, should be Transfer or Prepare!\n");
669 panic(
"Attempt to perform CHS access, only supports LBA\n");
687 panic(
"Attempt to perform CHS access, only supports LBA\n");
705 panic(
"Attempt to perform CHS access, only supports LBA\n");
744 panic(
"Attempt to post an interrupt with one pending\n");
759 panic(
"Attempt to clear a non-pending interrupt\n");
893 panic(
"DEBUG: READING DATA ONE BYTE AT A TIME!\n");
969 panic(
"DEBUG: WRITING DATA ONE BYTE AT A TIME!\n");
1020 panic(
"Inconsistent DMA state, should be Dma_Idle\n");
1063 DPRINTF(
IdeDisk,
"Disk still busy aborting previous DMA command\n");
1113 assert(eventCount <= 1);
1204 IdeDiskParams::create()
bool nIENBit
Interrupt enable bit.
bool next()
Advance generator to next chunk.
void reset(int id)
Reset the device state.
void writeCommand(const Addr offset, int size, const uint8_t *data)
EventWrapper< IdeDisk,&IdeDisk::dmaWriteDone > dmaWriteEvent
~IdeDisk()
Delete the data buffer.
DmaState_t dmaState
Dma state.
void dmaRead(Addr addr, int size, Event *event, uint8_t *data, Tick delay=0)
ChunkGenerator * dmaWriteCG
uint8_t atap_piomode_supp
bool isDiskSelected(IdeDisk *diskPtr)
See if a disk is selected based on its pointer.
struct PrdEntry PrdEntry_t
uint32_t curPrdAddr
PRD table base address.
void regStats() override
Register Statistics.
void serialize(CheckpointOut &cp) const override
Serialize an object.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Device model for an IDE disk.
uint8_t atap_capabilities1
unsigned size() const
Return size in bytes of current chunk.
#define WDCC_STANDBY_IMMED
bool scheduled() const
Determine if the current event is scheduled.
int devID
Device ID (master=0/slave=1)
DiskImage * image
The image that contains the data of this disk.
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data, Tick delay=0)
Simple PCI IDE controller with bus mastering capability and UDMA modeled after controller in the Inte...
unsigned complete() const
Number of bytes we have already chunked up.
bool dmaAborted
DMA Aborted.
EventWrapper< IdeDisk,&IdeDisk::dmaPrdReadDone > dmaPrdReadEvent
uint16_t atap_hwreset_res
uint32_t drqBytesLeft
Number of bytes left in DRQ block.
virtual void regStats()
Register statistics for this object.
void updateState(DevAction_t action)
Stats::Scalar dmaWriteBytes
Addr pciToDma(Addr pci_addr) const
EventWrapper< IdeDisk,&IdeDisk::doDmaTransfer > dmaTransferEvent
virtual std::streampos size() const =0
uint8_t atap_curmulti_valid
#define UNSERIALIZE_SCALAR(scalar)
Tick curTick()
The current simulated tick.
uint32_t cmdBytesLeft
Number of bytes left in command data transfer.
void readCommand(const Addr offset, int size, uint8_t *data)
Tick when() const
Get the time that the event is scheduled.
#define WDSF_READ_NATIVE_MAX
uint64_t Tick
Tick count type.
Stats::Scalar dmaReadBytes
This class takes an arbitrary memory region (address/length pair) and generates a series of appropria...
uint8_t atap_udmamode_supp
virtual std::streampos write(const uint8_t *data, std::streampos offset)=0
#define SERIALIZE_ARRAY(member, size)
struct ataparams driveID
Drive identification structure for this disk.
EventWrapper< IdeDisk,&IdeDisk::doDmaWrite > dmaWriteWaitEvent
void writeControl(const Addr offset, int size, const uint8_t *data)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
#define ULL(N)
uint64_t constant
#define DMA_BACKOFF_PERIOD
uint32_t curSector
Current sector in access.
uint8_t status
Status register.
EventWrapper< IdeDisk,&IdeDisk::doDmaRead > dmaReadWaitEvent
DevState_t devState
Device state.
#define SERIALIZE_SCALAR(scalar)
#define UNSERIALIZE_ENUM(scalar)
#define UNSERIALIZE_ARRAY(member, size)
enum DevAction DevAction_t
ChunkGenerator * dmaReadCG
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
uint32_t cmdBytes
Number of bytes in command data transfer.
void reschedule(Event &event, Tick when, bool always=false)
PrdTableEntry curPrd
PRD entry.
virtual const std::string name() const
CommandReg_t cmdReg
Command block registers.
bool intrPending
Interrupt pending.
std::ostream CheckpointOut
EventWrapper< IdeDisk,&IdeDisk::dmaReadDone > dmaReadEvent
bool done() const
Are we done? That is, did the last call to next() advance past the end of the region?
virtual std::streampos read(uint8_t *data, std::streampos offset) const =0
bool dmaRead
Dma transaction is a read.
void startDma(const uint32_t &prdTableBase)
Addr pciToDma(Addr pciAddr)
#define ATAPI_IDENTIFY_DEVICE
Stats::Scalar dmaReadFullPages
Addr addr() const
Return starting address of current chunk.
void schedule(Event &event, Tick when)
DrainState drainState() const
Return the current drain state of an object.
IdeController * ctrl
The IDE controller for this disk.
void writeDisk(uint32_t sector, uint8_t *data)
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.
Declaration and inline definition of ChunkGenerator object.
void readControl(const Addr offset, int size, uint8_t *data)
uint8_t atap_dmamode_supp
void readDisk(uint32_t sector, uint8_t *data)
void setDmaComplete(IdeDisk *disk)
Stats::Scalar dmaWriteFullPages
Abstract superclass for simulation objects.
int diskDelay
The disk delay in microseconds.
#define SERIALIZE_ENUM(scalar)
Stats::Scalar dmaWriteTxs