57d56
< intEvent([this]{ generateInterrupt(); }, name()),
60c59
< ps2->hostRegDataAvailable([this]() { this->updateIntStatus(); });
---
> ps2->hostRegDataAvailable([this]() { this->updateRxInt(); });
85a85
> updateRxInt();
87d86
< updateIntStatus();
110,124c109
< switch(pkt->getSize()) {
< case 1:
< pkt->set<uint8_t>(data);
< break;
< case 2:
< pkt->set<uint16_t>(data);
< break;
< case 4:
< pkt->set<uint32_t>(data);
< break;
< default:
< panic("KMI read size too big?\n");
< break;
< }
<
---
> pkt->setUintX(data, LittleEndianByteOrder);
135a121
> const uint32_t data = pkt->getUintX(LittleEndianByteOrder);
137c123,126
< assert(pkt->getSize() == sizeof(uint8_t));
---
> panic_if(pkt->getSize() != 1,
> "PL050: Unexpected write size "
> "(offset: %#x, data: %#x, size: %u)\n",
> daddr, data, pkt->getSize());
139d127
<
142,144c130,133
< DPRINTF(Pl050, "Write Commmand: %#x\n", (uint32_t)pkt->get<uint8_t>());
< control = pkt->get<uint8_t>();
< updateIntStatus();
---
> DPRINTF(Pl050, "Write Commmand: %#x\n", data);
> // Use the update interrupts helper to make sure any interrupt
> // mask changes are handled correctly.
> setControl((uint8_t)data);
148,150c137,142
< DPRINTF(Pl050, "Write Data: %#x\n", (uint32_t)pkt->get<uint8_t>());
< ps2->hostWrite(pkt->get<uint8_t>());
< updateIntStatus();
---
> DPRINTF(Pl050, "Write Data: %#x\n", data);
> // Clear the TX interrupt before writing new data.
> setTxInt(false);
> ps2->hostWrite((uint8_t)data);
> // Data is written in 0 time, so raise the TX interrupt again.
> setTxInt(true);
154c146
< clkdiv = pkt->get<uint8_t>();
---
> clkdiv = (uint8_t)data;
158c150
< warn("Tried to write PL050 at offset %#x that doesn't exist\n", daddr);
---
> warn("PL050: Unhandled write of %#x to offset %#x\n", data, daddr);
165a158,161
> void
> Pl050::setTxInt(bool value)
> {
> InterruptReg ints = rawInterrupts;
166a163,167
> ints.tx = value ? 1 : 0;
>
> setInterrupts(ints);
> }
>
168c169
< Pl050::updateIntStatus()
---
> Pl050::updateRxInt()
170c171
< const bool old_interrupt(getInterrupt());
---
> InterruptReg ints = rawInterrupts;
172c173
< rawInterrupts.rx = ps2->hostDataAvailable() ? 1 : 0;
---
> ints.rx = ps2->hostDataAvailable() ? 1 : 0;
174,177c175,193
< if ((!old_interrupt && getInterrupt()) && !intEvent.scheduled()) {
< schedule(intEvent, curTick() + intDelay);
< } else if (old_interrupt && !(getInterrupt())) {
< gic->clearInt(intNum);
---
> setInterrupts(ints);
> }
>
> void
> Pl050::updateIntCtrl(InterruptReg ints, ControlReg ctrl)
> {
> const bool old_pending(getInterrupt());
> control = ctrl;
> rawInterrupts = ints;
> const bool new_pending(getInterrupt());
>
> if (!old_pending && new_pending) {
> DPRINTF(Pl050, "Generate interrupt: rawInt=%#x ctrl=%#x int=%#x\n",
> rawInterrupts, control, getInterrupt());
> gic->sendInt(intNum);
> } else if (old_pending && !new_pending) {
> DPRINTF(Pl050, "Clear interrupt: rawInt=%#x ctrl=%#x int=%#x\n",
> rawInterrupts, control, getInterrupt());
> gic->clearInt(intNum);
193,204d208
< Pl050::generateInterrupt()
< {
< DPRINTF(Pl050, "Generate Interrupt: rawInt=%#x ctrl=%#x int=%#x\n",
< rawInterrupts, control, getInterrupt());
<
< if (getInterrupt()) {
< gic->sendInt(intNum);
< DPRINTF(Pl050, " -- Generated\n");
< }
< }
<
< void
207,211c211,212
< uint8_t ctrlreg = control;
< SERIALIZE_SCALAR(ctrlreg);
<
< uint8_t stsreg = status;
< SERIALIZE_SCALAR(stsreg);
---
> paramOut(cp, "ctrlreg", control);
> paramOut(cp, "stsreg", status);
213,215c214
<
< uint8_t raw_ints = rawInterrupts;
< SERIALIZE_SCALAR(raw_ints);
---
> paramOut(cp, "raw_ints", rawInterrupts);
221,228c220,221
< uint8_t ctrlreg;
< UNSERIALIZE_SCALAR(ctrlreg);
< control = ctrlreg;
<
< uint8_t stsreg;
< UNSERIALIZE_SCALAR(stsreg);
< status = stsreg;
<
---
> paramIn(cp, "ctrlreg", control);
> paramIn(cp, "stsreg", status);
230,233c223
<
< uint8_t raw_ints;
< UNSERIALIZE_SCALAR(raw_ints);
< rawInterrupts = raw_ints;
---
> paramIn(cp, "raw_ints", rawInterrupts);