46 #include "debug/IdeCtrl.hh" 50 #include "params/IdeController.hh" 76 IdeController::Channel::Channel(
77 string newName,
Addr _cmdSize,
Addr _ctrlSize) :
79 cmdAddr(0), cmdSize(_cmdSize), ctrlAddr(0), ctrlSize(_ctrlSize),
80 master(NULL), slave(NULL), selected(NULL)
83 bmiRegs.status.dmaCap0 = 1;
84 bmiRegs.status.dmaCap1 = 1;
87 IdeController::Channel::~Channel()
92 :
PciDevice(p), primary(
name() +
".primary", BARSize[0], BARSize[1]),
93 secondary(
name() +
".secondary", BARSize[2], BARSize[3]),
94 bmiAddr(0), bmiSize(BARSize[4]),
97 deviceTiming(0), udmaControl(0), udmaTiming(0), ideConfig(0),
98 ioEnabled(false), bmEnabled(false),
99 ioShift(p->io_shift), ctrlOffset(p->ctrl_offset)
103 for (
int i = 0;
i <
params()->disks.size();
i++) {
120 panic(
"IDE controllers support a maximum " 121 "of 4 devices attached!\n");
151 primary.bmiRegs.status.intStatus = 1;
164 panic(
"Unable to find disk based on pointer %#x\n", disk);
167 channel->bmiRegs.command.startStop = 0;
168 channel->bmiRegs.status.active = 0;
169 channel->bmiRegs.status.intStatus = 1;
181 case sizeof(uint8_t):
202 panic(
"Invalid PCI configuration read for size 1 at offset: %#x!\n",
205 DPRINTF(IdeCtrl,
"PCI read offset: %#x size: 1 data: %#x\n", offset,
206 (uint32_t)pkt->
getLE<uint8_t>());
208 case sizeof(uint16_t):
226 panic(
"Invalid PCI configuration read for size 2 offset: %#x!\n",
229 DPRINTF(IdeCtrl,
"PCI read offset: %#x size: 2 data: %#x\n", offset,
230 (uint32_t)pkt->
getLE<uint16_t>());
232 case sizeof(uint32_t):
241 panic(
"No 32bit reads implemented for this device.");
243 DPRINTF(IdeCtrl,
"PCI read offset: %#x size: 4 data: %#x\n", offset,
244 (uint32_t)pkt->
getLE<uint32_t>());
247 panic(
"invalid access size(?) for PCI configspace!\n");
262 case sizeof(uint8_t):
277 panic(
"Invalid PCI configuration write " 278 "for size 1 offset: %#x!\n", offset);
280 DPRINTF(IdeCtrl,
"PCI write offset: %#x size: 1 data: %#x\n",
281 offset, (uint32_t)pkt->
getLE<uint8_t>());
283 case sizeof(uint16_t):
301 panic(
"Invalid PCI configuration write " 302 "for size 2 offset: %#x!\n",
305 DPRINTF(IdeCtrl,
"PCI write offset: %#x size: 2 data: %#x\n",
306 offset, (uint32_t)pkt->
getLE<uint16_t>());
308 case sizeof(uint32_t):
317 panic(
"Write of unimplemented PCI config. register: %x\n", offset);
321 panic(
"invalid access size(?) for PCI configspace!\n");
364 IdeController::Channel::accessCommand(
Addr offset,
367 const Addr SelectOffset = 6;
368 const uint8_t SelectDevBit = 0x10;
370 if (!read &&
offset == SelectOffset)
371 select(*
data & SelectDevBit);
373 if (selected == NULL) {
374 assert(size ==
sizeof(uint8_t));
384 IdeController::Channel::accessControl(
Addr offset,
387 if (selected == NULL) {
388 assert(size ==
sizeof(uint8_t));
398 IdeController::Channel::accessBMI(
Addr offset,
401 assert(
offset + size <=
sizeof(BMIRegs));
403 memcpy(
data, (uint8_t *)&bmiRegs +
offset, size);
408 if (size !=
sizeof(uint8_t))
409 panic(
"Invalid BMIC write size: %x\n", size);
411 BMICommandReg oldVal = bmiRegs.command;
412 BMICommandReg newVal = *
data;
415 if (oldVal.startStop && oldVal.rw != newVal.rw)
416 oldVal.rw = newVal.rw;
418 if (oldVal.startStop != newVal.startStop) {
419 if (selected == NULL)
420 panic(
"DMA start for disk which does not exist\n");
422 if (oldVal.startStop) {
423 DPRINTF(IdeCtrl,
"Stopping DMA transfer\n");
424 bmiRegs.status.active = 0;
426 selected->abortDma();
428 DPRINTF(IdeCtrl,
"Starting DMA transfer\n");
429 bmiRegs.status.active = 1;
431 selected->startDma(
letoh(bmiRegs.bmidtp));
435 bmiRegs.command = newVal;
440 if (size !=
sizeof(uint8_t))
441 panic(
"Invalid BMIS write size: %x\n", size);
443 BMIStatusReg oldVal = bmiRegs.status;
444 BMIStatusReg newVal = *
data;
447 newVal.active = oldVal.active;
450 if ((oldVal.intStatus == 1) && (newVal.intStatus == 1)) {
451 newVal.intStatus = 0;
456 uint8_t tmp = oldVal.intStatus;
457 newVal.intStatus = tmp;
459 if ((oldVal.dmaError == 1) && (newVal.dmaError == 1)) {
462 uint8_t tmp = oldVal.dmaError;
463 newVal.dmaError = tmp;
466 bmiRegs.status = newVal;
470 if (size !=
sizeof(uint32_t))
471 panic(
"Invalid BMIDTP write size: %x\n", size);
472 bmiRegs.bmidtp =
htole(*(uint32_t *)
data & ~0x3);
475 if (size !=
sizeof(uint8_t) && size !=
sizeof(uint16_t) &&
476 size !=
sizeof(uint32_t))
477 panic(
"IDE controller write of invalid write size: %x\n", size);
478 memcpy((uint8_t *)&bmiRegs +
offset,
data, size);
491 DPRINTF(IdeCtrl,
"io not enabled\n");
497 uint8_t *dataPtr = pkt->
getPtr<uint8_t>();
505 primary.accessCommand(addr, size, dataPtr, read);
506 }
else if (addr >=
primary.ctrlAddr &&
510 primary.accessControl(addr, size, dataPtr, read);
514 secondary.accessCommand(addr, size, dataPtr, read);
518 secondary.accessControl(addr, size, dataPtr, read);
523 if (addr <
sizeof(Channel::BMIRegs)) {
524 primary.accessBMI(addr, size, dataPtr, read);
526 addr -=
sizeof(Channel::BMIRegs);
527 secondary.accessBMI(addr, size, dataPtr, read);
530 panic(
"IDE controller access to invalid address: %#x\n", addr);
536 data = pkt->
getLE<uint8_t>();
538 data = pkt->
getLE<uint16_t>();
540 data = pkt->
getLE<uint32_t>();
541 DPRINTF(IdeCtrl,
"%s from offset: %#x size: %#x data: %#x\n",
569 primary.serialize(
"primary", cp);
595 uint8_t command = bmiRegs.command;
597 paramOut(cp,
base +
".bmiRegs.reserved0", bmiRegs.reserved0);
598 uint8_t
status = bmiRegs.status;
600 paramOut(cp,
base +
".bmiRegs.reserved1", bmiRegs.reserved1);
612 primary.unserialize(
"primary", cp);
639 bmiRegs.command = command;
640 paramIn(cp,
base +
".bmiRegs.reserved0", bmiRegs.reserved0);
644 paramIn(cp,
base +
".bmiRegs.reserved1", bmiRegs.reserved1);
645 paramIn(cp,
base +
".bmiRegs.bmidtp", bmiRegs.bmidtp);
651 IdeControllerParams::create()
#define panic(...)
This implements a cprintf based panic() function.
Tick readConfig(PacketPtr pkt) override
Read from the PCI config space data that is stored locally.
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
const std::string & name()
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
PCI device, base implementation is only config space.
bool isDiskSelected(IdeDisk *diskPtr)
See if a disk is selected based on its pointer.
Device model for an IDE disk.
Device model for an Intel PIIX4 IDE controller.
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
Simple PCI IDE controller with bus mastering capability and UDMA modeled after controller in the Inte...
T * getPtr()
get a pointer to the data ptr.
uint16_t primaryTiming
Registers used in device specific PCI configuration.
void dispatchAccess(PacketPtr pkt, bool read)
void setLE(T v)
Set the value in the data pointer to v as little endian.
#define UNSERIALIZE_SCALAR(scalar)
bool legacyIO[6]
Whether the BARs are really hardwired legacy IO locations.
void makeAtomicResponse()
uint64_t Tick
Tick count type.
virtual Tick writeConfig(PacketPtr pkt)
Write to the PCI config space data that is stored locally.
void paramOut(CheckpointOut &cp, const string &name, ExtMachInst const &machInst)
void replaceBits(T &val, int first, int last, B bit_val)
A convenience function to replace bits first to last of val with bit_val in place.
void serialize(const ThreadContext &tc, CheckpointOut &cp)
Thread context serialization helpers.
virtual Tick readConfig(PacketPtr pkt)
Read from the PCI config space data that is stored locally.
const Params * params() const
#define PCI_DEVICE_SPECIFIC
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Addr BARAddrs[6]
The current address mapping of the BARs.
#define SERIALIZE_SCALAR(scalar)
Addr bmiAddr
Bus master interface (BMI) registers.
Declaration of the Packet class.
std::ostream CheckpointOut
static const uint16_t timeRegWithDecodeEn
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
void unserialize(ThreadContext &tc, CheckpointIn &cp)
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
PCIConfig config
The current config space.
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
void setDmaComplete(IdeDisk *disk)
Tick writeConfig(PacketPtr pkt) override
Write to the PCI config space data that is stored locally.
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
uint32_t BARSize[6]
The size of the BARs.
Addr getPageBytes() const
Get the page bytes for the ISA.