embox

Форк
0
123 строки · 2.6 Кб
1
/**
2
 * @file
3
 * @brief
4
 *
5
 * @author Aleksey Zhmulin
6
 * @date 20.10.23
7
 */
8
#include <assert.h>
9
#include <stddef.h>
10
#include <stdint.h>
11

12
#include <drivers/common/memory.h>
13
#include <drivers/irqctrl.h>
14
#include <framework/mod/options.h>
15
#include <hal/reg.h>
16
#include <kernel/critical.h>
17
#include <kernel/irq.h>
18
#include <kernel/printk.h>
19
#include <util/field.h>
20
#include <util/log.h>
21

22
#include "gicv1.h"
23

24
#define GIC_SPURIOUS_IRQ 0x3FF
25

26
static int gic_irqctrl_init(void) {
27
	uint32_t reg;
28

29
	/* Enable interrupts of all priorities */
30
	reg = REG32_LOAD(GICC_PMR);
31
	reg = FIELD_SET(reg, GICD_PMR_PRIOR, 0xff);
32
	REG32_STORE(GICC_PMR, reg);
33

34
	/* Configure control registers */
35
	REG32_ORIN(GICD_CTLR, GICD_CTLR_EN);
36
	REG32_ORIN(GICC_CTLR, GICC_CTLR_EN);
37

38
	/* Print info */
39
	reg = REG32_LOAD(GICD_TYPER);
40

41
	log_info("Number of SPI: %zi",
42
	    (size_t)(FIELD_GET(reg, GICD_TYPER_ITLINES) * 32));
43
	log_info("Number of supported CPU interfaces: %zi",
44
	    (size_t)FIELD_GET(reg, GICD_TYPER_CPU));
45

46
	if (reg & GICD_TYPER_SECEXT) {
47
		log_info("Secutity Extension implemented");
48
		log_info("Number of LSPI: %zi",
49
		    (size_t)FIELD_GET(reg, GICD_TYPER_LSPI));
50
	}
51
	else {
52
		log_info("Secutity Extension not implemented");
53
		log_info("LSPI not implemented");
54
	}
55

56
	return 0;
57
}
58

59
void irqctrl_enable(unsigned int irq) {
60
	unsigned int reg_nr;
61
	uint32_t value;
62

63
	assert(irq_nr_valid(irq));
64

65
	reg_nr = irq >> 5;
66
	value = 1U << (irq & 0x1f);
67

68
	/* Writing zeroes to this register has no
69
	 * effect, so we just write single "1" */
70
	REG32_STORE(GICD_ISENABLER(reg_nr), value);
71

72
	/* N-N irq model: all CPUs receive this IRQ */
73
	REG32_STORE(GICD_ICFGR(reg_nr), value);
74

75
	/* All CPUs do listen to this IRQ */
76
	reg_nr = irq >> 2;
77
	value = 0xff << ((irq & 0x3) << 3);
78
	REG32_ORIN(GICD_ITARGETSR(reg_nr), value);
79
}
80

81
void irqctrl_disable(unsigned int irq) {
82
	unsigned int reg_nr;
83
	uint32_t value;
84

85
	assert(irq_nr_valid(irq));
86

87
	reg_nr = irq >> 5;
88
	value = 1U << (irq & 0x1f);
89

90
	/* Writing zeroes to this register has no
91
	 * effect, so we just write single "1" */
92
	REG32_STORE(GICD_ICENABLER(reg_nr), value);
93
}
94

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

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

102
/* Sends an EOI (end of interrupt) signal to the PICs. */
103
void irqctrl_eoi(unsigned int irq) {
104
	assert(irq_nr_valid(irq));
105

106
	REG32_STORE(GICC_EOIR, irq);
107
}
108

109
unsigned int irqctrl_get_intid(void) {
110
	unsigned int irq;
111

112
	irq = REG32_LOAD(GICC_IAR);
113
	if (irq == GIC_SPURIOUS_IRQ) {
114
		irq = -1;
115
	}
116

117
	return irq;
118
}
119

120
IRQCTRL_DEF(gicv1, gic_irqctrl_init);
121

122
PERIPH_MEMORY_DEFINE(gicd, GICD_BASE, 0x1000);
123
PERIPH_MEMORY_DEFINE(gicc, GICC_BASE, 0x2020);
124

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

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

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

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