1 /*****************************************************************************
2 
3   Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4   more contributor license agreements.  See the NOTICE file distributed
5   with this work for additional information regarding copyright ownership.
6   Accellera licenses this file to you under the Apache License, Version 2.0
7   (the "License"); you may not use this file except in compliance with the
8   License.  You may obtain a copy of the License at
9 
10     http://www.apache.org/licenses/LICENSE-2.0
11 
12   Unless required by applicable law or agreed to in writing, software
13   distributed under the License is distributed on an "AS IS" BASIS,
14   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15   implied.  See the License for the specific language governing
16   permissions and limitations under the License.
17 
18  *****************************************************************************/
19 
20 #ifndef __TLM_DMI_H__
21 #define __TLM_DMI_H__
22 
23 #include <systemc>
24 
25 namespace tlm {
26 
27 class tlm_dmi
28 {
29   public:
30 
31   // Enum for indicating the access granted to the initiator.
32   // The initiator uses gp.m_command to indicate it intention (read/write)
33   //  The target is allowed to promote DMI_ACCESS_READ or DMI_ACCESS_WRITE
34   //  requests to dmi_access_read_write.
35 
36   enum dmi_access_e
37   { DMI_ACCESS_NONE       = 0x00                               // no access
38   , DMI_ACCESS_READ       = 0x01                               // read access
39   , DMI_ACCESS_WRITE      = 0x02                               // write access
40   , DMI_ACCESS_READ_WRITE = DMI_ACCESS_READ | DMI_ACCESS_WRITE // read/write access
41   };
42 
tlm_dmi(void)43   tlm_dmi (void)
44   {
45     init();
46   }
47 
init(void)48   void init (void)
49   {
50     m_dmi_ptr           = 0x0;
51     m_dmi_start_address = 0x0;
52     m_dmi_end_address   = (sc_dt::uint64)(-1);
53     m_dmi_access        = DMI_ACCESS_NONE;
54     m_dmi_read_latency  = sc_core::SC_ZERO_TIME;
55     m_dmi_write_latency = sc_core::SC_ZERO_TIME;
56   }
57 
get_dmi_ptr(void)58   unsigned char*    get_dmi_ptr           (void) const {return m_dmi_ptr;}
get_start_address(void)59   sc_dt::uint64     get_start_address     (void) const {return m_dmi_start_address;}
get_end_address(void)60   sc_dt::uint64     get_end_address       (void) const {return m_dmi_end_address;}
get_read_latency(void)61   sc_core::sc_time  get_read_latency      (void) const {return m_dmi_read_latency;}
get_write_latency(void)62   sc_core::sc_time  get_write_latency     (void) const {return m_dmi_write_latency;}
get_granted_access(void)63   dmi_access_e      get_granted_access    (void) const {return m_dmi_access;}
is_none_allowed(void)64   bool              is_none_allowed       (void) const {return m_dmi_access == DMI_ACCESS_NONE;}
is_read_allowed(void)65   bool              is_read_allowed       (void) const {return (m_dmi_access & DMI_ACCESS_READ) == DMI_ACCESS_READ;}
is_write_allowed(void)66   bool              is_write_allowed      (void) const {return (m_dmi_access & DMI_ACCESS_WRITE) == DMI_ACCESS_WRITE;}
is_read_write_allowed(void)67   bool              is_read_write_allowed (void) const {return (m_dmi_access & DMI_ACCESS_READ_WRITE) == DMI_ACCESS_READ_WRITE;}
68 
set_dmi_ptr(unsigned char * p)69   void              set_dmi_ptr           (unsigned char* p)   {m_dmi_ptr = p;}
set_start_address(sc_dt::uint64 addr)70   void              set_start_address     (sc_dt::uint64 addr) {m_dmi_start_address = addr;}
set_end_address(sc_dt::uint64 addr)71   void              set_end_address       (sc_dt::uint64 addr) {m_dmi_end_address = addr;}
set_read_latency(sc_core::sc_time t)72   void              set_read_latency      (sc_core::sc_time t) {m_dmi_read_latency = t;}
set_write_latency(sc_core::sc_time t)73   void              set_write_latency     (sc_core::sc_time t) {m_dmi_write_latency = t;}
set_granted_access(dmi_access_e a)74   void              set_granted_access    (dmi_access_e a)     {m_dmi_access = a;}
allow_none(void)75   void              allow_none            (void)               {m_dmi_access = DMI_ACCESS_NONE;}
allow_read(void)76   void              allow_read            (void)               {m_dmi_access = DMI_ACCESS_READ;}
allow_write(void)77   void              allow_write           (void)               {m_dmi_access = DMI_ACCESS_WRITE;}
allow_read_write(void)78   void              allow_read_write      (void)               {m_dmi_access = DMI_ACCESS_READ_WRITE;}
79 
80   private:
81 
82   // If the forward call is successful, the target returns the dmi_ptr,
83   // which must point to the data element corresponding to the
84   // dmi_start_address. The data is organized as a byte array with the
85   // endianness of the target (endianness member of the tlm_dmi struct).
86 
87   unsigned char*   m_dmi_ptr;
88 
89   // The absolute start and end addresses of the DMI region. If the decoder
90   // logic in the interconnect changes the address field e.g. by masking, the
91   // interconnect is responsible to transform the relative address back to an
92   // absolute address again.
93 
94   sc_dt::uint64    m_dmi_start_address;
95   sc_dt::uint64    m_dmi_end_address;
96 
97   // Granted access
98 
99   dmi_access_e     m_dmi_access;
100 
101   // These members define the latency of read/write transactions. The
102   // initiator must initialize these members to zero before requesting a
103   // dmi pointer, because both the interconnect as well as the target can
104   // add to the total transaction latency.
105   // Depending on the 'type' attribute only one, or both of these attributes
106   // will be valid.
107 
108   sc_core::sc_time m_dmi_read_latency;
109   sc_core::sc_time m_dmi_write_latency;
110 };
111 
112 } // namespace tlm
113 
114 #endif /* TLM_DMI_HEADER */
115