* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Nathan Binkert
*/
#include <deque>
#include <string>
#include "base/inet.hh"
-#include "cpu/exec_context.hh"
+#include "cpu/thread_context.hh"
#include "cpu/intr_control.hh"
#include "dev/etherlink.hh"
#include "dev/sinic.hh"
-#include "dev/pciconfigall.hh"
#include "mem/packet.hh"
#include "sim/builder.hh"
#include "sim/debug.hh"
Device::read(Packet *pkt)
{
assert(config.command & PCI_CMD_MSE);
- assert(pkt->addr >= BARAddrs[0] && pkt->size < BARSize[0]);
+ assert(pkt->getAddr() >= BARAddrs[0] && pkt->getSize() < BARSize[0]);
int cpu = pkt->req->getCpuNum();
- Addr daddr = pkt->addr - BARAddrs[0];
+ Addr daddr = pkt->getAddr() - BARAddrs[0];
Addr index = daddr >> Regs::VirtualShift;
Addr raddr = daddr & Regs::VirtualMask;
- pkt->time += pioDelay;
pkt->allocate();
if (!regValid(raddr))
panic("invalid register: cpu=%d vnic=%d da=%#x pa=%#x size=%d",
- cpu, index, daddr, pkt->addr, pkt->size);
+ cpu, index, daddr, pkt->getAddr(), pkt->getSize());
const Regs::Info &info = regInfo(raddr);
if (!info.read)
panic("read %s (write only): "
"cpu=%d vnic=%d da=%#x pa=%#x size=%d",
- info.name, cpu, index, daddr, pkt->addr, pkt->size);
+ info.name, cpu, index, daddr, pkt->getAddr(), pkt->getSize());
panic("read %s (invalid size): "
"cpu=%d vnic=%d da=%#x pa=%#x size=%d",
- info.name, cpu, index, daddr, pkt->addr, pkt->size);
+ info.name, cpu, index, daddr, pkt->getAddr(), pkt->getSize());
prepareRead(cpu, index);
uint64_t value = 0;
- if (pkt->size == 4) {
+ if (pkt->getSize() == 4) {
uint32_t reg = regData32(raddr);
pkt->set(reg);
value = reg;
}
- if (pkt->size == 8) {
+ if (pkt->getSize() == 8) {
uint64_t reg = regData64(raddr);
pkt->set(reg);
value = reg;
DPRINTF(EthernetPIO,
"read %s: cpu=%d vnic=%d da=%#x pa=%#x size=%d val=%#x\n",
- info.name, cpu, index, daddr, pkt->addr, pkt->size, value);
+ info.name, cpu, index, daddr, pkt->getAddr(), pkt->getSize(), value);
// reading the interrupt status register has the side effect of
// clearing it
Device::write(Packet *pkt)
{
assert(config.command & PCI_CMD_MSE);
- assert(pkt->addr >= BARAddrs[0] && pkt->size < BARSize[0]);
+ assert(pkt->getAddr() >= BARAddrs[0] && pkt->getSize() < BARSize[0]);
int cpu = pkt->req->getCpuNum();
- Addr daddr = pkt->addr - BARAddrs[0];
+ Addr daddr = pkt->getAddr() - BARAddrs[0];
Addr index = daddr >> Regs::VirtualShift;
Addr raddr = daddr & Regs::VirtualMask;
- pkt->time += pioDelay;
-
if (!regValid(raddr))
panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d",
- cpu, daddr, pkt->addr, pkt->size);
+ cpu, daddr, pkt->getAddr(), pkt->getSize());
const Regs::Info &info = regInfo(raddr);
if (!info.write)
panic("write %s (read only): "
"cpu=%d vnic=%d da=%#x pa=%#x size=%d",
- info.name, cpu, index, daddr, pkt->addr, pkt->size);
+ info.name, cpu, index, daddr, pkt->getAddr(), pkt->getSize());
- if (pkt->size != info.size)
+ if (pkt->getSize() != info.size)
panic("write %s (invalid size): "
"cpu=%d vnic=%d da=%#x pa=%#x size=%d",
- info.name, cpu, index, daddr, pkt->addr, pkt->size);
+ info.name, cpu, index, daddr, pkt->getAddr(), pkt->getSize());
VirtualReg &vnic = virtualRegs[index];
DPRINTF(EthernetPIO,
"write %s vnic %d: cpu=%d val=%#x da=%#x pa=%#x size=%d\n",
info.name, index, cpu, info.size == 4 ? pkt->get<uint32_t>() :
- pkt->get<uint64_t>(), daddr, pkt->addr, pkt->size);
+ pkt->get<uint64_t>(), daddr, pkt->getAddr(), pkt->getSize());
prepareWrite(cpu, index);
break;
case rxBeginCopy:
- if (dmaPending())
+ if (dmaPending() || getState() != Running)
goto exit;
rxDmaAddr = params()->platform->pciToDma(
break;
case txBeginCopy:
- if (dmaPending())
+ if (dmaPending() || getState() != Running)
goto exit;
txDmaAddr = params()->platform->pciToDma(
return true;
}
+void
+Device::resume()
+{
+ SimObject::resume();
+
+ // During drain we could have left the state machines in a waiting state and
+ // they wouldn't get out until some other event occured to kick them.
+ // This way they'll get out immediately
+ txKick();
+ rxKick();
+}
+
//=====================================================================
//
//
}
+/* namespace Sinic */ }
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(Interface)
+BEGIN_DECLARE_SIM_OBJECT_PARAMS_WNS(Sinic, SinicInterface)
SimObjectParam<EtherInt *> peer;
- SimObjectParam<Device *> device;
-
-END_DECLARE_SIM_OBJECT_PARAMS(Interface)
+ SimObjectParam<Sinic::Device *> device;
+END_DECLARE_SIM_OBJECT_PARAMS_WNS(Sinic, SinicInterface)
-BEGIN_INIT_SIM_OBJECT_PARAMS(Interface)
+BEGIN_INIT_SIM_OBJECT_PARAMS_WNS(Sinic, SinicInterface)
INIT_PARAM_DFLT(peer, "peer interface", NULL),
INIT_PARAM(device, "Ethernet device of this interface")
-END_INIT_SIM_OBJECT_PARAMS(Interface)
+END_INIT_SIM_OBJECT_PARAMS_WNS(Sinic, SinicInterface)
-CREATE_SIM_OBJECT(Interface)
+CREATE_SIM_OBJECT_WNS(Sinic, SinicInterface)
{
- Interface *dev_int = new Interface(getInstanceName(), device);
+ Sinic::Interface *dev_int = new Sinic::Interface(getInstanceName(), device);
EtherInt *p = (EtherInt *)peer;
if (p) {
return dev_int;
}
-REGISTER_SIM_OBJECT("SinicInt", Interface)
+REGISTER_SIM_OBJECT_WNS(Sinic, "SinicInt", SinicInterface)
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device)
+BEGIN_DECLARE_SIM_OBJECT_PARAMS_WNS(Sinic, SinicDevice)
SimObjectParam<System *> system;
SimObjectParam<Platform *> platform;
- SimObjectParam<PciConfigAll *> configspace;
SimObjectParam<PciConfigData *> configdata;
Param<uint32_t> pci_bus;
Param<uint32_t> pci_dev;
Param<uint32_t> pci_func;
Param<Tick> pio_latency;
+ Param<Tick> config_latency;
Param<Tick> intr_delay;
Param<Tick> clock;
Param<bool> delay_copy;
Param<bool> virtual_addr;
-END_DECLARE_SIM_OBJECT_PARAMS(Device)
+END_DECLARE_SIM_OBJECT_PARAMS_WNS(Sinic, SinicDevice)
-BEGIN_INIT_SIM_OBJECT_PARAMS(Device)
+BEGIN_INIT_SIM_OBJECT_PARAMS_WNS(Sinic, SinicDevice)
INIT_PARAM(system, "System pointer"),
INIT_PARAM(platform, "Platform pointer"),
- INIT_PARAM(configspace, "PCI Configspace"),
INIT_PARAM(configdata, "PCI Config data"),
INIT_PARAM(pci_bus, "PCI bus ID"),
INIT_PARAM(pci_dev, "PCI device number"),
INIT_PARAM(pci_func, "PCI function code"),
INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
+ INIT_PARAM(config_latency, "Number of cycles for a config read or write"),
INIT_PARAM(intr_delay, "Interrupt Delay"),
INIT_PARAM(clock, "State machine cycle time"),
INIT_PARAM(delay_copy, ""),
INIT_PARAM(virtual_addr, "")
-END_INIT_SIM_OBJECT_PARAMS(Device)
+END_INIT_SIM_OBJECT_PARAMS_WNS(Sinic, SinicDevice)
-CREATE_SIM_OBJECT(Device)
+CREATE_SIM_OBJECT_WNS(Sinic, SinicDevice)
{
- Device::Params *params = new Device::Params;
+ Sinic::Sinic::Device::Params *params = new Device::Params;
params->name = getInstanceName();
params->platform = platform;
params->system = system;
- params->configSpace = configspace;
params->configData = configdata;
params->busNum = pci_bus;
params->deviceNum = pci_dev;
params->functionNum = pci_func;
params->pio_delay = pio_latency;
+ params->config_delay = config_latency;
params->intr_delay = intr_delay;
params->clock = clock;
params->delay_copy = delay_copy;
params->virtual_addr = virtual_addr;
- return new Device(params);
+ return new Sinic::Device(params);
}
-REGISTER_SIM_OBJECT("Sinic", Device)
+REGISTER_SIM_OBJECT_WNS(Sinic, "Sinic", SinicDevice)
-/* namespace Sinic */ }