46#include "debug/IdeCtrl.hh"
50#include "params/IdeController.hh"
66 Named(new_name), ctrl(new_ctrl), primary(new_primary)
80 "IDE controllers support a maximum of 4 devices attached!");
83 for (
int i = 0;
i <
params().disks.size();
i++) {
93 channel.setDevice1(disk);
96 disk->setChannel(&channel, 4 * 1024);
104IdeController::ConfigSpaceRegs::serialize(
CheckpointOut &cp)
const
114IdeController::ConfigSpaceRegs::unserialize(CheckpointIn &cp)
134 bmiRegs.status.intStatus = 0;
135 _pendingInterrupt =
false;
136 ctrl->clearInterrupt(isPrimary());
144 if (!other.pendingInterrupt())
153 if (!other.pendingInterrupt())
168 DPRINTF(IdeCtrl,
"PCI read offset: %#x size: %d data: %#x\n",
offset, size,
186 DPRINTF(IdeCtrl,
"PCI write offset: %#x size: %d data: %#x\n",
199 const Addr SelectOffset = 6;
200 const uint8_t SelectDevBit = 0x10;
203 select(*
data & SelectDevBit);
205 if (selected() == NULL) {
206 assert(size ==
sizeof(uint8_t));
219 if (selected() == NULL) {
220 assert(size ==
sizeof(uint8_t));
235 memcpy(
data, (uint8_t *)&bmiRegs +
offset, size);
240 if (size !=
sizeof(uint8_t))
241 panic(
"Invalid BMIC write size: %x\n", size);
243 BMICommandReg oldVal = bmiRegs.command;
244 BMICommandReg newVal = *
data;
247 if (oldVal.startStop && oldVal.rw != newVal.rw)
248 oldVal.rw = newVal.rw;
250 if (oldVal.startStop != newVal.startStop) {
251 if (selected() == NULL)
252 panic(
"DMA start for disk which does not exist\n");
254 if (oldVal.startStop) {
255 DPRINTF(IdeCtrl,
"Stopping DMA transfer\n");
256 bmiRegs.status.active = 0;
258 selected()->abortDma();
260 DPRINTF(IdeCtrl,
"Starting DMA transfer\n");
261 bmiRegs.status.active = 1;
263 selected()->startDma(
letoh(bmiRegs.bmidtp));
267 bmiRegs.command = newVal;
272 if (size !=
sizeof(uint8_t))
273 panic(
"Invalid BMIS write size: %x\n", size);
275 BMIStatusReg oldVal = bmiRegs.status;
276 BMIStatusReg newVal = *
data;
279 newVal.active = oldVal.active;
282 if ((oldVal.intStatus == 1) && (newVal.intStatus == 1)) {
283 newVal.intStatus = 0;
288 uint8_t tmp = oldVal.intStatus;
289 newVal.intStatus = tmp;
291 if ((oldVal.dmaError == 1) && (newVal.dmaError == 1)) {
294 uint8_t tmp = oldVal.dmaError;
295 newVal.dmaError = tmp;
298 bmiRegs.status = newVal;
302 if (size !=
sizeof(uint32_t))
303 panic(
"Invalid BMIDTP write size: %x\n", size);
304 bmiRegs.bmidtp =
htole(*(uint32_t *)
data & ~0x3);
307 if (size !=
sizeof(uint8_t) && size !=
sizeof(uint16_t) &&
308 size !=
sizeof(uint32_t)) {
309 panic(
"IDE controller write of invalid size: %x\n", size);
311 memcpy((uint8_t *)&bmiRegs +
offset,
data, size);
324 uint8_t *dataPtr = pkt->
getPtr<uint8_t>();
329 "IDE controller access to invalid address: %#x.",
addr);
350 PciCommandRegister command =
letoh(
config.command);
351 if (!
read && !command.busMaster)
371 DPRINTF(IdeCtrl,
"%s from offset: %#x size: %#x data: %#x\n",
381 bmiRegs.command.startStop = 0;
382 bmiRegs.status.active = 0;
383 bmiRegs.status.intStatus = 1;
418 uint8_t command = bmiRegs.command;
420 paramOut(cp,
base +
".bmiRegs.reserved0", bmiRegs.reserved0);
421 uint8_t
status = bmiRegs.status;
423 paramOut(cp,
base +
".bmiRegs.reserved1", bmiRegs.reserved1);
447 bmiRegs.command = command;
448 paramIn(cp,
base +
".bmiRegs.reserved0", bmiRegs.reserved0);
452 paramIn(cp,
base +
".bmiRegs.reserved1", bmiRegs.reserved1);
453 paramIn(cp,
base +
".bmiRegs.bmidtp", bmiRegs.bmidtp);
void accessControl(Addr offset, int size, uint8_t *data, bool read)
void select(bool select_device_1)
void serialize(const std::string &base, std::ostream &os) const
void accessCommand(Addr offset, int size, uint8_t *data, bool read)
void setDevice0(IdeDisk *disk)
void accessBMI(Addr offset, int size, uint8_t *data, bool read)
void unserialize(const std::string &base, CheckpointIn &cp)
struct gem5::IdeController::Channel::BMIRegs bmiRegs
Channel(std::string new_name, IdeController *new_ctrl, bool new_primary)
Device model for an Intel PIIX4 IDE controller.
virtual void postInterrupt(bool is_primary)
virtual void clearInterrupt(bool is_primary)
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
IdeController(const Params &p)
EndBitUnion(BMICommandReg) class ConfigSpaceRegs ConfigSpaceRegs configSpaceRegs
Registers used in device specific PCI configuration.
void serialize(CheckpointOut &cp) const override
Serialize an object.
void dispatchAccess(PacketPtr pkt, bool read)
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Tick readConfig(PacketPtr pkt) override
Read from the PCI config space data that is stored locally.
Tick writeConfig(PacketPtr pkt) override
Write to the PCI config space data that is stored locally.
Interface for things with names.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
T * getPtr()
get a pointer to the data ptr.
uint64_t getUintX(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness and zero-extended to 64 bits.
const T * getConstPtr() const
void makeAtomicResponse()
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
PCI device, base implementation is only config space.
PCIConfig config
The current config space.
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
bool getBAR(Addr addr, int &num, Addr &offs)
Which base address register (if any) maps the given address?
virtual Tick readConfig(PacketPtr pkt)
Read from the PCI config space data that is stored locally.
virtual Tick writeConfig(PacketPtr pkt)
Write to the PCI config space data that is stored locally.
#define panic(...)
This implements a cprintf based panic() function.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
const Params & params() const
Device model for an IDE disk.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
std::ostream CheckpointOut
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
uint64_t Tick
Tick count type.
Declaration of the Packet class.
#define PCI_DEVICE_SPECIFIC
#define UNSERIALIZE_SCALAR(scalar)
#define SERIALIZE_SCALAR(scalar)
Simple PCI IDE controller with bus mastering capability and UDMA modeled after controller in the Inte...
Registers used for bus master interface.
const std::string & name()