embox

Форк
0
148 строк · 2.6 Кб
1
/**
2
 * @file
3
 * @brief
4
 *
5
 * @date 05.02.2013
6
 * @author Anton Bulychev
7
 */
8

9
#include <embox/unit.h>
10

11
#include <stdint.h>
12

13
#include <hal/cpu.h>
14

15
#include <asm/io.h>
16

17
#include "lapic.h"
18

19
#include <drivers/irqctrl.h>
20
#include <drivers/common/memory.h>
21

22
#include <module/embox/driver/interrupt/lapic.h>
23

24
#ifdef LAPIC_REGS_X86_H_
25
#include "drivers/i8259_regs.h"
26
#endif
27

28
EMBOX_UNIT_INIT(ioapic_enable);
29

30
static inline void i8259_disable(void)
31
{
32
#ifdef IOAPIC_REGS_X86_H_ /* Needed only for x86 */
33
	outb(0xFF, PIC2_DATA);
34
	outb(0xFF, PIC1_DATA);
35
	//inb(PIC1_DATA);
36
#endif /* IOAPIC_REGS_X86_H_ */
37
}
38

39
/**
40
 * Initialize the IOAPIC
41
 */
42
static int ioapic_enable(void) {
43
	static int inited = 0;
44
	if (inited & 0x1 << cpu_get_id()) {
45
		return 0;
46
	}else
47
		inited |= 0x1 << cpu_get_id();
48

49
#ifdef IOAPIC_REGS_X86_H_
50
	/* I'm not sure that it is correct */
51
	outb(0x70, 0x22);
52
	outb(0x01, 0x23);
53
#endif
54

55
	return 0;
56
}
57

58
void apic_init(void) {
59
	i8259_disable();
60
	ioapic_enable();
61

62
	lapic_enable();
63
}
64

65
static inline uint32_t irq_redir_low(unsigned int irq) {
66
	uint32_t val = 0;
67

68
	if (irq < 16) {
69
		/* ISA active-high */
70
		val |= IOAPIC_ICR_HIGH_POLARITY;
71
		/* ISA edge triggered */
72
		val |= IOAPIC_ICR_EDGE_TRIGGER;
73
	}
74
	else {
75
		/* PCI active-low */
76
		val |= IOAPIC_ICR_LOW_POLARITY;
77
		/* PCI level triggered */
78
		val |= IOAPIC_ICR_LEVEL_TRIGGER;
79
	}
80

81
	val |= IOAPIC_ICR_DM_FIXED;
82
	val |= IOAPIC_ICR_LOGICAL_DEST;
83
	val |= (irq + 0x20);
84

85
	/* Return with Mask bit clear */
86
	return val;
87
}
88

89
void irqctrl_enable(unsigned int irq) {
90
	uint32_t low;
91
	static uint32_t high = 0;
92

93
	if (irq >= 24) {
94
		/* msi irq */
95
		return;
96
	}
97
	low = irq_redir_low(irq);
98
	/**
99
	 * In both SMP and NOSMP situation, we can use logical destination
100
	 * mode to delivery interrupt. But when we add CPU in such mode,
101
	 * we only need to call irqctrl_enable() at each CPUs to set bit
102
	 */
103
	high |= lapic_read(LAPIC_LDR);
104

105
	ioapic_write(IOAPIC_REDIR_TABLE + irq * 2, low);
106
	ioapic_write(IOAPIC_REDIR_TABLE + irq * 2 + 1, high);
107
}
108

109
void irqctrl_disable(unsigned int irq) {
110
	uint32_t low;
111

112
	if (irq == 0) {
113
		/*None Maskable interrupt*/
114
		return;
115
	}
116

117
	if (irq >= 24) {
118
		/* msi irq */
119
		return;
120
	}
121

122
	low = ioapic_read(IOAPIC_REDIR_TABLE + irq * 2);
123
	low |= IOAPIC_ICR_INT_MASK;
124
	ioapic_write(IOAPIC_REDIR_TABLE + irq * 2, low);
125
}
126

127
void irqctrl_force(unsigned int irq) {
128
	// TODO Emm?.. -- Eldar
129
}
130

131
int irqctrl_pending(unsigned int irq) {
132
	// TODO Emm?.. -- Anton
133
	return 1;
134
}
135

136
void irqctrl_eoi(unsigned int irq) {
137
	//TODO: irq >= 16
138
	if (irq >= 24) {
139
		/* msi irq */
140
		return;
141
	}
142

143
	lapic_send_eoi();
144
}
145

146
IRQCTRL_DEF(iopic, NULL);
147

148
PERIPH_MEMORY_DEFINE(iopic, IOAPIC_DEF_ADDR, 0x100);
149

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

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

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

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