embox

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

9
#include <embox/unit.h>
10

11
#include <drivers/common/memory.h>
12

13
#include "lapic.h"
14

15
#ifdef LAPIC_REGS_X86_H_
16
#include <asm/msr.h>
17
#include <asm/ap.h>
18
#endif
19

20
#include <kernel/panic.h>
21
#include <hal/cpu.h>
22

23
#define lapic_read_icr1()    lapic_read(LAPIC_ICR1)
24
#define lapic_read_icr2()    lapic_read(LAPIC_ICR2)
25

26
#define lapic_write_icr1(val)   lapic_write(LAPIC_ICR1, val)
27
#define lapic_write_icr2(val)   lapic_write(LAPIC_ICR2, val)
28

29
#define	TMR_PERIODIC     0x20000
30
#define	TMR_BASEDIV      (1<<20)
31

32
static void udelay(int delay) {
33
	volatile int i;
34

35
	for (i = delay * 10; i != 0; i-- );
36
}
37

38
void lapic_send_init_ipi(uint32_t apic_id) {
39
	uint32_t val;
40

41
	val = (apic_id & 0xFF) << 24; /* Destination Field */
42
	lapic_write_icr2(val);
43

44
	/* since target cpu is not init yet, this ipi MUST in physical mode */
45
	val = LAPIC_ICR_DM_INIT; /* Delivery Mode: INIT */
46
	val |= LAPIC_ICR_INT_ASSERT; /* Level: Assert */
47
	val |= LAPIC_ICR_DEST_FIELD; /* Destination Shorthand: field specified*/
48
	val |= LAPIC_ICR_INIT_LEVELTRIG;/*triger level: set high level*/	
49
	lapic_write_icr1(val);
50

51
	udelay(10000);
52

53
	/* sleep until Delivery Status is Pending */
54
	while (lapic_read_icr1() & LAPIC_ICR_DELIVERY_PENDING);
55
}
56

57
void lapic_send_startup_ipi(uint32_t apic_id, uint32_t trampoline) {
58
	uint32_t val;
59

60
	val = (apic_id & 0xFF) << 24; /* Destination Field */
61
	lapic_write_icr2(val);
62

63
	/* since target cpu is not init yet, this ipi MUST in physical mode */
64
	val = (trampoline >> 12) & 0xFF; /* Vector Field */
65
	val |= LAPIC_ICR_DM_FIXED; /* Delivery Mode: FIXED */
66
	val |= LAPIC_ICR_DM_STARTUP; /* Delivery Mode: Start Up */
67
	val |= LAPIC_ICR_DEST_FIELD; /* Destination Shorthand: field specified*/
68
	lapic_write_icr1(val);
69

70
	udelay(1000);
71

72
	val = (trampoline >> 12) & 0xFF; /* Vector Field */
73
	val |= LAPIC_ICR_DM_FIXED; /* Delivery Mode: FIXED */
74
	val |= LAPIC_ICR_DM_STARTUP; /* Delivery Mode: Start Up */
75
	val |= LAPIC_ICR_DEST_FIELD; /* Destination Shorthand: field specified*/
76
	lapic_write_icr1(val);
77

78
	udelay(1000);
79

80
	/* sleep until Delivery Status is Pending */
81
	while (lapic_read_icr1() & LAPIC_ICR_DELIVERY_PENDING);
82
}
83

84
void lapic_send_ipi(unsigned int vector, unsigned int cpu, int type) {
85
	uint32_t icr1, icr2;
86

87
	while (lapic_read_icr1() & LAPIC_ICR_DELIVERY_PENDING) {
88
		panic("Not implemented\n");
89
	}
90

91
	/* Clear all ICR state */
92
	icr1 = icr2 = 0;
93

94
	switch (type) {
95
		case LAPIC_ICR_DEST_FIELD:
96
			lapic_write_icr2(icr2 |	(cpu << 24));
97
			lapic_write_icr1(icr1 |	type | LAPIC_ICR_LOGICAL_DEST | vector);
98
			break;
99
		case LAPIC_ICR_DEST_SELF:
100
			/* Do not care about the delivery mode */
101
			lapic_write_icr2(icr2);
102
			lapic_write_icr1(icr1 |	type | vector);
103
			break;
104
		case LAPIC_ICR_DEST_ALL:
105
			/* Do not care about the delivery mode */
106
			lapic_write_icr2(icr2);
107
			lapic_write_icr1(icr1 |	type | vector);
108
			break;
109
		case LAPIC_ICR_DEST_ALL_BUT_SELF:
110
			/* Do not care about the delivery mode */
111
			lapic_write_icr2(icr2);
112
			lapic_write_icr1(icr1 |	type | vector);
113
			break;
114
		default:
115
			panic("Unknown send ipi type request\n");
116
			break;
117
	}
118

119
}
120

121
static inline void lapic_enable_in_msr(void) {
122
#ifdef LAPIC_REGS_X86_H_ /* Needed only on x86 */
123
	uint32_t msr_hi, msr_lo;
124

125
	ia32_msr_read(IA32_APIC_BASE, &msr_lo, &msr_hi);
126
	msr_lo |= (1 << IA32_APIC_BASE_ENABLE_BIT);
127
	ia32_msr_write(IA32_APIC_BASE, msr_lo, msr_hi);
128
#endif /* LAPIC_REGS_X86_H_ */
129
}
130

131
int lapic_enable(void) {
132
	uint32_t val;
133

134
	lapic_enable_in_msr();
135

136
    /**
137
	 * Current Model is Flat Model of logical destination Mode
138
	 * 0xF in DFR is Flat Model, 0x0 in DFR is cluster Model
139
	 * ATTENTION: Flat Model limits the number of CPU to 8
140
	 */
141
	val = (0x1 << cpu_get_id()) << 24; /* logical APIC ID is specified in bit */
142
	lapic_write(LAPIC_LDR, val);
143
	val = (0xF << 28);
144
	lapic_write(LAPIC_DFR, val);
145

146
    /* Set the spurious interrupt vector register */
147
	val = lapic_read(LAPIC_SIVR);
148
	val |= 0x100;
149
	lapic_write(LAPIC_SIVR, val);
150

151
#if 0
152
	/* Clear error state register */
153
	lapic_errstatus();
154

155
	lapic_write(LAPIC_LVT_TR, LAPIC_DISABLE);
156
	lapic_write(LAPIC_LVT_PCR, LAPIC_NMI);
157
	lapic_write(LAPIC_LVT_LINT0, LAPIC_DISABLE);
158
	lapic_write(LAPIC_LVT_LINT1, LAPIC_DISABLE);
159
	lapic_write(LAPIC_TASKPRIOR, 0);
160
#endif
161

162
	return 0;
163
}
164

165
PERIPH_MEMORY_DEFINE(local_apic, LOCAL_APIC_DEF_ADDR, 0x1000);
166

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

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

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

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