50 #include "debug/IdeCtrl.hh" 54 #include "params/IdeController.hh" 80 IdeController::Channel::Channel(
81 string newName,
Addr _cmdSize,
Addr _ctrlSize) :
83 cmdAddr(0), cmdSize(_cmdSize), ctrlAddr(0), ctrlSize(_ctrlSize),
84 master(NULL), slave(NULL), selected(NULL)
87 bmiRegs.status.dmaCap0 = 1;
88 bmiRegs.status.dmaCap1 = 1;
91 IdeController::Channel::~Channel()
96 :
PciDevice(p), primary(
name() +
".primary", BARSize[0], BARSize[1]),
97 secondary(
name() +
".secondary", BARSize[2], BARSize[3]),
98 bmiAddr(0), bmiSize(BARSize[4]),
101 deviceTiming(0), udmaControl(0), udmaTiming(0), ideConfig(0),
102 ioEnabled(false), bmEnabled(false),
103 ioShift(p->io_shift), ctrlOffset(p->ctrl_offset)
107 for (
int i = 0;
i <
params()->disks.size();
i++) {
124 panic(
"IDE controllers support a maximum " 125 "of 4 devices attached!\n");
155 primary.bmiRegs.status.intStatus = 1;
168 panic(
"Unable to find disk based on pointer %#x\n", disk);
171 channel->bmiRegs.command.startStop = 0;
172 channel->bmiRegs.status.active = 0;
173 channel->bmiRegs.status.intStatus = 1;
185 case sizeof(uint8_t):
206 panic(
"Invalid PCI configuration read for size 1 at offset: %#x!\n",
209 DPRINTF(IdeCtrl,
"PCI read offset: %#x size: 1 data: %#x\n", offset,
210 (uint32_t)pkt->
getLE<uint8_t>());
212 case sizeof(uint16_t):
230 panic(
"Invalid PCI configuration read for size 2 offset: %#x!\n",
233 DPRINTF(IdeCtrl,
"PCI read offset: %#x size: 2 data: %#x\n", offset,
234 (uint32_t)pkt->
getLE<uint16_t>());
236 case sizeof(uint32_t):
245 panic(
"No 32bit reads implemented for this device.");
247 DPRINTF(IdeCtrl,
"PCI read offset: %#x size: 4 data: %#x\n", offset,
248 (uint32_t)pkt->
getLE<uint32_t>());
251 panic(
"invalid access size(?) for PCI configspace!\n");
266 case sizeof(uint8_t):
281 panic(
"Invalid PCI configuration write " 282 "for size 1 offset: %#x!\n", offset);
284 DPRINTF(IdeCtrl,
"PCI write offset: %#x size: 1 data: %#x\n",
285 offset, (uint32_t)pkt->
getLE<uint8_t>());
287 case sizeof(uint16_t):
305 panic(
"Invalid PCI configuration write " 306 "for size 2 offset: %#x!\n",
309 DPRINTF(IdeCtrl,
"PCI write offset: %#x size: 2 data: %#x\n",
310 offset, (uint32_t)pkt->
getLE<uint16_t>());
312 case sizeof(uint32_t):
321 panic(
"Write of unimplemented PCI config. register: %x\n", offset);
325 panic(
"invalid access size(?) for PCI configspace!\n");
368 IdeController::Channel::accessCommand(
Addr offset,
371 const Addr SelectOffset = 6;
372 const uint8_t SelectDevBit = 0x10;
374 if (!read &&
offset == SelectOffset)
375 select(*
data & SelectDevBit);
377 if (selected == NULL) {
378 assert(size ==
sizeof(uint8_t));
388 IdeController::Channel::accessControl(
Addr offset,
391 if (selected == NULL) {
392 assert(size ==
sizeof(uint8_t));
402 IdeController::Channel::accessBMI(
Addr offset,
405 assert(
offset + size <=
sizeof(BMIRegs));
407 memcpy(
data, (uint8_t *)&bmiRegs +
offset, size);
412 if (size !=
sizeof(uint8_t))
413 panic(
"Invalid BMIC write size: %x\n", size);
415 BMICommandReg oldVal = bmiRegs.command;
416 BMICommandReg newVal = *
data;
419 if (oldVal.startStop && oldVal.rw != newVal.rw)
420 oldVal.rw = newVal.rw;
422 if (oldVal.startStop != newVal.startStop) {
423 if (selected == NULL)
424 panic(
"DMA start for disk which does not exist\n");
426 if (oldVal.startStop) {
427 DPRINTF(IdeCtrl,
"Stopping DMA transfer\n");
428 bmiRegs.status.active = 0;
430 selected->abortDma();
432 DPRINTF(IdeCtrl,
"Starting DMA transfer\n");
433 bmiRegs.status.active = 1;
435 selected->startDma(
letoh(bmiRegs.bmidtp));
439 bmiRegs.command = newVal;
444 if (size !=
sizeof(uint8_t))
445 panic(
"Invalid BMIS write size: %x\n", size);
447 BMIStatusReg oldVal = bmiRegs.status;
448 BMIStatusReg newVal = *
data;
451 newVal.active = oldVal.active;
454 if ((oldVal.intStatus == 1) && (newVal.intStatus == 1)) {
455 newVal.intStatus = 0;
460 uint8_t tmp = oldVal.intStatus;
461 newVal.intStatus = tmp;
463 if ((oldVal.dmaError == 1) && (newVal.dmaError == 1)) {
466 uint8_t tmp = oldVal.dmaError;
467 newVal.dmaError = tmp;
470 bmiRegs.status = newVal;
474 if (size !=
sizeof(uint32_t))
475 panic(
"Invalid BMIDTP write size: %x\n", size);
476 bmiRegs.bmidtp =
htole(*(uint32_t *)
data & ~0x3);
479 if (size !=
sizeof(uint8_t) && size !=
sizeof(uint16_t) &&
480 size !=
sizeof(uint32_t))
481 panic(
"IDE controller write of invalid write size: %x\n", size);
482 memcpy((uint8_t *)&bmiRegs +
offset,
data, size);
495 DPRINTF(IdeCtrl,
"io not enabled\n");
501 uint8_t *dataPtr = pkt->
getPtr<uint8_t>();
509 primary.accessCommand(addr, size, dataPtr, read);
510 }
else if (addr >=
primary.ctrlAddr &&
514 primary.accessControl(addr, size, dataPtr, read);
518 secondary.accessCommand(addr, size, dataPtr, read);
522 secondary.accessControl(addr, size, dataPtr, read);
527 if (addr <
sizeof(Channel::BMIRegs)) {
528 primary.accessBMI(addr, size, dataPtr, read);
530 addr -=
sizeof(Channel::BMIRegs);
531 secondary.accessBMI(addr, size, dataPtr, read);
534 panic(
"IDE controller access to invalid address: %#x\n", addr);
540 data = pkt->
getLE<uint8_t>();
542 data = pkt->
getLE<uint16_t>();
544 data = pkt->
getLE<uint32_t>();
545 DPRINTF(IdeCtrl,
"%s from offset: %#x size: %#x data: %#x\n",
573 primary.serialize(
"primary", cp);
599 uint8_t command = bmiRegs.command;
601 paramOut(cp,
base +
".bmiRegs.reserved0", bmiRegs.reserved0);
602 uint8_t
status = bmiRegs.status;
604 paramOut(cp,
base +
".bmiRegs.reserved1", bmiRegs.reserved1);
616 primary.unserialize(
"primary", cp);
643 bmiRegs.command = command;
644 paramIn(cp,
base +
".bmiRegs.reserved0", bmiRegs.reserved0);
648 paramIn(cp,
base +
".bmiRegs.reserved1", bmiRegs.reserved1);
649 paramIn(cp,
base +
".bmiRegs.bmidtp", bmiRegs.bmidtp);
655 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.