summaryrefslogtreecommitdiffstats
path: root/drivers/arm/gic/v3/gicrv3_helpers.c
blob: 3004054ee7d431f0c658e709cc589b5d2e0da84b (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
/*
 * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <arch.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <common/interrupt_props.h>
#include <drivers/arm/gicv3.h>
#include "gicv3_private.h"

/*******************************************************************************
 * GIC Redistributor functions
 * Note: The raw register values correspond to multiple interrupt `id`s and
 * the number of interrupt `id`s involved depends on the register accessed.
 ******************************************************************************/

/*
 * Accessors to read/write the GIC Redistributor IPRIORITYR and IPRIORITYRE
 * register corresponding to the interrupt `id`, 4 interrupts IDs at a time.
 */
unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id)
{
	return GICR_READ(IPRIORITY, base, id);
}

void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
{
	GICR_WRITE(IPRIORITY, base, id, val);
}

/*
 * Accessor to set the byte corresponding to interrupt `id`
 * in GIC Redistributor IPRIORITYR and IPRIORITYRE.
 */
void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
{
	GICR_WRITE_8(IPRIORITY, base, id, (uint8_t)(pri & GIC_PRI_MASK));
}

/*
 * Accessors to get/set/clear the bit corresponding to interrupt `id`
 * from GIC Redistributor IGROUPR0 and IGROUPRE
 */
unsigned int gicr_get_igroupr(uintptr_t base, unsigned int id)
{
	return GICR_GET_BIT(IGROUP, base, id);
}

void gicr_set_igroupr(uintptr_t base, unsigned int id)
{
	GICR_SET_BIT(IGROUP, base, id);
}

void gicr_clr_igroupr(uintptr_t base, unsigned int id)
{
	GICR_CLR_BIT(IGROUP, base, id);
}

/*
 * Accessors to get/set/clear the bit corresponding to interrupt `id`
 * from GIC Redistributor IGRPMODR0 and IGRPMODRE
 */
unsigned int gicr_get_igrpmodr(uintptr_t base, unsigned int id)
{
	return GICR_GET_BIT(IGRPMOD, base, id);
}

void gicr_set_igrpmodr(uintptr_t base, unsigned int id)
{
	GICR_SET_BIT(IGRPMOD, base, id);
}

void gicr_clr_igrpmodr(uintptr_t base, unsigned int id)
{
	GICR_CLR_BIT(IGRPMOD, base, id);
}

/*
 * Accessor to write the bit corresponding to interrupt `id`
 * in GIC Redistributor ISENABLER0 and ISENABLERE
 */
void gicr_set_isenabler(uintptr_t base, unsigned int id)
{
	GICR_WRITE_BIT(ISENABLE, base, id);
}

/*
 * Accessor to write the bit corresponding to interrupt `id`
 * in GIC Redistributor ICENABLER0 and ICENABLERE
 */
void gicr_set_icenabler(uintptr_t base, unsigned int id)
{
	GICR_WRITE_BIT(ICENABLE, base, id);
}

/*
 * Accessor to get the bit corresponding to interrupt `id`
 * in GIC Redistributor ISACTIVER0 and ISACTIVERE
 */
unsigned int gicr_get_isactiver(uintptr_t base, unsigned int id)
{
	return	GICR_GET_BIT(ISACTIVE, base, id);
}

/*
 * Accessor to clear the bit corresponding to interrupt `id`
 * in GIC Redistributor ICPENDR0 and ICPENDRE
 */
void gicr_set_icpendr(uintptr_t base, unsigned int id)
{
	GICR_WRITE_BIT(ICPEND, base, id);
}

/*
 * Accessor to write the bit corresponding to interrupt `id`
 * in GIC Redistributor ISPENDR0 and ISPENDRE
 */
void gicr_set_ispendr(uintptr_t base, unsigned int id)
{
	GICR_WRITE_BIT(ISPEND, base, id);
}

/*
 * Accessor to set the bit fields corresponding to interrupt `id`
 * in GIC Redistributor ICFGR0, ICFGR1 and ICFGRE
 */
void gicr_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg)
{
	/* Interrupt configuration is a 2-bit field */
	unsigned int bit_shift = BIT_NUM(ICFG, id) << 1U;

	/* Clear the field, and insert required configuration */
	mmio_clrsetbits_32(base + GICR_OFFSET(ICFG, id),
				(uint32_t)GIC_CFG_MASK << bit_shift,
				(cfg & GIC_CFG_MASK) << bit_shift);
}