12
#include <asm/mipsregs.h>
13
#include <drivers/mips/global_control_block.h>
14
#include <framework/mod/options.h>
16
#include <kernel/irq.h>
19
#include "mips_gic_regs.h"
21
#define MIPS_GIC_BASE OPTION_GET(NUMBER, base_addr)
23
static int mips_gic_init(void) {
27
#if (MIPS_GIC_BASE < (0xA0000000))
28
mips32_gcb_set_register(GCR_GIC_BASE, MIPS_GIC_BASE | GIC_EN);
30
mips32_gcb_set_register(GCR_GIC_BASE,
31
(MIPS_GIC_BASE - (0xA0000000)) | GIC_EN);
35
for (i = 0; i < __IRQCTRL_IRQS_TOTAL; i++) {
36
if (0 == (i & 0x1F)) {
37
REG32_STORE((MIPS_GIC_BASE + GIC_SH_RMASK(i)), 0xFFFFFFFF);
38
REG32_STORE(MIPS_GIC_BASE + GIC_SH_POL(i), 0xFFFFFFFF);
41
REG32_STORE(MIPS_GIC_BASE + GIC_SH_MAP_CORE31_0(i), 0x1);
42
REG32_STORE(MIPS_GIC_BASE + GIC_SH_MAP_PIN(i),
43
MIPS_GIC_INTERRUPT_PIN | 1u << 31);
46
c0 = mips_read_c0_status();
47
c0 |= 1 << (MIPS_GIC_INTERRUPT_PIN + ST0_IRQ_MASK_OFFSET + ST0_SOFTIRQ_NUM);
48
mips_write_c0_status(c0);
50
log_info("mips_gic config %x\n", REG_LOAD(MIPS_GIC_BASE + GIC_SH_CONFIG));
51
log_info("mips_gic revision %x\n", REG_LOAD(MIPS_GIC_BASE + GIC_SH_REVID));
56
void irqctrl_enable(unsigned int irq) {
61
assert(irq_nr_valid(irq));
64
c0 = mips_read_c0_status();
65
c0 |= 1 << (irq + ST0_IRQ_MASK_OFFSET);
66
mips_write_c0_status(c0);
70
mask = (1 << (irq & 0x1F));
71
REG32_STORE(MIPS_GIC_BASE + GIC_SH_SMASK(reg << 5), mask);
75
void irqctrl_disable(unsigned int irq) {
80
assert(irq_nr_valid(irq));
83
c0 = mips_read_c0_status();
84
c0 &= ~(1 << (irq + ST0_IRQ_MASK_OFFSET));
85
mips_write_c0_status(c0);
89
mask = (1 << (irq & 0x1F));
90
REG32_STORE(MIPS_GIC_BASE + GIC_SH_RMASK(reg << 5), mask);
94
void irqctrl_force(unsigned int irq) {
97
int irqctrl_pending(unsigned int irq) {
101
void irqctrl_eoi(unsigned int irq) {
105
assert(irq_nr_valid(irq));
110
mask = (1 << (irq & 0x1F));
111
REG32_STORE(MIPS_GIC_BASE + GIC_SH_SMASK(reg << 5), mask);
115
unsigned int irqctrl_get_intid(void) {
119
pending = (mips_read_c0_cause() & CAUSE_IM) >> ST0_IRQ_MASK_OFFSET;
121
if (!(pending & (0x1 << (ST0_SOFTIRQ_NUM + MIPS_GIC_INTERRUPT_PIN)))) {
122
for (i = 0; i < 8; i++) {
123
if (pending & (1U << i)) {
129
for (i = 0; i < __IRQCTRL_IRQS_TOTAL; i += 32) {
130
pending = REG32_LOAD(MIPS_GIC_BASE + GIC_SH_PEND(i));
131
pending &= REG32_LOAD(MIPS_GIC_BASE + GIC_SH_MASK(i));
137
for (j = 0; j < 32; j++) {
138
if (pending & (1U << j)) {
147
IRQCTRL_DEF(mips_gic, mips_gic_init);