blob: 838ae37e2cc6b24f319a7ef29b3e001fa47866a5 [file] [log] [blame]
Boyan Karatotev8cef63d2025-01-07 11:26:56 +00001/*
2 * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef GICV5_H
8#define GICV5_H
Boyan Karatotev13b62812024-11-20 14:02:32 +00009
10#ifndef __ASSEMBLER__
11#include <stdbool.h>
12#include <stdint.h>
Boyan Karatotevdfb37a22024-12-09 14:29:33 +000013
14#include <lib/mmio.h>
Boyan Karatotev13b62812024-11-20 14:02:32 +000015#endif
16
17#include <lib/utils_def.h>
18
19/* Interrupt Domain definitions */
20#define INTDMN_S 0
21#define INTDMN_NS 1
22#define INTDMN_EL3 2
23#define INTDMN_RL 3
24
25/* Trigger modes */
26#define TM_EDGE 0
27#define TM_LEVEL 1
28
Boyan Karatotev82b228b2024-12-09 14:26:37 +000029/* Architected PPI numbers */
30#define PPI_TRBIRQ 31
31#define PPI_CNTP 30
32#define PPI_CNTPS 29
33#define PPI_CNTHV 28
34#define PPI_CNTV 27
35#define PPI_CNTHP 26
36#define PPI_GICMNT 25
37#define PPI_CTIIRQ 24
38#define PPI_PMUIRQ 23
39#define PPI_COMMIRQ 22
40#define PPI_PMBIRQ 21
41#define PPI_CNTHPS 20
42#define PPI_CNTHVS 19
43#define PPI_DB_NS 2
44#define PPI_DB_RL 1
45#define PPI_DB_S 0
46
Boyan Karatotevdfb37a22024-12-09 14:29:33 +000047/* IRS register fields */
48#define IRS_IDR6_SPI_IRS_RANGE_SHIFT 0
49#define IRS_IDR6_SPI_IRS_RANGE_WIDTH 24
50#define IRS_IDR7_SPI_BASE_SHIFT 0
51#define IRS_IDR7_SPI_BASE_WIDTH 24
52
53#define IRS_SPI_STATUSR_IDLE_BIT BIT(0)
54#define IRS_SPI_STATUSR_V_BIT BIT(1)
55
Boyan Karatotev13b62812024-11-20 14:02:32 +000056#ifndef __ASSEMBLER__
57
Boyan Karatotev82b228b2024-12-09 14:26:37 +000058#define _PPI_FIELD_SHIFT(_REG, _ppi_id) \
59 ((_ppi_id % (ICC_PPI_##_REG##_COUNT)) * (64 / ICC_PPI_##_REG##_COUNT))
60
61#define write_icc_ppi_domainr(_var, _ppi_id, _value) \
62 do { \
63 _var |= (uint64_t)_value << _PPI_FIELD_SHIFT(DOMAINR, _ppi_id);\
64 } while (false)
65
Boyan Karatotevdfb37a22024-12-09 14:29:33 +000066
67#define DEFINE_GICV5_MMIO_WRITE_FUNC(_name, _offset) \
68static inline void write_##_name(uintptr_t base, uint32_t val) \
69{ \
70 mmio_write_32(base + _offset, val); \
71}
72
73#define DEFINE_GICV5_MMIO_READ_FUNC(_name, _offset) \
74static inline uint32_t read_##_name(uintptr_t base) \
75{ \
76 return mmio_read_32(base + _offset); \
77}
78
79#define DEFINE_GICV5_MMIO_RW_FUNCS(_name, _offset) \
80 DEFINE_GICV5_MMIO_READ_FUNC(_name, _offset) \
81 DEFINE_GICV5_MMIO_WRITE_FUNC(_name, _offset)
82
83DEFINE_GICV5_MMIO_READ_FUNC(irs_idr6, 0x0018)
84DEFINE_GICV5_MMIO_READ_FUNC(irs_idr7, 0x001c)
85DEFINE_GICV5_MMIO_RW_FUNCS( irs_spi_selr, 0x0108)
86DEFINE_GICV5_MMIO_RW_FUNCS( irs_spi_domainr, 0x010c)
87DEFINE_GICV5_MMIO_RW_FUNCS( irs_spi_cfgr, 0x0114)
88DEFINE_GICV5_MMIO_READ_FUNC(irs_spi_statusr, 0x0118)
89
90#define WAIT_FOR_IDLE(base, reg, reg_up) \
91 do { \
92 while ((read_##reg(base) & reg_up##_IDLE_BIT) == 0U) {} \
93 } while (0)
94
95/* wait for IDLE but also check the V bit was set */
96#define WAIT_FOR_VIDLE(base, reg, reg_up) \
97 do { \
98 uint32_t val; \
99 while (((val = read_##reg(base)) & reg_up##_IDLE_BIT) == 0U) {} \
100 assert((val & reg##_V_BIT) != 0U); \
101 } while (0)
102
103#define WAIT_FOR_VIDLE_IRS_SPI_STATUSR(base) \
104 WAIT_FOR_IDLE(base, irs_spi_statusr, IRS_SPI_STATUSR)
105
106struct gicv5_wire_props {
107 /* continuous wire ID as seen by the attached component */
108 uint32_t id;
109 /* use the INTDMN_XYZ macros */
110 uint8_t domain:2;
111 /* use the TM_XYZ (eg. TM_EDGE) macros */
112 uint8_t tm:1;
113};
114
115/* to describe every IRS in the system */
116struct gicv5_irs {
117 /* mapped device nGnRnE by the platform*/
118 uintptr_t el3_config_frame;
119 struct gicv5_wire_props *spis;
120 uint32_t num_spis;
121};
122
Boyan Karatotev13b62812024-11-20 14:02:32 +0000123struct gicv5_driver_data {
Boyan Karatotevdfb37a22024-12-09 14:29:33 +0000124 struct gicv5_irs *irss;
125 uint32_t num_irss;
Boyan Karatotev13b62812024-11-20 14:02:32 +0000126};
127
128extern const struct gicv5_driver_data plat_gicv5_driver_data;
129
130void gicv5_driver_init();
131uint8_t gicv5_get_pending_interrupt_type(void);
132bool gicv5_has_interrupt_type(unsigned int type);
Boyan Karatotev82b228b2024-12-09 14:26:37 +0000133void gicv5_enable_ppis();
Boyan Karatotev13b62812024-11-20 14:02:32 +0000134#endif /* __ASSEMBLER__ */
Boyan Karatotev8cef63d2025-01-07 11:26:56 +0000135#endif /* GICV5_H */