diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc index ae7525c2c..f45bcc080 100644 --- a/dev/ide_ctrl.cc +++ b/dev/ide_ctrl.cc @@ -338,7 +338,10 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) memcpy((void *)&pci_regs[offset], (void *)&data, size); } - if (offset == PCI_COMMAND) { + // Catch the writes to specific PCI registers that have side affects + // (like updating the PIO ranges) + switch (offset) { + case PCI_COMMAND: if (config.data[offset] & IOSE) io_enabled = true; else @@ -348,53 +351,61 @@ IdeController::WriteConfig(int offset, int size, uint32_t data) bm_enabled = true; else bm_enabled = false; + break; - } else if (data != 0xffffffff) { - switch (offset) { - case PCI0_BASE_ADDR0: + case PCI0_BASE_ADDR0: + if (BARAddrs[0] != 0) { pri_cmd_addr = BARAddrs[0]; if (pioInterface) pioInterface->addAddrRange(pri_cmd_addr, pri_cmd_addr + pri_cmd_size - 1); - pri_cmd_addr = pri_cmd_addr & PA_UNCACHED_MASK; - break; + pri_cmd_addr &= PA_UNCACHED_MASK; + } + break; - case PCI0_BASE_ADDR1: + case PCI0_BASE_ADDR1: + if (BARAddrs[1] != 0) { pri_ctrl_addr = BARAddrs[1]; if (pioInterface) pioInterface->addAddrRange(pri_ctrl_addr, pri_ctrl_addr + pri_ctrl_size - 1); - pri_ctrl_addr = pri_ctrl_addr & PA_UNCACHED_MASK; - break; + pri_ctrl_addr &= PA_UNCACHED_MASK; + } + break; - case PCI0_BASE_ADDR2: + case PCI0_BASE_ADDR2: + if (BARAddrs[2] != 0) { sec_cmd_addr = BARAddrs[2]; if (pioInterface) pioInterface->addAddrRange(sec_cmd_addr, sec_cmd_addr + sec_cmd_size - 1); - sec_cmd_addr = sec_cmd_addr & PA_UNCACHED_MASK; - break; + sec_cmd_addr &= PA_UNCACHED_MASK; + } + break; - case PCI0_BASE_ADDR3: + case PCI0_BASE_ADDR3: + if (BARAddrs[3] != 0) { sec_ctrl_addr = BARAddrs[3]; if (pioInterface) pioInterface->addAddrRange(sec_ctrl_addr, sec_ctrl_addr + sec_ctrl_size - 1); - sec_ctrl_addr = sec_ctrl_addr & PA_UNCACHED_MASK; - break; + sec_ctrl_addr &= PA_UNCACHED_MASK; + } + break; - case PCI0_BASE_ADDR4: + case PCI0_BASE_ADDR4: + if (BARAddrs[4] != 0) { bmi_addr = BARAddrs[4]; if (pioInterface) pioInterface->addAddrRange(bmi_addr, bmi_addr + bmi_size - 1); - bmi_addr = bmi_addr & PA_UNCACHED_MASK; - break; + bmi_addr &= PA_UNCACHED_MASK; } + break; } } @@ -589,6 +600,9 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) void IdeController::serialize(std::ostream &os) { + // Serialize the PciDev base class + PciDev::serialize(os); + // Serialize register addresses and sizes SERIALIZE_SCALAR(pri_cmd_addr); SERIALIZE_SCALAR(pri_cmd_size); @@ -615,6 +629,9 @@ IdeController::serialize(std::ostream &os) void IdeController::unserialize(Checkpoint *cp, const std::string §ion) { + // Unserialize the PciDev base class + PciDev::unserialize(cp, section); + // Unserialize register addresses and sizes UNSERIALIZE_SCALAR(pri_cmd_addr); UNSERIALIZE_SCALAR(pri_cmd_size); diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index f3a82781c..812c10df4 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -97,9 +97,9 @@ NSGigE::NSGigE(const std::string &name, IntrControl *i, Tick intr_delay, bool dma_data_free, Tick dma_read_delay, Tick dma_write_delay, Tick dma_read_factor, Tick dma_write_factor, PciConfigAll *cf, PciConfigData *cd, Tsunami *t, uint32_t bus, uint32_t dev, - uint32_t func, bool rx_filter, const int eaddr[6], Addr addr) + uint32_t func, bool rx_filter, const int eaddr[6]) : PciDev(name, mmu, cf, cd, bus, dev, func), tsunami(t), - addr(addr), txPacketBufPtr(NULL), rxPacketBufPtr(NULL), + txPacketBufPtr(NULL), rxPacketBufPtr(NULL), txXferLen(0), rxXferLen(0), txPktXmitted(0), txState(txIdle), CTDD(false), txFifoCnt(0), txFifoAvail(MAX_TX_FIFO_SIZE), txHalt(false), txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle), @@ -115,13 +115,12 @@ NSGigE::NSGigE(const std::string &name, IntrControl *i, Tick intr_delay, physmem(pmem), intctrl(i), intrTick(0), cpuPendingIntr(false), intrEvent(0), interface(0), pioLatency(pio_latency) { - mmu->add_child(this, Range(addr, addr + size)); tsunami->ethernet = this; if (header_bus) { pioInterface = newPioInterface(name, hier, header_bus, this, &NSGigE::cacheAccess); - pioInterface->addAddrRange(addr, addr + size - 1); + if (payload_bus) dmaInterface = new DMAInterface(name + ".dma", header_bus, payload_bus, 1); @@ -131,7 +130,7 @@ NSGigE::NSGigE(const std::string &name, IntrControl *i, Tick intr_delay, } else if (payload_bus) { pioInterface = newPioInterface(name, hier, payload_bus, this, &NSGigE::cacheAccess); - pioInterface->addAddrRange(addr, addr + size - 1); + dmaInterface = new DMAInterface(name + ".dma", payload_bus, payload_bus, 1); @@ -226,9 +225,8 @@ NSGigE::ReadConfig(int offset, int size, uint8_t *data) { if (offset < PCI_DEVICE_SPECIFIC) PciDev::ReadConfig(offset, size, data); - else { - panic("need to do this\n"); - } + else + panic("Device specific PCI config space not implemented!\n"); } /** @@ -240,7 +238,21 @@ NSGigE::WriteConfig(int offset, int size, uint32_t data) if (offset < PCI_DEVICE_SPECIFIC) PciDev::WriteConfig(offset, size, data); else - panic("Need to do that\n"); + panic("Device specific PCI config space not implemented!\n"); + + // Need to catch writes to BARs to update the PIO interface + switch (offset) { + case PCI0_BASE_ADDR0: + if (BARAddrs[0] != 0) { + addr = BARAddrs[0]; + + if (pioInterface) + pioInterface->addAddrRange(addr, addr + size - 1); + + addr &= PA_UNCACHED_MASK; + } + break; + } } /** @@ -2002,6 +2014,9 @@ NSGigE::checksumCalc(uint16_t *pseudo, uint16_t *buf, uint32_t len) void NSGigE::serialize(ostream &os) { + // Serialize the PciDev base class + PciDev::serialize(os); + /* * Finalize any DMA events now. */ @@ -2153,6 +2168,9 @@ NSGigE::serialize(ostream &os) void NSGigE::unserialize(Checkpoint *cp, const std::string §ion) { + // Unserialize the PciDev base class + PciDev::unserialize(cp, section); + UNSERIALIZE_SCALAR(regs.command); UNSERIALIZE_SCALAR(regs.config); UNSERIALIZE_SCALAR(regs.mear); @@ -2346,7 +2364,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE) Param intr_delay; SimObjectParam mmu; SimObjectParam physmem; - Param addr; Param rx_filter; Param hardware_address; SimObjectParam header_bus; @@ -2376,7 +2393,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE) INIT_PARAM_DFLT(intr_delay, "Interrupt Delay in microseconds", 0), INIT_PARAM(mmu, "Memory Controller"), INIT_PARAM(physmem, "Physical Memory"), - INIT_PARAM(addr, "Device Address"), INIT_PARAM_DFLT(rx_filter, "Enable Receive Filter", true), INIT_PARAM_DFLT(hardware_address, "Ethernet Hardware Address", "00:99:00:00:00:01"), @@ -2407,12 +2423,11 @@ CREATE_SIM_OBJECT(NSGigE) &eaddr[0], &eaddr[1], &eaddr[2], &eaddr[3], &eaddr[4], &eaddr[5]); return new NSGigE(getInstanceName(), intr_ctrl, intr_delay, - physmem, tx_delay, rx_delay, mmu, hier, header_bus, - payload_bus, pio_latency, dma_desc_free, dma_data_free, - dma_read_delay, dma_write_delay, dma_read_factor, - dma_write_factor, configspace, configdata, - tsunami, pci_bus, pci_dev, pci_func, rx_filter, eaddr, - addr); + physmem, tx_delay, rx_delay, mmu, hier, header_bus, + payload_bus, pio_latency, dma_desc_free, dma_data_free, + dma_read_delay, dma_write_delay, dma_read_factor, + dma_write_factor, configspace, configdata, + tsunami, pci_bus, pci_dev, pci_func, rx_filter, eaddr); } REGISTER_SIM_OBJECT("NSGigE", NSGigE) diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index d2f234bca..9466e8930 100644 --- a/dev/ns_gige.hh +++ b/dev/ns_gige.hh @@ -345,7 +345,7 @@ class NSGigE : public PciDev bool dma_data_free, Tick dma_read_delay, Tick dma_write_delay, Tick dma_read_factor, Tick dma_write_factor, PciConfigAll *cf, PciConfigData *cd, Tsunami *t, uint32_t bus, uint32_t dev, - uint32_t func, bool rx_filter, const int eaddr[6], Addr addr); + uint32_t func, bool rx_filter, const int eaddr[6]); ~NSGigE(); virtual void WriteConfig(int offset, int size, uint32_t data); diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc index 949124c8c..65bee19ad 100644 --- a/dev/pciconfigall.cc +++ b/dev/pciconfigall.cc @@ -148,13 +148,21 @@ PciConfigAll::write(MemReqPtr &req, const uint8_t *data) void PciConfigAll::serialize(std::ostream &os) { - // code should be written + /* + * There is no state associated with this object that requires + * serialization. The only real state are the device pointers + * which are all setup by the constructor of the PciDev class + */ } void PciConfigAll::unserialize(Checkpoint *cp, const std::string §ion) { - //code should be written + /* + * There is no state associated with this object that requires + * serialization. The only real state are the device pointers + * which are all setup by the constructor of the PciDev class + */ } #ifndef DOXYGEN_SHOULD_SKIP_THIS diff --git a/dev/pcidev.cc b/dev/pcidev.cc index 191233348..01f336ff8 100644 --- a/dev/pcidev.cc +++ b/dev/pcidev.cc @@ -256,13 +256,26 @@ PciDev::WriteConfig(int offset, int size, uint32_t data) void PciDev::serialize(ostream &os) { + SERIALIZE_ARRAY(BARSize, 6); + SERIALIZE_ARRAY(BARAddrs, 6); SERIALIZE_ARRAY(config.data, 64); } void PciDev::unserialize(Checkpoint *cp, const std::string §ion) { + UNSERIALIZE_ARRAY(BARSize, 6); + UNSERIALIZE_ARRAY(BARAddrs, 6); UNSERIALIZE_ARRAY(config.data, 64); + + // Add the MMU mappings for the BARs + for (int i=0; i < 6; i++) { + if (BARAddrs[i] != 0) + mmu->add_child((FunctionalMemory *)this, + Range(BARAddrs[i], + BARAddrs[i] + + BARSize[i] - 1)); + } } #ifndef DOXYGEN_SHOULD_SKIP_THIS