1 /** @file
2   ArmLibPrivate.h
3 
4   Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
5   Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
6 
7   SPDX-License-Identifier: BSD-2-Clause-Patent
8 
9 **/
10 
11 #ifndef __ARM_LIB_PRIVATE_H__
12 #define __ARM_LIB_PRIVATE_H__
13 
14 #define CACHE_SIZE_4_KB             (3UL)
15 #define CACHE_SIZE_8_KB             (4UL)
16 #define CACHE_SIZE_16_KB            (5UL)
17 #define CACHE_SIZE_32_KB            (6UL)
18 #define CACHE_SIZE_64_KB            (7UL)
19 #define CACHE_SIZE_128_KB           (8UL)
20 
21 #define CACHE_ASSOCIATIVITY_DIRECT  (0UL)
22 #define CACHE_ASSOCIATIVITY_4_WAY   (2UL)
23 #define CACHE_ASSOCIATIVITY_8_WAY   (3UL)
24 
25 #define CACHE_PRESENT               (0UL)
26 #define CACHE_NOT_PRESENT           (1UL)
27 
28 #define CACHE_LINE_LENGTH_32_BYTES  (2UL)
29 
30 #define SIZE_FIELD_TO_CACHE_SIZE(x)           (((x) >> 6) & 0x0F)
31 #define SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(x)  (((x) >> 3) & 0x07)
32 #define SIZE_FIELD_TO_CACHE_PRESENCE(x)       (((x) >> 2) & 0x01)
33 #define SIZE_FIELD_TO_CACHE_LINE_LENGTH(x)    (((x) >> 0) & 0x03)
34 
35 #define DATA_CACHE_SIZE_FIELD(x)              (((x) >> 12) & 0x0FFF)
36 #define INSTRUCTION_CACHE_SIZE_FIELD(x)       (((x) >>  0) & 0x0FFF)
37 
38 #define DATA_CACHE_SIZE(x)                    (SIZE_FIELD_TO_CACHE_SIZE(DATA_CACHE_SIZE_FIELD(x)))
39 #define DATA_CACHE_ASSOCIATIVITY(x)           (SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(DATA_CACHE_SIZE_FIELD(x)))
40 #define DATA_CACHE_PRESENT(x)                 (SIZE_FIELD_TO_CACHE_PRESENCE(DATA_CACHE_SIZE_FIELD(x)))
41 #define DATA_CACHE_LINE_LENGTH(x)             (SIZE_FIELD_TO_CACHE_LINE_LENGTH(DATA_CACHE_SIZE_FIELD(x)))
42 
43 #define INSTRUCTION_CACHE_SIZE(x)             (SIZE_FIELD_TO_CACHE_SIZE(INSTRUCTION_CACHE_SIZE_FIELD(x)))
44 #define INSTRUCTION_CACHE_ASSOCIATIVITY(x)    (SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(INSTRUCTION_CACHE_SIZE_FIELD(x)))
45 #define INSTRUCTION_CACHE_PRESENT(x)          (SIZE_FIELD_TO_CACHE_PRESENCE(INSTRUCTION_CACHE_SIZE_FIELD(x)))
46 #define INSTRUCTION_CACHE_LINE_LENGTH(x)      (SIZE_FIELD_TO_CACHE_LINE_LENGTH(INSTRUCTION_CACHE_SIZE_FIELD(x)))
47 
48 #define CACHE_TYPE(x)                         (((x) >> 25) & 0x0F)
49 #define CACHE_TYPE_WRITE_BACK                 (0x0EUL)
50 
51 #define CACHE_ARCHITECTURE(x)                 (((x) >> 24) & 0x01)
52 #define CACHE_ARCHITECTURE_UNIFIED            (0UL)
53 #define CACHE_ARCHITECTURE_SEPARATE           (1UL)
54 
55 
56 /// Defines the structure of the CSSELR (Cache Size Selection) register
57 typedef union {
58   struct {
59     UINT32    InD       :1;  ///< Instruction not Data bit
60     UINT32    Level     :3;  ///< Cache level (zero based)
61     UINT32    TnD       :1;  ///< Allocation not Data bit
62     UINT32    Reserved  :27; ///< Reserved, RES0
63   } Bits; ///< Bitfield definition of the register
64   UINT32 Data; ///< The entire 32-bit value
65 } CSSELR_DATA;
66 
67 /// The cache type values for the InD field of the CSSELR register
68 typedef enum
69 {
70   /// Select the data or unified cache
71   CsselrCacheTypeDataOrUnified = 0,
72   /// Select the instruction cache
73   CsselrCacheTypeInstruction,
74   CsselrCacheTypeMax
75 } CSSELR_CACHE_TYPE;
76 
77 /// Defines the structure of the CCSIDR (Current Cache Size ID) register
78 typedef union {
79   struct {
80     UINT64    LineSize           :3;  ///< Line size (Log2(Num bytes in cache) - 4)
81     UINT64    Associativity      :10; ///< Associativity - 1
82     UINT64    NumSets            :15; ///< Number of sets in the cache -1
83     UINT64    Unknown            :4;  ///< Reserved, UNKNOWN
84     UINT64    Reserved           :32; ///< Reserved, RES0
85   } BitsNonCcidx; ///< Bitfield definition of the register when FEAT_CCIDX is not supported.
86   struct {
87     UINT64    LineSize           :3;  ///< Line size (Log2(Num bytes in cache) - 4)
88     UINT64    Associativity      :21; ///< Associativity - 1
89     UINT64    Reserved1          :8;  ///< Reserved, RES0
90     UINT64    NumSets            :24; ///< Number of sets in the cache -1
91     UINT64    Reserved2          :8;  ///< Reserved, RES0
92   } BitsCcidxAA64; ///< Bitfield definition of the register when FEAT_IDX is supported.
93   struct {
94     UINT64    LineSize           : 3;
95     UINT64    Associativity      : 21;
96     UINT64    Reserved           : 8;
97     UINT64    Unallocated        : 32;
98   } BitsCcidxAA32;
99   UINT64 Data; ///< The entire 64-bit value
100 } CCSIDR_DATA;
101 
102 /// Defines the structure of the AARCH32 CCSIDR2 register.
103 typedef union {
104   struct {
105     UINT32 NumSets               :24; ///< Number of sets in the cache - 1
106     UINT32 Reserved              :8;  ///< Reserved, RES0
107   } Bits; ///< Bitfield definition of the register
108   UINT32 Data; ///< The entire 32-bit value
109 } CCSIDR2_DATA;
110 
111 /** Defines the structure of the CLIDR (Cache Level ID) register.
112  *
113  * The lower 32 bits are the same for both AARCH32 and AARCH64
114  * so we can use the same structure for both.
115 **/
116 typedef union {
117   struct {
118     UINT32    Ctype1   : 3; ///< Level 1 cache type
119     UINT32    Ctype2   : 3; ///< Level 2 cache type
120     UINT32    Ctype3   : 3; ///< Level 3 cache type
121     UINT32    Ctype4   : 3; ///< Level 4 cache type
122     UINT32    Ctype5   : 3; ///< Level 5 cache type
123     UINT32    Ctype6   : 3; ///< Level 6 cache type
124     UINT32    Ctype7   : 3; ///< Level 7 cache type
125     UINT32    LoUIS    : 3; ///< Level of Unification Inner Shareable
126     UINT32    LoC      : 3; ///< Level of Coherency
127     UINT32    LoUU     : 3; ///< Level of Unification Uniprocessor
128     UINT32    Icb      : 3; ///< Inner Cache Boundary
129   } Bits; ///< Bitfield definition of the register
130   UINT32 Data; ///< The entire 32-bit value
131 } CLIDR_DATA;
132 
133 /// The cache types reported in the CLIDR register.
134 typedef enum {
135   /// No cache is present
136   ClidrCacheTypeNone = 0,
137   /// There is only an instruction cache
138   ClidrCacheTypeInstructionOnly,
139   /// There is only a data cache
140   ClidrCacheTypeDataOnly,
141   /// There are separate data and instruction caches
142   ClidrCacheTypeSeparate,
143   /// There is a unified cache
144   ClidrCacheTypeUnified,
145   ClidrCacheTypeMax
146 } CLIDR_CACHE_TYPE;
147 
148 #define CLIDR_GET_CACHE_TYPE(x, level) ((x >> (3 * (level))) & 0b111)
149 
150 VOID
151 CPSRMaskInsert (
152   IN  UINT32  Mask,
153   IN  UINT32  Value
154   );
155 
156 UINT32
157 CPSRRead (
158   VOID
159   );
160 
161 /** Reads the CCSIDR register for the specified cache.
162 
163   @param CSSELR The CSSELR cache selection register value.
164 
165   @return The contents of the CCSIDR_EL1 register for the specified cache, when in AARCH64 mode.
166           Returns the contents of the CCSIDR register in AARCH32 mode.
167 **/
168 UINTN
169 ReadCCSIDR (
170   IN UINT32 CSSELR
171   );
172 
173 /** Reads the CCSIDR2 for the specified cache.
174 
175   @param CSSELR The CSSELR cache selection register value
176 
177   @return The contents of the CCSIDR2 register for the specified cache.
178 **/
179 UINT32
180 ReadCCSIDR2 (
181   IN UINT32 CSSELR
182   );
183 
184 UINT32
185 ReadCLIDR (
186   VOID
187   );
188 
189 #endif // __ARM_LIB_PRIVATE_H__
190