blob: e95e47bc85dab9a129c408a213fefe646f4494f1 [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
72 * - Level triggered: 1
73 * 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;
105};
106
107/**
108 * Helper APIs for accessing interrupt_descriptor member variables.
109 */
110static inline uint32_t interrupt_desc_get_id(
111 struct interrupt_descriptor int_desc)
112{
113 return int_desc.interrupt_id;
114}
115
116static inline uint8_t interrupt_desc_get_sec_state(
117 struct interrupt_descriptor int_desc)
118{
119 return ((int_desc.type_config_sec_state >> 0) & 1U);
120}
121
122static inline uint8_t interrupt_desc_get_config(
123 struct interrupt_descriptor int_desc)
124{
125 return ((int_desc.type_config_sec_state >> 1) & 1U);
126}
127
128static inline uint8_t interrupt_desc_get_type(
129 struct interrupt_descriptor int_desc)
130{
131 return ((int_desc.type_config_sec_state >> 2) & 3U);
132}
133
134static inline uint8_t interrupt_desc_get_priority(
135 struct interrupt_descriptor int_desc)
136{
137 return int_desc.priority;
138}
139
140static inline bool interrupt_desc_get_valid(
141 struct interrupt_descriptor int_desc)
142{
143 return int_desc.valid;
144}
145
146static inline void interrupt_desc_set_id(struct interrupt_descriptor *int_desc,
147 uint32_t interrupt_id)
148{
149 int_desc->interrupt_id = interrupt_id;
150}
151
152static inline void interrupt_desc_set_type_config_sec_state(
153 struct interrupt_descriptor *int_desc, uint8_t value)
154{
155 int_desc->type_config_sec_state = value;
156}
157
158static inline void interrupt_desc_set_priority(
159 struct interrupt_descriptor *int_desc, uint8_t priority)
160{
161 int_desc->priority = priority;
162}
163
164static inline void interrupt_desc_set_valid(
165 struct interrupt_descriptor *int_desc, bool valid)
166{
167 int_desc->valid = valid;
168}