embox

Форк
0
147 строк · 3.0 Кб
1
/**
2
 * @file
3
 *
4
 * @date Mar 23, 2020
5
 * @author Anton Bondarev
6
 */
7

8
#include <assert.h>
9
#include <stdint.h>
10

11
#include <asm/io.h>
12
#include <asm/mipsregs.h>
13
#include <drivers/mips/global_control_block.h>
14
#include <framework/mod/options.h>
15
#include <hal/reg.h>
16
#include <kernel/irq.h>
17
#include <util/log.h>
18

19
#include "mips_gic_regs.h"
20

21
#define MIPS_GIC_BASE OPTION_GET(NUMBER, base_addr)
22

23
static int mips_gic_init(void) {
24
	uint32_t c0;
25
	int i;
26

27
#if (MIPS_GIC_BASE < (0xA0000000))
28
	mips32_gcb_set_register(GCR_GIC_BASE, MIPS_GIC_BASE | GIC_EN);
29
#else
30
	mips32_gcb_set_register(GCR_GIC_BASE,
31
	    (MIPS_GIC_BASE - (0xA0000000)) | GIC_EN);
32
#endif /* (MIPS_GIC_BASE < (0xA0000000)) */
33
	__sync();
34

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);
39
		}
40
		/* only 1 cpu core */
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);
44
	}
45

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);
49

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));
52

53
	return 0;
54
}
55

56
void irqctrl_enable(unsigned int irq) {
57
	uint32_t mask;
58
	uint32_t reg;
59
	uint32_t c0;
60

61
	assert(irq_nr_valid(irq));
62

63
	if (irq < 8) {
64
		c0 = mips_read_c0_status();
65
		c0 |= 1 << (irq + ST0_IRQ_MASK_OFFSET);
66
		mips_write_c0_status(c0);
67
	}
68
	else {
69
		reg = irq >> 5;
70
		mask = (1 << (irq & 0x1F));
71
		REG32_STORE(MIPS_GIC_BASE + GIC_SH_SMASK(reg << 5), mask);
72
	}
73
}
74

75
void irqctrl_disable(unsigned int irq) {
76
	uint32_t mask;
77
	uint32_t reg;
78
	uint32_t c0;
79

80
	assert(irq_nr_valid(irq));
81

82
	if (irq < 8) {
83
		c0 = mips_read_c0_status();
84
		c0 &= ~(1 << (irq + ST0_IRQ_MASK_OFFSET));
85
		mips_write_c0_status(c0);
86
	}
87
	else {
88
		reg = irq >> 5;
89
		mask = (1 << (irq & 0x1F));
90
		REG32_STORE(MIPS_GIC_BASE + GIC_SH_RMASK(reg << 5), mask);
91
	}
92
}
93

94
void irqctrl_force(unsigned int irq) {
95
}
96

97
int irqctrl_pending(unsigned int irq) {
98
	return 0;
99
}
100

101
void irqctrl_eoi(unsigned int irq) {
102
	uint32_t mask;
103
	uint32_t reg;
104

105
	assert(irq_nr_valid(irq));
106

107
	/* XXX */
108
	if (irq >= 8) {
109
		reg = irq >> 5;
110
		mask = (1 << (irq & 0x1F));
111
		REG32_STORE(MIPS_GIC_BASE + GIC_SH_SMASK(reg << 5), mask);
112
	}
113
}
114

115
unsigned int irqctrl_get_intid(void) {
116
	uint32_t pending;
117
	int i, j;
118

119
	pending = (mips_read_c0_cause() & CAUSE_IM) >> ST0_IRQ_MASK_OFFSET;
120

121
	if (!(pending & (0x1 << (ST0_SOFTIRQ_NUM + MIPS_GIC_INTERRUPT_PIN)))) {
122
		for (i = 0; i < 8; i++) {
123
			if (pending & (1U << i)) {
124
				return i;
125
			}
126
		}
127
	}
128

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));
132

133
		if (!pending) {
134
			continue;
135
		}
136

137
		for (j = 0; j < 32; j++) {
138
			if (pending & (1U << j)) {
139
				return i + j;
140
			}
141
		}
142
	}
143

144
	return -1;
145
}
146

147
IRQCTRL_DEF(mips_gic, mips_gic_init);
148

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.