Go to the documentation of this file.
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 device0(NULL), device1(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",
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",
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,
365 int size, uint8_t *
data,
bool read)
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,
385 int size, uint8_t *
data,
bool read)
387 if (selected == NULL) {
388 assert(size ==
sizeof(uint8_t));
398 IdeController::Channel::accessBMI(
Addr offset,
399 int size, uint8_t *
data,
bool read)
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>();
523 if (
addr <
sizeof(Channel::BMIRegs)) {
526 addr -=
sizeof(Channel::BMIRegs);
530 panic(
"IDE controller access to invalid address: %#x\n",
addr);
541 DPRINTF(IdeCtrl,
"%s from offset: %#x size: %#x data: %#x\n",
595 uint8_t command = bmiRegs.command;
598 uint8_t
status = bmiRegs.status;
639 bmiRegs.command = command;
651 IdeControllerParams::create()
void makeAtomicResponse()
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.
#define UNSERIALIZE_SCALAR(scalar)
static const uint16_t timeRegWithDecodeEn
Device model for an Intel PIIX4 IDE controller.
Addr getPageBytes() const
Get the page bytes for the ISA.
virtual Tick writeConfig(PacketPtr pkt)
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.
virtual Tick readConfig(PacketPtr pkt)
Read from the PCI config space data that is stored locally.
uint64_t Tick
Tick count type.
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
void serialize(const ThreadContext &tc, CheckpointOut &cp)
Thread context serialization helpers.
PCIConfig config
The current config space.
void paramOut(CheckpointOut &cp, const string &name, ExtMachInst const &machInst)
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
#define PCI_DEVICE_SPECIFIC
void unserialize(ThreadContext &tc, CheckpointIn &cp)
bool isDiskSelected(IdeDisk *diskPtr)
See if a disk is selected based on its pointer.
uint32_t BARSize[6]
The size of the BARs.
void dispatchAccess(PacketPtr pkt, bool read)
void setDmaComplete(IdeDisk *disk)
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
const Params * params() const
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Tick writeConfig(PacketPtr pkt) override
Write to the PCI config space data that is stored locally.
const std::string & name()
#define SERIALIZE_SCALAR(scalar)
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
Tick readConfig(PacketPtr pkt) override
Read from the PCI config space data that is stored locally.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Addr bmiAddr
Bus master interface (BMI) registers.
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
uint16_t primaryTiming
Registers used in device specific PCI configuration.
void setLE(T v)
Set the value in the data pointer to v as little endian.
T * getPtr()
get a pointer to the data ptr.
std::ostream CheckpointOut
Addr BARAddrs[6]
The current address mapping of the BARs.
bool legacyIO[6]
Whether the BARs are really hardwired legacy IO locations.
PCI device, base implementation is only config space.
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
#define panic(...)
This implements a cprintf based panic() function.
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Generated on Wed Sep 30 2020 14:02:11 for gem5 by doxygen 1.8.17