blob: 6fcb938151befeddb3f05c0e8f1e7fa5a23f0367 [file] [log] [blame]
Madhukar Pappireddy464f2462021-08-03 11:23:07 -05001/*
2 * Copyright 2021 The Hafnium Authors.
3 *
4 * Use of this source code is governed by a BSD-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/BSD-3-Clause.
7 */
8
9#pragma once
10
11#include <stdatomic.h>
12
13#include "hf/arch/types.h"
14
15#include "vmapi/hf/ffa.h"
16
17/**
Daniel Boulby801f8ef2022-06-27 14:21:01 +010018 * Macros for accessing the bitmap tracking interrupts.
19 */
20/* The number of bits in each element of the interrupt bitfields. */
21#define INTERRUPT_REGISTER_BITS 32
22
Daniel Boulby4ca50f02022-07-29 18:29:34 +010023struct interrupt_bitmap {
24 uint32_t bitmap[HF_NUM_INTIDS / INTERRUPT_REGISTER_BITS];
25};
Daniel Boulby801f8ef2022-06-27 14:21:01 +010026
Daniel Boulby4ca50f02022-07-29 18:29:34 +010027static inline uint32_t interrupt_bitmap_get_value(
28 struct interrupt_bitmap *bitmap, uint32_t intid)
29{
30 uint32_t index = intid / INTERRUPT_REGISTER_BITS;
31 uint32_t shift = intid % INTERRUPT_REGISTER_BITS;
32
33 return (bitmap->bitmap[index] >> shift) & 1U;
34}
35
36static inline void interrupt_bitmap_set_value(struct interrupt_bitmap *bitmap,
37 uint32_t intid)
38{
39 uint32_t index = intid / INTERRUPT_REGISTER_BITS;
40 uint32_t shift = intid % INTERRUPT_REGISTER_BITS;
41
42 bitmap->bitmap[index] |= 1U << shift;
43}
44
45static inline void interrupt_bitmap_clear_value(struct interrupt_bitmap *bitmap,
46 uint32_t intid)
47{
48 uint32_t index = intid / INTERRUPT_REGISTER_BITS;
49 uint32_t shift = intid % INTERRUPT_REGISTER_BITS;
50
51 bitmap->bitmap[index] &= ~(1U << shift);
52}
Daniel Boulby801f8ef2022-06-27 14:21:01 +010053/**
Madhukar Pappireddy464f2462021-08-03 11:23:07 -050054 * Attributes encoding in the manifest:
55
56 * Field Bit(s)
57 * ---------------------------
58 * Priority 7:0
59 * Security_State 8
60 * Config(Edge/Level) 9
61 * Type(SPI/PPI/SGI) 11:10
62 * Reserved 31:12
63 *
64 * Implementation defined Encodings for various fields:
65 *
66 * Security_State:
67 * - Secure: 1
68 * - Non-secure: 0
69 *
70 * Configuration:
71 * - Edge triggered: 0
Madhukar Pappireddy1f9df612023-01-04 08:38:22 -060072 * - Level sensitive: 1
Madhukar Pappireddy464f2462021-08-03 11:23:07 -050073 * Type:
74 * - SPI: 0b10
75 * - PPI: 0b01
76 * - SGI: 0b00
77 *
78 */
79
80#define INT_DESC_TYPE_SPI 2
81#define INT_DESC_TYPE_PPI 1
82#define INT_DESC_TYPE_SGI 0
83
84/** Interrupt Descriptor field masks and shifts. */
85
86#define INT_DESC_PRIORITY_SHIFT 0
87#define INT_DESC_SEC_STATE_SHIFT 8
88#define INT_DESC_CONFIG_SHIFT 9
89#define INT_DESC_TYPE_SHIFT 10
90
91struct interrupt_descriptor {
92 uint32_t interrupt_id;
93
94 /**
95 * Bit fields Position
96 * ---------------------
97 * reserved: 7:4
98 * type: 3:2
99 * config: 1
100 * sec_state: 0
101 */
102 uint8_t type_config_sec_state;
103 uint8_t priority;
104 bool valid;
Raghu Krishnamurthy98da1ca2022-10-04 08:59:01 -0700105 bool mpidr_valid;
106 uint64_t mpidr;
Madhukar Pappireddy464f2462021-08-03 11:23:07 -0500107};
108
109/**
110 * Helper APIs for accessing interrupt_descriptor member variables.
111 */
112static inline uint32_t interrupt_desc_get_id(
113 struct interrupt_descriptor int_desc)
114{
115 return int_desc.interrupt_id;
116}
117
118static inline uint8_t interrupt_desc_get_sec_state(
119 struct interrupt_descriptor int_desc)
120{
121 return ((int_desc.type_config_sec_state >> 0) & 1U);
122}
123
124static inline uint8_t interrupt_desc_get_config(
125 struct interrupt_descriptor int_desc)
126{
127 return ((int_desc.type_config_sec_state >> 1) & 1U);
128}
129
130static inline uint8_t interrupt_desc_get_type(
131 struct interrupt_descriptor int_desc)
132{
133 return ((int_desc.type_config_sec_state >> 2) & 3U);
134}
135
136static inline uint8_t interrupt_desc_get_priority(
137 struct interrupt_descriptor int_desc)
138{
139 return int_desc.priority;
140}
141
Raghu Krishnamurthy98da1ca2022-10-04 08:59:01 -0700142static inline uint64_t interrupt_desc_get_mpidr(
143 struct interrupt_descriptor int_desc)
144{
145 return int_desc.mpidr;
146}
147
148static inline bool interrupt_desc_get_mpidr_valid(
149 struct interrupt_descriptor int_desc)
150{
151 return int_desc.mpidr_valid;
152}
153
Madhukar Pappireddy464f2462021-08-03 11:23:07 -0500154static inline bool interrupt_desc_get_valid(
155 struct interrupt_descriptor int_desc)
156{
157 return int_desc.valid;
158}
159
160static inline void interrupt_desc_set_id(struct interrupt_descriptor *int_desc,
161 uint32_t interrupt_id)
162{
163 int_desc->interrupt_id = interrupt_id;
164}
165
Raghu Krishnamurthy98da1ca2022-10-04 08:59:01 -0700166static inline void interrupt_desc_set_mpidr(
167 struct interrupt_descriptor *int_desc, uint64_t mpidr)
168{
169 int_desc->mpidr_valid = true;
170 int_desc->mpidr = mpidr;
171}
172
173static inline void interrupt_desc_set_mpidr_invalid(
174 struct interrupt_descriptor *int_desc)
175{
176 int_desc->mpidr_valid = false;
177 int_desc->mpidr = 0;
178}
179
Madhukar Pappireddy464f2462021-08-03 11:23:07 -0500180static inline void interrupt_desc_set_type_config_sec_state(
181 struct interrupt_descriptor *int_desc, uint8_t value)
182{
183 int_desc->type_config_sec_state = value;
184}
185
186static inline void interrupt_desc_set_priority(
187 struct interrupt_descriptor *int_desc, uint8_t priority)
188{
189 int_desc->priority = priority;
190}
191
192static inline void interrupt_desc_set_valid(
193 struct interrupt_descriptor *int_desc, bool valid)
194{
195 int_desc->valid = valid;
196}