RTEMS
6.3
Toggle main menu visibility
Loading...
Searching...
No Matches
bsps
x86_64
amd64
include
apic.h
Go to the documentation of this file.
1
/* SPDX-License-Identifier: BSD-2-Clause */
2
10
11
/*
12
* Copyright (C) 2024 Matheus Pecoraro
13
* Copyright (c) 2018 Amaan Cheval <amaan.cheval@gmail.com>
14
*
15
* Redistribution and use in source and binary forms, with or without
16
* modification, are permitted provided that the following conditions
17
* are met:
18
* 1. Redistributions of source code must retain the above copyright
19
* notice, this list of conditions and the following disclaimer.
20
* 2. Redistributions in binary form must reproduce the above copyright
21
* notice, this list of conditions and the following disclaimer in the
22
* documentation and/or other materials provided with the distribution.
23
*
24
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
25
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
28
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34
* SUCH DAMAGE.
35
*/
36
37
#ifndef _AMD64_APIC_H
38
#define _AMD64_APIC_H
39
40
#include <
rtems/score/basedefs.h
>
41
42
#ifdef __cplusplus
43
extern
"C"
{
44
#endif
45
46
/* The address of the MSR pointing to the APIC base physical address */
47
#define APIC_BASE_MSR 0x1B
48
/* Value to hardware-enable the APIC through the APIC_BASE_MSR */
49
#define APIC_BASE_MSR_ENABLE 0x800
50
51
#define xAPIC_MAX_APIC_ID 0xFE
52
53
/*
54
* Since the LAPIC registers are contained in an array of 32-bit elements
55
* these byte-offsets need to be divided by 4 to index the array.
56
*/
57
#define LAPIC_OFFSET(val) (val >> 2)
58
59
#define LAPIC_REGISTER_ID LAPIC_OFFSET(0x20)
60
#define LAPIC_REGISTER_EOI LAPIC_OFFSET(0x0B0)
61
#define LAPIC_REGISTER_SPURIOUS LAPIC_OFFSET(0x0F0)
62
#define LAPIC_REGISTER_ICR_LOW LAPIC_OFFSET(0x300)
63
#define LAPIC_REGISTER_ICR_HIGH LAPIC_OFFSET(0x310)
64
#define LAPIC_REGISTER_LVT_TIMER LAPIC_OFFSET(0x320)
65
#define LAPIC_REGISTER_TIMER_INITCNT LAPIC_OFFSET(0x380)
66
#define LAPIC_REGISTER_TIMER_CURRCNT LAPIC_OFFSET(0x390)
67
#define LAPIC_REGISTER_TIMER_DIV LAPIC_OFFSET(0x3E0)
68
69
#define LAPIC_LVT_MASK 0x10000
70
71
#define LAPIC_ICR_HIGH_MASK 0x00FFFFFF
72
#define LAPIC_ICR_LOW_MASK 0xFFF32000
73
#define LAPIC_ICR_DELIV_INIT 0x500
74
#define LAPIC_ICR_DELIV_START 0x600
75
#define LAPIC_ICR_DELIV_STAT_PEND 0x1000
76
#define LAPIC_ICR_ASSERT 0x4000
77
#define LAPIC_ICR_TRIG_LEVEL 0x8000
78
79
#define LAPIC_EOI_ACK 0
80
#define LAPIC_SELECT_TMR_PERIODIC 0x20000
81
#define LAPIC_SPURIOUS_ENABLE 0x100
82
83
/* Number of times to calibrate the LAPIC timer to average it out */
84
#define LAPIC_TIMER_NUM_CALIBRATIONS 5
85
/* Default divide value used by LAPIC timer */
86
#define LAPIC_TIMER_DIVIDE_VALUE 16
87
/* Value to set in register to pick the divide value above */
88
#define LAPIC_TIMER_SELECT_DIVIDER 3
89
90
/* PIT defines and macros used when calibrating the LAPIC timer and starting APs */
91
#define PIT_FREQUENCY 1193180
92
/*
93
* The PIT_FREQUENCY determines how many times the PIT counter is decremented
94
* per second - therefore, we can calculate how many ticks we set based on what
95
* fraction of a second we're okay with spending on calibration
96
*/
97
#define PIT_CALIBRATE_DIVIDER 20
98
#define PIT_CALIBRATE_TICKS (PIT_FREQUENCY/PIT_CALIBRATE_DIVIDER)
99
/*
100
* Since the PIT only has 2 one-byte registers, the maximum tick value is
101
* limited to 16-bits. We can set the PIT to use a frequency divider if
102
* needed.
103
*/
104
RTEMS_STATIC_ASSERT
(
105
PIT_CALIBRATE_TICKS <= 0xffff,
106
PIT_CALIBRATE_DIVIDER
107
);
108
109
/* I/O ports for the PIT */
110
#define PIT_PORT_CHAN0 0x40
111
#define PIT_PORT_CHAN1 0x41
112
#define PIT_PORT_CHAN2 0x42
113
/*
114
* The input to channel 2 can be gated through software, using bit 0 of port
115
* 0x61.
116
*/
117
#define PIT_PORT_CHAN2_GATE 0x61
118
#define PIT_CHAN2_TIMER_BIT 1
119
#define PIT_CHAN2_SPEAKER_BIT 2
120
/* The PIT mode/command register */
121
#define PIT_PORT_MCR 0x43
122
123
/* PIT values to select channels, access, and operating modes */
124
#define PIT_SELECT_CHAN0 0b00000000
125
#define PIT_SELECT_CHAN1 0b01000000
126
#define PIT_SELECT_CHAN2 0b10000000
127
/*
128
* In the lo/hi mode, the low-byte is sent to the data port, followed by the
129
* high-byte; this makes it important that this be an atomic operation.
130
*/
131
#define PIT_SELECT_ACCESS_LOHI 0b00110000
132
#define PIT_SELECT_ONE_SHOT_MODE 0b00000010
133
#define PIT_SELECT_BINARY_MODE 0
134
135
#define PIT_CHAN2_ENABLE(chan2_value) \
136
/* Enable the channel 2 timer gate and disable the speaker output */
\
137
chan2_value = (inport_byte(PIT_PORT_CHAN2_GATE) | PIT_CHAN2_TIMER_BIT) \
138
& ~PIT_CHAN2_SPEAKER_BIT; \
139
outport_byte(PIT_PORT_CHAN2_GATE, chan2_value); \
140
/* Initialize PIT in one-shot mode on Channel 2 */
\
141
outport_byte( \
142
PIT_PORT_MCR, \
143
PIT_SELECT_CHAN2 | PIT_SELECT_ACCESS_LOHI | \
144
PIT_SELECT_ONE_SHOT_MODE | PIT_SELECT_BINARY_MODE \
145
); \
146
147
#define PIT_CHAN2_WRITE_TICKS(pit_ticks) \
148
/* Set PIT reload value */
\
149
outport_byte(PIT_PORT_CHAN2, pit_ticks & 0xff); \
150
stub_io_wait(); \
151
outport_byte(PIT_PORT_CHAN2, (pit_ticks >> 8) & 0xff); \
152
153
#define PIT_CHAN2_START_DELAY(chan2_value) \
154
/* Restart PIT by disabling the gated input and then re-enabling it */
\
155
chan2_value &= ~PIT_CHAN2_TIMER_BIT; \
156
outport_byte(PIT_PORT_CHAN2_GATE, chan2_value); \
157
chan2_value |= PIT_CHAN2_TIMER_BIT; \
158
outport_byte(PIT_PORT_CHAN2_GATE, chan2_value); \
159
160
#define PIT_CHAN2_WAIT_DELAY(pit_ticks) \
161
do { \
162
uint32_t curr_ticks = pit_ticks; \
163
while ( curr_ticks <= pit_ticks ) { \
164
/* Send latch command to read multi-byte value atomically */
\
165
outport_byte(PIT_PORT_MCR, PIT_SELECT_CHAN2); \
166
curr_ticks = inport_byte(PIT_PORT_CHAN2); \
167
curr_ticks |= inport_byte(PIT_PORT_CHAN2) << 8; \
168
} \
169
} while(0); \
170
171
extern
volatile
uint32_t* amd64_lapic_base;
172
extern
uint8_t amd64_lapic_to_cpu_map[xAPIC_MAX_APIC_ID + 1];
173
183
bool
lapic_initialize
(
void
);
184
193
uint32_t
lapic_timer_calc_ticks
(uint64_t desired_freq_hz);
194
200
void
lapic_timer_enable
(uint32_t reload_value);
201
202
#ifdef RTEMS_SMP
208
uint32_t lapic_get_num_of_procesors(
void
);
209
216
void
lapic_send_ipi(uint32_t target_cpu_index, uint8_t
isr_vector
);
217
224
void
lapic_start_ap(uint32_t cpu_index, uint8_t page_vector);
225
#endif
226
231
uint8_t
inline
lapic_get_id
(
void
)
232
{
233
/* ID stored in highest 8 bits */
234
return
amd64_lapic_base[LAPIC_REGISTER_ID]>>24;
235
}
236
240
void
inline
lapic_eoi
(
void
)
241
{
242
amd64_lapic_base[LAPIC_REGISTER_EOI] = LAPIC_EOI_ACK;
243
}
244
245
#ifdef __cplusplus
246
}
247
#endif
248
249
#endif
/* _AMD64_APIC_H */
basedefs.h
This header file provides basic definitions used by the API and the implementation.
isr_vector
lpc176x_can_isr_vector isr_vector
Vector of isr for the can_driver .
Definition
can.c:37
RTEMS_STATIC_ASSERT
#define RTEMS_STATIC_ASSERT(_cond, _msg)
It is defined if a static analysis run is performed.
Definition
basedefs.h:841
lapic_eoi
void lapic_eoi(void)
Signals an end of interrupt to the Local APIC.
Definition
apic.h:240
lapic_get_id
uint8_t lapic_get_id(void)
Retrieves the Local APIC ID.
Definition
apic.h:231
lapic_initialize
bool lapic_initialize(void)
Initializes the Local APIC by hardware and software enabling it.
Definition
apic.c:228
lapic_timer_enable
void lapic_timer_enable(uint32_t reload_value)
Enables the Local APIC timer.
Definition
apic.c:305
lapic_timer_calc_ticks
uint32_t lapic_timer_calc_ticks(uint64_t desired_freq_hz)
Calculates the number of Local APIC timer ticks which can be used with lapic_timer_enable to set up a...
Definition
apic.c:283
Generated by
1.18.0