/*
- * 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
#include <deque>
#include <string>
-#include "arch/alpha/pmap.h"
#include "base/cprintf.hh" // csprintf
#include "base/trace.hh"
#include "dev/disk_image.hh"
#include "sim/builder.hh"
#include "sim/sim_object.hh"
#include "sim/universe.hh"
+#include "targetarch/isa_traits.hh"
using namespace std;
// Utility functions
////
+bool
+IdeDisk::isDEVSelect()
+{
+ return ctrl->isDiskSelected(this);
+}
+
Addr
IdeDisk::pciToDma(Addr pciAddr)
{
if (ctrl)
- return ctrl->tsunami->pchip->translatePciToDma(pciAddr);
+ return ctrl->plat->pciToDma(pciAddr);
else
panic("Access to unset controller!\n");
}
uint32_t bytesInPage = 0;
// First calculate how many bytes could be in the page
- if (bytesLeft > ALPHA_PGBYTES)
- bytesInPage = ALPHA_PGBYTES;
+ if (bytesLeft > TheISA::PageBytes)
+ bytesInPage = TheISA::PageBytes;
else
bytesInPage = bytesLeft;
// Next, see if we have crossed a page boundary, and adjust
Addr upperBound = curAddr + bytesInPage;
- Addr pageBound = alpha_trunc_page(curAddr) + ALPHA_PGBYTES;
+ Addr pageBound = TheISA::TruncPage(curAddr) + TheISA::PageBytes;
assert(upperBound >= curAddr && "DMA read wraps around address space!\n");
physmem->dma_addr(curPrdAddr, sizeof(PrdEntry_t)),
sizeof(PrdEntry_t));
- curPrdAddr += sizeof(PrdEntry_t);
+ DPRINTF(IdeDisk, "PRD: baseAddr:%#x (%#x) byteCount:%d (%d) eot:%#x sector:%d\n",
+ curPrd.getBaseAddr(), pciToDma(curPrd.getBaseAddr()),
+ curPrd.getByteCount(), (cmdBytesLeft/SectorSize),
+ curPrd.getEOT(), curSector);
+
+ // the prd pointer has already been translated, so just do an increment
+ curPrdAddr = curPrdAddr + sizeof(PrdEntry_t);
if (dmaRead)
doDmaRead();
writeDisk(curSector++, (uint8_t *)(dataBuffer + bytesWritten));
}
-#if 0
- // actually copy the data from memory to data buffer
- Addr dmaAddr =
- ctrl->tsunami->pchip->translatePciToDma(curPrd.getBaseAddr());
- memcpy((void *)dataBuffer,
- physmem->dma_addr(dmaAddr, curPrd.getByteCount()),
- curPrd.getByteCount());
-
- uint32_t bytesWritten = 0;
-
- while (bytesWritten < curPrd.getByteCount()) {
- if (cmdBytesLeft <= 0)
- panic("DMA data is larger than # sectors specified\n");
-
- writeDisk(curSector++, (uint8_t *)(dataBuffer + bytesWritten));
-
- bytesWritten += SectorSize;
- cmdBytesLeft -= SectorSize;
- }
-#endif
-
// check for the EOT
- if (curPrd.getEOT()){
+ if (curPrd.getEOT()) {
assert(cmdBytesLeft == 0);
dmaState = Dma_Idle;
updateState(ACT_DMA_DONE);
// setup the initial page and DMA address
curAddr = curPrd.getBaseAddr();
- pageAddr = alpha_trunc_page(curAddr);
+ pageAddr = TheISA::TruncPage(curAddr);
dmaAddr = pciToDma(curAddr);
// clear out the data buffer
while (bytesRead < curPrd.getByteCount()) {
// see if we have crossed into a new page
- if (pageAddr != alpha_trunc_page(curAddr)) {
+ if (pageAddr != TheISA::TruncPage(curAddr)) {
// write the data to memory
memcpy(physmem->dma_addr(dmaAddr, bytesInPage),
(void *)(dataBuffer + (bytesRead - bytesInPage)),
bytesInPage);
// update the DMA address and page address
- pageAddr = alpha_trunc_page(curAddr);
+ pageAddr = TheISA::TruncPage(curAddr);
dmaAddr = pciToDma(curAddr);
bytesInPage = 0;
bytesInPage);
}
-#if 0
- Addr dmaAddr = ctrl->tsunami->pchip->
- translatePciToDma(curPrd.getBaseAddr());
-
- memcpy(physmem->dma_addr(dmaAddr, curPrd.getByteCount()),
- (void *)dataBuffer, curPrd.getByteCount());
-#endif
-
// check for the EOT
if (curPrd.getEOT()) {
assert(cmdBytesLeft == 0);
if (devState != Transfer_Data_Dma)
panic("Inconsistent device state for DMA start!\n");
- curPrdAddr = pciToDma((Addr)prdTableBase);
+ // PRD base address is given by bits 31:2
+ curPrdAddr = pciToDma((Addr)(prdTableBase & ~ULL(0x3)));
dmaState = Dma_Transfer;
void
IdeDisk::intrPost()
{
+ DPRINTF(IdeDisk, "IDE Disk Posting Interrupt\n");
if (intrPending)
panic("Attempt to post an interrupt with one pending\n");
void
IdeDisk::intrClear()
{
+ DPRINTF(IdeDisk, "IDE Disk Clearing Interrupt\n");
if (!intrPending)
panic("Attempt to clear a non-pending interrupt\n");
Tick reschedule = 0;
Events_t event = None;
+ int eventCount = 0;
+
if (dmaTransferEvent.scheduled()) {
reschedule = dmaTransferEvent.when();
event = Transfer;
- } else if (dmaReadWaitEvent.scheduled()) {
+ eventCount++;
+ }
+ if (dmaReadWaitEvent.scheduled()) {
reschedule = dmaReadWaitEvent.when();
event = ReadWait;
- } else if (dmaWriteWaitEvent.scheduled()) {
+ eventCount++;
+ }
+ if (dmaWriteWaitEvent.scheduled()) {
reschedule = dmaWriteWaitEvent.when();
event = WriteWait;
- } else if (dmaPrdReadEvent.scheduled()) {
+ eventCount++;
+ }
+ if (dmaPrdReadEvent.scheduled()) {
reschedule = dmaPrdReadEvent.when();
event = PrdRead;
- } else if (dmaReadEvent.scheduled()) {
+ eventCount++;
+ }
+ if (dmaReadEvent.scheduled()) {
reschedule = dmaReadEvent.when();
event = DmaRead;
- } else if (dmaWriteEvent.scheduled()) {
+ eventCount++;
+ }
+ if (dmaWriteEvent.scheduled()) {
reschedule = dmaWriteEvent.when();
event = DmaWrite;
+ eventCount++;
}
+ assert(eventCount <= 1);
+
SERIALIZE_SCALAR(reschedule);
SERIALIZE_ENUM(event);
SERIALIZE_SCALAR(cmdReg.cyl_low);
SERIALIZE_SCALAR(cmdReg.cyl_high);
SERIALIZE_SCALAR(cmdReg.drive);
+ SERIALIZE_SCALAR(cmdReg.command);
SERIALIZE_SCALAR(status);
SERIALIZE_SCALAR(nIENBit);
SERIALIZE_SCALAR(devID);
UNSERIALIZE_SCALAR(cmdReg.cyl_low);
UNSERIALIZE_SCALAR(cmdReg.cyl_high);
UNSERIALIZE_SCALAR(cmdReg.drive);
+ UNSERIALIZE_SCALAR(cmdReg.command);
UNSERIALIZE_SCALAR(status);
UNSERIALIZE_SCALAR(nIENBit);
UNSERIALIZE_SCALAR(devID);