-----------------------------------------------------------
This is an automatically generated e-mail. To reply, visit:
http://reviews.gem5.org/r/1301/
-----------------------------------------------------------

Review request for Default.


Description
-------

Changeset 9104:6e7b0ddcc5b5
---------------------------
Port: Separate the port and the interface protocol

This patch splits the port and its interface into a very basic stack.
The port itself dictates how things are connected and governs the
physical topology of the system. On top of this, the port interfaces
(implemented by handlers) are responsible for the transport functions,
e.g. send/recv for functional, atomic and timing, and also for
functions like querying of address ranges and block size.

Why are we doing this? This patch enables us to gradually introduce
the 4-phase ports as an alternative interface to the classic send/recv
interface. In theory, it would also enable Ruby to rely on the normal
ports for structurally assembling the system, and then use a custom
Ruby interface. If we want different protocols at different locations
in the system it is thus possible.

So what does this patch actually change? Brace yourself, as it
is quite extensive. First and foremost each port now has two template
parameters, one for the exposed interface of the port itself (i.e. the
sending and receiving functionality) and one for the interface
required from the peer port (the receiving end of the port's own
sending interface). For example, for a conventional master port, this
would now be IfaceMasterPort<MasterInterface, SlaveInterface>, where
the parameters can be left out as they are the default values. This
corresponds to a port on which we can use the MasterInterface, and
bind to a peer port with a SlaveInterface.

For convenience, the name MasterPort and SlavePort are type defined to
be a master and slave with the classic MasterInterface and
SlaveInterface, as exemplified above. This is sufficient in most
typical cases, where no additional functionality is required from the
sending interface. In the case of e.g. a DMA port, additional sending
functions like dmaAction require the port to expose a DMA-specific
interface, which extends the MasterInterface. This is now implemented
in a DmaHandler (the name could be discussed with options including
Handler, Interface, Iface, IF), which inherits from the
MasterInterface, and besides implementing e.g. recvTimingResp also
adds the desired DMA functions. By declaring a
IfaceMasterPort<DmaHandler> we get a master port with the desired DMA
interface (which still binds to a SlaveInterface).

The implementation of the interfaces is, as already mentioned, done in
a handler. Where there previously used to be e.g. a WalkerPort, there
is now a WalkerHandler and a MasterPort that uses the handler. We
could consider naming the Handlers Interface or Iface instead as
already mentioned. The name handler was chosen as they actually
implement the interface functions.

To enable any arbitrary specialisation of the interfaces, the
protcol-agnostic base ports have bind functions that call a virtual
bind function on the interface base class. It is then up to the
specific implementation to overload this function and verify the
compatibility. Thus, the ports pass the binding responsibility to the
interface, and the master interface tries to cast the slave interface
to the right class.

The separation of the port and the interface is done in a similar
manner to TLM-2.0, with the interface of the port being accessible by
overloading the pointer operator. Although this might seem like C++
abuse, it makes for a far-less verbose way of accessing the interface
compared to e.g. a member function. As a result of this change, where
it used to say port.send, it will now say port->send, and similarly a
port->send becomes (*port)->send.

As can be seen e.g. in the CPU, the separation of the port and the
interface also enable the BaseCPU to declare the instPort and
dataPort, and then leave it up to the specific CPU model to provide
the interface handlers. Thus, the atomic, timing, inorder and O3 CPU
can all implement their own independent handlers, and merely pass them
on to the BaseCPU. A similar approach is used in the cache where a
handler is created in the subclass and passed to the base cache
parent that holds the ports themselves.

An additional benefit of this separation is that the module itself can
implement the interface. This is done in the SimpleMemory, where the
port handler was a trivial class that only added a level of
indirection (port.recvAtomic calls memory.recvAtomic). Instead of
having this handler, the port is now assigned the SimpleMemory itself
as the handler, and the SimpleMemory is both a MemObject and a
SlaveInterface.


Diffs
-----

  src/arch/arm/table_walker.hh 7dee77da691b 
  src/arch/arm/table_walker.cc 7dee77da691b 
  src/arch/x86/interrupts.hh 7dee77da691b 
  src/arch/x86/interrupts.cc 7dee77da691b 
  src/arch/x86/pagetable_walker.hh 7dee77da691b 
  src/arch/x86/pagetable_walker.cc 7dee77da691b 
  src/cpu/base.hh 7dee77da691b 
  src/cpu/base.cc 7dee77da691b 
  src/cpu/base_dyn_inst.hh 7dee77da691b 
  src/cpu/checker/cpu.hh 7dee77da691b 
  src/cpu/checker/cpu.cc 7dee77da691b 
  src/cpu/checker/cpu_impl.hh 7dee77da691b 
  src/cpu/inorder/cpu.hh 7dee77da691b 
  src/cpu/inorder/cpu.cc 7dee77da691b 
  src/cpu/inorder/resources/cache_unit.cc 7dee77da691b 
  src/cpu/o3/cpu.hh 7dee77da691b 
  src/cpu/o3/cpu.cc 7dee77da691b 
  src/cpu/o3/fetch_impl.hh 7dee77da691b 
  src/cpu/o3/lsq_impl.hh 7dee77da691b 
  src/cpu/o3/lsq_unit.hh 7dee77da691b 
  src/cpu/o3/lsq_unit_impl.hh 7dee77da691b 
  src/cpu/simple/atomic.hh 7dee77da691b 
  src/cpu/simple/atomic.cc 7dee77da691b 
  src/cpu/simple/base.hh 7dee77da691b 
  src/cpu/simple/base.cc 7dee77da691b 
  src/cpu/simple/timing.hh 7dee77da691b 
  src/cpu/simple/timing.cc 7dee77da691b 
  src/cpu/testers/directedtest/InvalidateGenerator.cc 7dee77da691b 
  src/cpu/testers/directedtest/RubyDirectedTester.hh 7dee77da691b 
  src/cpu/testers/directedtest/RubyDirectedTester.cc 7dee77da691b 
  src/cpu/testers/directedtest/SeriesRequestGenerator.cc 7dee77da691b 
  src/cpu/testers/memtest/memtest.hh 7dee77da691b 
  src/cpu/testers/memtest/memtest.cc 7dee77da691b 
  src/cpu/testers/networktest/networktest.hh 7dee77da691b 
  src/cpu/testers/networktest/networktest.cc 7dee77da691b 
  src/cpu/testers/rubytest/Check.cc 7dee77da691b 
  src/cpu/testers/rubytest/RubyTester.hh 7dee77da691b 
  src/cpu/testers/rubytest/RubyTester.cc 7dee77da691b 
  src/dev/arm/pl111.cc 7dee77da691b 
  src/dev/copy_engine.hh 7dee77da691b 
  src/dev/copy_engine.cc 7dee77da691b 
  src/dev/dma_device.hh 7dee77da691b 
  src/dev/dma_device.cc 7dee77da691b 
  src/dev/i8254xGBe.cc 7dee77da691b 
  src/dev/io_device.hh 7dee77da691b 
  src/dev/io_device.cc 7dee77da691b 
  src/dev/pcidev.hh 7dee77da691b 
  src/dev/pcidev.cc 7dee77da691b 
  src/dev/sinic.cc 7dee77da691b 
  src/dev/x86/i82094aa.cc 7dee77da691b 
  src/dev/x86/intdev.hh 7dee77da691b 
  src/dev/x86/intdev.cc 7dee77da691b 
  src/kern/tru64/tru64_events.cc 7dee77da691b 
  src/mem/SConscript 7dee77da691b 
  src/mem/bridge.hh 7dee77da691b 
  src/mem/bridge.cc 7dee77da691b 
  src/mem/bus.cc 7dee77da691b 
  src/mem/cache/base.hh 7dee77da691b 
  src/mem/cache/base.cc 7dee77da691b 
  src/mem/cache/cache.hh 7dee77da691b 
  src/mem/cache/cache_impl.hh 7dee77da691b 
  src/mem/coherent_bus.hh 7dee77da691b 
  src/mem/coherent_bus.cc 7dee77da691b 
  src/mem/comm_monitor.hh 7dee77da691b 
  src/mem/comm_monitor.cc 7dee77da691b 
  src/mem/fs_translating_port_proxy.hh 7dee77da691b 
  src/mem/fs_translating_port_proxy.cc 7dee77da691b 
  src/mem/mport.hh 7dee77da691b 
  src/mem/mport.cc 7dee77da691b 
  src/mem/noncoherent_bus.hh 7dee77da691b 
  src/mem/noncoherent_bus.cc 7dee77da691b 
  src/mem/packet_queue.hh 7dee77da691b 
  src/mem/packet_queue.cc 7dee77da691b 
  src/mem/port.hh 7dee77da691b 
  src/mem/port.cc 7dee77da691b 
  src/mem/port_interface.hh PRE-CREATION 
  src/mem/port_interface.cc PRE-CREATION 
  src/mem/port_proxy.hh 7dee77da691b 
  src/mem/port_proxy.cc 7dee77da691b 
  src/mem/qport.hh 7dee77da691b 
  src/mem/ruby/system/RubyPort.hh 7dee77da691b 
  src/mem/ruby/system/RubyPort.cc 7dee77da691b 
  src/mem/se_translating_port_proxy.hh 7dee77da691b 
  src/mem/se_translating_port_proxy.cc 7dee77da691b 
  src/mem/simple_mem.hh 7dee77da691b 
  src/mem/simple_mem.cc 7dee77da691b 
  src/mem/tport.hh 7dee77da691b 
  src/mem/tport.cc 7dee77da691b 
  src/sim/system.hh 7dee77da691b 
  src/sim/system.cc 7dee77da691b 

Diff: http://reviews.gem5.org/r/1301/diff/


Testing
-------

util/regress all passing (disregarding t1000 and eio)


Thanks,

Andreas Hansson

_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to