quic/qbox
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | List of all members
QemuInitiatorSocket< BUSWIDTH > Class Template Reference

TLM-2.0 initiator socket specialisation for QEMU AddressSpace mapping. More...

#include <initiator.h>

Inheritance diagram for QemuInitiatorSocket< BUSWIDTH >:
Inheritance graph
[legend]
Collaboration diagram for QemuInitiatorSocket< BUSWIDTH >:
Collaboration graph
[legend]

Classes

class  m_mem_obj
 

Public Types

using TlmInitiatorSocket = tlm::tlm_initiator_socket< BUSWIDTH, tlm::tlm_base_protocol_types, 1, sc_core::SC_ZERO_OR_MORE_BOUND >
 
using TlmPayload = tlm::tlm_generic_payload
 
using MemTxResult = qemu::MemoryRegionOps::MemTxResult
 
using MemTxAttrs = qemu::MemoryRegionOps::MemTxAttrs
 
using DmiRegion = QemuInstanceDmiManager::DmiRegion
 
using DmiRegionAlias = QemuInstanceDmiManager::DmiRegionAlias
 
using DmiRegionAliasKey = uint64_t
 

Public Member Functions

 SCP_LOGGER (())
 
MemTxResult qemu_io_read (uint64_t addr, uint64_t *val, unsigned int size, MemTxAttrs attrs)
 
MemTxResult qemu_io_write (uint64_t addr, uint64_t val, unsigned int size, MemTxAttrs attrs)
 
 QemuInitiatorSocket (const char *name, QemuInitiatorIface &initiator, QemuInstance &inst)
 
void init (qemu::Device &dev, const char *prop)
 
void end_of_simulation ()
 
void qemu_map (qemu::MemoryListener &listener, uint64_t addr, uint64_t len)
 
void init_global (qemu::Device &dev)
 
void cancel_all ()
 
virtual tlm::tlm_sync_enum nb_transport_bw (tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase, sc_core::sc_time &t)
 
virtual AliasesIterator remove_alias (AliasesIterator it)
 
virtual void invalidate_direct_mem_ptr (sc_dt::uint64 start_range, sc_dt::uint64 end_range)
 
virtual void reset ()
 

Protected Types

using AliasesIterator = std::map< DmiRegionAliasKey, DmiRegionAlias::Ptr >::iterator
 

Protected Member Functions

void init_payload (TlmPayload &trans, tlm::tlm_command command, uint64_t addr, uint64_t *val, unsigned int size)
 
void add_dmi_mr_alias (DmiRegionAlias::Ptr alias)
 
void del_dmi_mr_alias (const DmiRegionAlias::Ptr alias)
 
void dmi_translate (qemu::IOMMUMemoryRegion::IOMMUTLBEntry *te, std::shared_ptr< qemu::IOMMUMemoryRegion > iommumr, uint64_t base_addr, uint64_t addr, qemu::IOMMUMemoryRegion::IOMMUAccessFlags flags, int idx)
 Use DMI data to set up a qemu IOMMU translate.
 
tlm::tlm_dmi check_dmi_hint_locked (TlmPayload &trans)
 Request a DMI region, ask the QEMU instance DMI manager for a DMI region alias for it and map it on the CPU address space.
 
void check_qemu_mr_hint (TlmPayload &trans)
 
void do_regular_access (TlmPayload &trans)
 
void do_debug_access (TlmPayload &trans)
 
void do_direct_access (TlmPayload &trans)
 
MemTxResult qemu_io_access (tlm::tlm_command command, uint64_t addr, uint64_t *val, unsigned int size, MemTxAttrs attrs)
 

Protected Attributes

QemuInstancem_inst
 
QemuInitiatorIfacem_initiator
 
qemu::Device m_dev
 
gs::runonsysc m_on_sysc
 
int reentrancy = 0
 
bool m_finished = false
 
std::shared_ptr< qemu::AddressSpacem_as
 
std::shared_ptr< qemu::MemoryListenerm_listener
 
std::map< uint64_t, std::shared_ptr< qemu::IOMMUMemoryRegion > > m_mmio_mrs
 
m_mem_objm_r = nullptr
 
std::map< DmiRegionAliasKey, DmiRegionAlias::Ptr > m_dmi_aliases
 

Detailed Description

template<unsigned int BUSWIDTH = DEFAULT_TLM_BUSWIDTH>
class QemuInitiatorSocket< BUSWIDTH >

TLM-2.0 initiator socket specialisation for QEMU AddressSpace mapping.

This class is used to expose a QEMU AddressSpace object as a standard TLM-2.0 initiator socket. It creates a root memory region to map the whole address space, receives I/O accesses to it and forwards them as standard TLM-2.0 transactions.

Member Function Documentation

◆ check_dmi_hint_locked()

template<unsigned int BUSWIDTH = DEFAULT_TLM_BUSWIDTH>
tlm::tlm_dmi QemuInitiatorSocket< BUSWIDTH >::check_dmi_hint_locked ( TlmPayload &  trans)
inlineprotected

Request a DMI region, ask the QEMU instance DMI manager for a DMI region alias for it and map it on the CPU address space.

Parameters
transDMI allowed transation

Ideal, the whole operation could be done on the SystemC thread for simplicity. Unfortunately, QEMU misbehaves if the memory region alias subregion is mapped on the root MR by another thread than the CPU thread. This is related to some internal QEMU code taking different paths depending on the current thread. Basically if the subregion add is not done on the CPU thread, the modification won't be visible immediately by the CPU so the next memory access may go through the I/O path again.

On the other hand we SHOULD do a bunch on the SystemC thread to ensure validity of the DMI region and thus the alias until the point where we effectively map the alias onto the root MR. This is why we first create the alias on the SystemC thread and return it to the CPU thread. Once we're back to the CPU thread, we lock the DMI manager again and check for the alias validity flag. If an invalidation happened in between, this flag will be false and we know we can throw the entire DMI request.

If the alias is valid after we took the lock, we can map it. If an invalidation must occur, it will be done after we release the lock.

Note
We choose to protect all such areas with a mutex, allowing us to process everything on the QEMU thread.
See also
QemuInstanceDmiManager for more information on why we need a global MR per DMI region.
Note
All DMI activity MUST happen from the CPU thread (from an MMIO read/write or 'safe work') For 7.2 this may need to be safe aync work ????????
Needs to be called with iothread locked as it will be doing several updates and we dont want multiple DMI's
Returns
The DMI descriptor for the corresponding DMI region - this is used to help construct memory maps only.

◆ dmi_translate()

template<unsigned int BUSWIDTH = DEFAULT_TLM_BUSWIDTH>
void QemuInitiatorSocket< BUSWIDTH >::dmi_translate ( qemu::IOMMUMemoryRegion::IOMMUTLBEntry te,
std::shared_ptr< qemu::IOMMUMemoryRegion iommumr,
uint64_t  base_addr,
uint64_t  addr,
qemu::IOMMUMemoryRegion::IOMMUAccessFlags  flags,
int  idx 
)
inlineprotected

Use DMI data to set up a qemu IOMMU translate.

Parameters
tepointer to translate block that will be filled in
iommumrmemory region through which translation is being done
base_addrbase address of the iommumr memory region in the address space
addraddress to translate
flagsQEMU read/write request flags
idxindex of translation block.

The documentation for this class was generated from the following file: