From 50a57c0376c02c912a978c4443dd58caebe0f173 Mon Sep 17 00:00:00 2001 From: Stanislaw Czerniawski Date: Wed, 16 May 2018 13:30:24 +0100 Subject: [PATCH] mem: Add StreamID and SubstreamID This patch adds StreamID and SubstreamID to Request. These fields can be used by a SMMU/IOMMU model to pick up the correct translation context for each request and they correspond to an ASID in a device. For this reason they have been merged together with the request asid in a union, so that a cpu will set the asid and a device will set the Stream and Substream ID. Change-Id: Iac2b5a1ba9c6598ee7635c30845dc68ba6787c34 Signed-off-by: Giacomo Travaglini Reviewed-on: https://gem5-review.googlesource.com/12187 Reviewed-by: Anthony Gutierrez Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power --- src/mem/request.hh | 82 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 12 deletions(-) diff --git a/src/mem/request.hh b/src/mem/request.hh index 189d160ab..3df29aa1c 100644 --- a/src/mem/request.hh +++ b/src/mem/request.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013,2017 ARM Limited + * Copyright (c) 2012-2013,2017-2018 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -257,7 +257,7 @@ class Request }; private: - typedef uint8_t PrivateFlagsType; + typedef uint16_t PrivateFlagsType; typedef ::Flags PrivateFlags; enum : PrivateFlagsType { @@ -275,6 +275,9 @@ class Request VALID_CONTEXT_ID = 0x00000020, /** Whether or not the sc result is valid. */ VALID_EXTRA_DATA = 0x00000080, + /** Whether or not the stream ID and substream ID is valid. */ + VALID_STREAM_ID = 0x00000100, + VALID_SUBSTREAM_ID = 0x00000200, /** * These flags are *not* cleared when a Request object is reused * (assigned a new address). @@ -343,8 +346,27 @@ class Request */ uint32_t _taskId; - /** The address space ID. */ - int _asid; + union { + struct { + /** + * The stream ID uniquely identifies a device behind the + * SMMU/IOMMU Each transaction arriving at the SMMU/IOMMU is + * associated with exactly one stream ID. + */ + uint32_t _streamId; + + /** + * The substream ID identifies an "execution context" within a + * device behind an SMMU/IOMMU. It's intended to map 1-to-1 to + * PCIe PASID (Process Address Space ID). The presence of a + * substream ID is optional. + */ + uint32_t _substreamId; + }; + + /** The address space ID. */ + uint64_t _asid; + }; /** The virtual address of the request. */ Addr _vaddr; @@ -431,8 +453,8 @@ class Request privateFlags.set(VALID_PC); } - Request(int asid, Addr vaddr, unsigned size, Flags flags, MasterID mid, - Addr pc, ContextID cid) + Request(uint64_t asid, Addr vaddr, unsigned size, Flags flags, + MasterID mid, Addr pc, ContextID cid) : _paddr(0), _size(0), _masterId(invldMasterId), _time(0), _taskId(ContextSwitchTaskId::Unknown), _asid(0), _vaddr(0), _extraData(0), _contextId(0), _pc(0), @@ -443,8 +465,9 @@ class Request setContext(cid); } - Request(int asid, Addr vaddr, unsigned size, Flags flags, MasterID mid, - Addr pc, ContextID cid, AtomicOpFunctor *atomic_op) + Request(uint64_t asid, Addr vaddr, unsigned size, Flags flags, + MasterID mid, Addr pc, ContextID cid, + AtomicOpFunctor *atomic_op) { setVirt(asid, vaddr, size, flags, mid, pc, atomic_op); setContext(cid); @@ -486,13 +509,28 @@ class Request privateFlags.set(VALID_CONTEXT_ID); } + void + setStreamId(uint32_t sid) + { + _streamId = sid; + privateFlags.set(VALID_STREAM_ID); + } + + void + setSubStreamId(uint32_t ssid) + { + assert(privateFlags.isSet(VALID_STREAM_ID)); + _substreamId = ssid; + privateFlags.set(VALID_SUBSTREAM_ID); + } + /** * Set up a virtual (e.g., CPU) request in a previously * allocated Request object. */ void - setVirt(int asid, Addr vaddr, unsigned size, Flags flags, MasterID mid, - Addr pc, AtomicOpFunctor *amo_op = nullptr) + setVirt(uint64_t asid, Addr vaddr, unsigned size, Flags flags, + MasterID mid, Addr pc, AtomicOpFunctor *amo_op = nullptr) { _asid = asid; _vaddr = vaddr; @@ -673,7 +711,7 @@ class Request } /** Accessor function for asid.*/ - int + uint64_t getAsid() const { assert(privateFlags.isSet(VALID_VADDR)); @@ -682,7 +720,7 @@ class Request /** Accessor function for asid.*/ void - setAsid(int asid) + setAsid(uint64_t asid) { _asid = asid; } @@ -732,6 +770,26 @@ class Request return _contextId; } + uint32_t + streamId() const + { + assert(privateFlags.isSet(VALID_STREAM_ID)); + return _streamId; + } + + bool + hasSubstreamId() const + { + return privateFlags.isSet(VALID_SUBSTREAM_ID); + } + + uint32_t + substreamId() const + { + assert(privateFlags.isSet(VALID_SUBSTREAM_ID)); + return _substreamId; + } + void setPC(Addr pc) { -- 2.30.2