summaryrefslogtreecommitdiffstats
path: root/ArmPkg/Library/ArmLib/ArmLibPrivate.h
blob: 1818a1994dc328f0bcc14321a89db726e11a3f12 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/** @file
  ArmLibPrivate.h

  Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#ifndef __ARM_LIB_PRIVATE_H__
#define __ARM_LIB_PRIVATE_H__

#define CACHE_SIZE_4_KB             (3UL)
#define CACHE_SIZE_8_KB             (4UL)
#define CACHE_SIZE_16_KB            (5UL)
#define CACHE_SIZE_32_KB            (6UL)
#define CACHE_SIZE_64_KB            (7UL)
#define CACHE_SIZE_128_KB           (8UL)

#define CACHE_ASSOCIATIVITY_DIRECT  (0UL)
#define CACHE_ASSOCIATIVITY_4_WAY   (2UL)
#define CACHE_ASSOCIATIVITY_8_WAY   (3UL)

#define CACHE_PRESENT               (0UL)
#define CACHE_NOT_PRESENT           (1UL)

#define CACHE_LINE_LENGTH_32_BYTES  (2UL)

#define SIZE_FIELD_TO_CACHE_SIZE(x)           (((x) >> 6) & 0x0F)
#define SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(x)  (((x) >> 3) & 0x07)
#define SIZE_FIELD_TO_CACHE_PRESENCE(x)       (((x) >> 2) & 0x01)
#define SIZE_FIELD_TO_CACHE_LINE_LENGTH(x)    (((x) >> 0) & 0x03)

#define DATA_CACHE_SIZE_FIELD(x)              (((x) >> 12) & 0x0FFF)
#define INSTRUCTION_CACHE_SIZE_FIELD(x)       (((x) >>  0) & 0x0FFF)

#define DATA_CACHE_SIZE(x)                    (SIZE_FIELD_TO_CACHE_SIZE(DATA_CACHE_SIZE_FIELD(x)))
#define DATA_CACHE_ASSOCIATIVITY(x)           (SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(DATA_CACHE_SIZE_FIELD(x)))
#define DATA_CACHE_PRESENT(x)                 (SIZE_FIELD_TO_CACHE_PRESENCE(DATA_CACHE_SIZE_FIELD(x)))
#define DATA_CACHE_LINE_LENGTH(x)             (SIZE_FIELD_TO_CACHE_LINE_LENGTH(DATA_CACHE_SIZE_FIELD(x)))

#define INSTRUCTION_CACHE_SIZE(x)             (SIZE_FIELD_TO_CACHE_SIZE(INSTRUCTION_CACHE_SIZE_FIELD(x)))
#define INSTRUCTION_CACHE_ASSOCIATIVITY(x)    (SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(INSTRUCTION_CACHE_SIZE_FIELD(x)))
#define INSTRUCTION_CACHE_PRESENT(x)          (SIZE_FIELD_TO_CACHE_PRESENCE(INSTRUCTION_CACHE_SIZE_FIELD(x)))
#define INSTRUCTION_CACHE_LINE_LENGTH(x)      (SIZE_FIELD_TO_CACHE_LINE_LENGTH(INSTRUCTION_CACHE_SIZE_FIELD(x)))

#define CACHE_TYPE(x)                         (((x) >> 25) & 0x0F)
#define CACHE_TYPE_WRITE_BACK                 (0x0EUL)

#define CACHE_ARCHITECTURE(x)                 (((x) >> 24) & 0x01)
#define CACHE_ARCHITECTURE_UNIFIED            (0UL)
#define CACHE_ARCHITECTURE_SEPARATE           (1UL)


/// Defines the structure of the CSSELR (Cache Size Selection) register
typedef union {
  struct {
    UINT32    InD       :1;  ///< Instruction not Data bit
    UINT32    Level     :3;  ///< Cache level (zero based)
    UINT32    TnD       :1;  ///< Allocation not Data bit
    UINT32    Reserved  :27; ///< Reserved, RES0
  } Bits; ///< Bitfield definition of the register
  UINT32 Data; ///< The entire 32-bit value
} CSSELR_DATA;

/// The cache type values for the InD field of the CSSELR register
typedef enum
{
  /// Select the data or unified cache
  CsselrCacheTypeDataOrUnified = 0,
  /// Select the instruction cache
  CsselrCacheTypeInstruction,
  CsselrCacheTypeMax
} CSSELR_CACHE_TYPE;

/// Defines the structure of the CCSIDR (Current Cache Size ID) register
typedef union {
  struct {
    UINT64    LineSize           :3;  ///< Line size (Log2(Num bytes in cache) - 4)
    UINT64    Associativity      :10; ///< Associativity - 1
    UINT64    NumSets            :15; ///< Number of sets in the cache -1
    UINT64    Unknown            :4;  ///< Reserved, UNKNOWN
    UINT64    Reserved           :32; ///< Reserved, RES0
  } BitsNonCcidx; ///< Bitfield definition of the register when FEAT_CCIDX is not supported.
  struct {
    UINT64    LineSize           :3;  ///< Line size (Log2(Num bytes in cache) - 4)
    UINT64    Associativity      :21; ///< Associativity - 1
    UINT64    Reserved1          :8;  ///< Reserved, RES0
    UINT64    NumSets            :24; ///< Number of sets in the cache -1
    UINT64    Reserved2          :8;  ///< Reserved, RES0
  } BitsCcidxAA64; ///< Bitfield definition of the register when FEAT_IDX is supported.
  struct {
    UINT64    LineSize           : 3;
    UINT64    Associativity      : 21;
    UINT64    Reserved           : 8;
    UINT64    Unallocated        : 32;
  } BitsCcidxAA32;
  UINT64 Data; ///< The entire 64-bit value
} CCSIDR_DATA;

/// Defines the structure of the AARCH32 CCSIDR2 register.
typedef union {
  struct {
    UINT32 NumSets               :24; ///< Number of sets in the cache - 1
    UINT32 Reserved              :8;  ///< Reserved, RES0
  } Bits; ///< Bitfield definition of the register
  UINT32 Data; ///< The entire 32-bit value
} CCSIDR2_DATA;

/** Defines the structure of the CLIDR (Cache Level ID) register.
 *
 * The lower 32 bits are the same for both AARCH32 and AARCH64
 * so we can use the same structure for both.
**/
typedef union {
  struct {
    UINT32    Ctype1   : 3; ///< Level 1 cache type
    UINT32    Ctype2   : 3; ///< Level 2 cache type
    UINT32    Ctype3   : 3; ///< Level 3 cache type
    UINT32    Ctype4   : 3; ///< Level 4 cache type
    UINT32    Ctype5   : 3; ///< Level 5 cache type
    UINT32    Ctype6   : 3; ///< Level 6 cache type
    UINT32    Ctype7   : 3; ///< Level 7 cache type
    UINT32    LoUIS    : 3; ///< Level of Unification Inner Shareable
    UINT32    LoC      : 3; ///< Level of Coherency
    UINT32    LoUU     : 3; ///< Level of Unification Uniprocessor
    UINT32    Icb      : 3; ///< Inner Cache Boundary
  } Bits; ///< Bitfield definition of the register
  UINT32 Data; ///< The entire 32-bit value
} CLIDR_DATA;

/// The cache types reported in the CLIDR register.
typedef enum {
  /// No cache is present
  ClidrCacheTypeNone = 0,
  /// There is only an instruction cache
  ClidrCacheTypeInstructionOnly,
  /// There is only a data cache
  ClidrCacheTypeDataOnly,
  /// There are separate data and instruction caches
  ClidrCacheTypeSeparate,
  /// There is a unified cache
  ClidrCacheTypeUnified,
  ClidrCacheTypeMax
} CLIDR_CACHE_TYPE;

#define CLIDR_GET_CACHE_TYPE(x, level) ((x >> (3 * (level))) & 0b111)

VOID
CPSRMaskInsert (
  IN  UINT32  Mask,
  IN  UINT32  Value
  );

UINT32
CPSRRead (
  VOID
  );

/** Reads the CCSIDR register for the specified cache.

  @param CSSELR The CSSELR cache selection register value.

  @return The contents of the CCSIDR_EL1 register for the specified cache, when in AARCH64 mode.
          Returns the contents of the CCSIDR register in AARCH32 mode.
**/
UINTN
ReadCCSIDR (
  IN UINT32 CSSELR
  );

/** Reads the CCSIDR2 for the specified cache.

  @param CSSELR The CSSELR cache selection register value

  @return The contents of the CCSIDR2 register for the specified cache.
**/
UINT32
ReadCCSIDR2 (
  IN UINT32 CSSELR
  );

UINT32
ReadCLIDR (
  VOID
  );

#endif // __ARM_LIB_PRIVATE_H__