blob: 3004054ee7d431f0c658e709cc589b5d2e0da84b [file] [log] [blame]
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +00001/*
2 * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <arch_helpers.h>
9#include <common/debug.h>
10#include <common/interrupt_props.h>
11#include <drivers/arm/gicv3.h>
12#include "gicv3_private.h"
13
14/*******************************************************************************
15 * GIC Redistributor functions
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010016 * Note: The raw register values correspond to multiple interrupt `id`s and
17 * the number of interrupt `id`s involved depends on the register accessed.
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000018 ******************************************************************************/
19
20/*
Alexei Fedorovc7510c52020-04-07 18:16:18 +010021 * Accessors to read/write the GIC Redistributor IPRIORITYR and IPRIORITYRE
22 * register corresponding to the interrupt `id`, 4 interrupts IDs at a time.
23 */
24unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id)
25{
26 return GICR_READ(IPRIORITY, base, id);
27}
28
29void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
30{
31 GICR_WRITE(IPRIORITY, base, id, val);
32}
33
34/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010035 * Accessor to set the byte corresponding to interrupt `id`
36 * in GIC Redistributor IPRIORITYR and IPRIORITYRE.
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000037 */
38void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
39{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010040 GICR_WRITE_8(IPRIORITY, base, id, (uint8_t)(pri & GIC_PRI_MASK));
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000041}
42
43/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010044 * Accessors to get/set/clear the bit corresponding to interrupt `id`
45 * from GIC Redistributor IGROUPR0 and IGROUPRE
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000046 */
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010047unsigned int gicr_get_igroupr(uintptr_t base, unsigned int id)
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000048{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010049 return GICR_GET_BIT(IGROUP, base, id);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000050}
51
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010052void gicr_set_igroupr(uintptr_t base, unsigned int id)
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000053{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010054 GICR_SET_BIT(IGROUP, base, id);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000055}
56
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010057void gicr_clr_igroupr(uintptr_t base, unsigned int id)
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000058{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010059 GICR_CLR_BIT(IGROUP, base, id);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000060}
61
62/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010063 * Accessors to get/set/clear the bit corresponding to interrupt `id`
64 * from GIC Redistributor IGRPMODR0 and IGRPMODRE
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000065 */
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010066unsigned int gicr_get_igrpmodr(uintptr_t base, unsigned int id)
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000067{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010068 return GICR_GET_BIT(IGRPMOD, base, id);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000069}
70
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010071void gicr_set_igrpmodr(uintptr_t base, unsigned int id)
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000072{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010073 GICR_SET_BIT(IGRPMOD, base, id);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000074}
75
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010076void gicr_clr_igrpmodr(uintptr_t base, unsigned int id)
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000077{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010078 GICR_CLR_BIT(IGRPMOD, base, id);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000079}
80
81/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010082 * Accessor to write the bit corresponding to interrupt `id`
83 * in GIC Redistributor ISENABLER0 and ISENABLERE
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000084 */
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010085void gicr_set_isenabler(uintptr_t base, unsigned int id)
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000086{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010087 GICR_WRITE_BIT(ISENABLE, base, id);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000088}
89
90/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010091 * Accessor to write the bit corresponding to interrupt `id`
92 * in GIC Redistributor ICENABLER0 and ICENABLERE
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000093 */
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010094void gicr_set_icenabler(uintptr_t base, unsigned int id)
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000095{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010096 GICR_WRITE_BIT(ICENABLE, base, id);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000097}
98
99/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100100 * Accessor to get the bit corresponding to interrupt `id`
101 * in GIC Redistributor ISACTIVER0 and ISACTIVERE
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000102 */
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100103unsigned int gicr_get_isactiver(uintptr_t base, unsigned int id)
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000104{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100105 return GICR_GET_BIT(ISACTIVE, base, id);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000106}
107
108/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100109 * Accessor to clear the bit corresponding to interrupt `id`
110 * in GIC Redistributor ICPENDR0 and ICPENDRE
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000111 */
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100112void gicr_set_icpendr(uintptr_t base, unsigned int id)
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000113{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100114 GICR_WRITE_BIT(ICPEND, base, id);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000115}
116
117/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100118 * Accessor to write the bit corresponding to interrupt `id`
119 * in GIC Redistributor ISPENDR0 and ISPENDRE
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000120 */
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100121void gicr_set_ispendr(uintptr_t base, unsigned int id)
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000122{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100123 GICR_WRITE_BIT(ISPEND, base, id);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000124}
125
126/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100127 * Accessor to set the bit fields corresponding to interrupt `id`
128 * in GIC Redistributor ICFGR0, ICFGR1 and ICFGRE
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000129 */
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100130void gicr_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg)
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000131{
132 /* Interrupt configuration is a 2-bit field */
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100133 unsigned int bit_shift = BIT_NUM(ICFG, id) << 1U;
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000134
135 /* Clear the field, and insert required configuration */
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100136 mmio_clrsetbits_32(base + GICR_OFFSET(ICFG, id),
137 (uint32_t)GIC_CFG_MASK << bit_shift,
138 (cfg & GIC_CFG_MASK) << bit_shift);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000139}