File indexing completed on 2025-05-11 08:24:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifndef _AMD64_APIC_H
0038 #define _AMD64_APIC_H
0039
0040 #include <rtems/score/basedefs.h>
0041
0042 #ifdef __cplusplus
0043 extern "C" {
0044 #endif
0045
0046
0047 #define APIC_BASE_MSR 0x1B
0048
0049 #define APIC_BASE_MSR_ENABLE 0x800
0050
0051 #define xAPIC_MAX_APIC_ID 0xFE
0052
0053
0054
0055
0056
0057 #define LAPIC_OFFSET(val) (val >> 2)
0058
0059 #define LAPIC_REGISTER_ID LAPIC_OFFSET(0x20)
0060 #define LAPIC_REGISTER_EOI LAPIC_OFFSET(0x0B0)
0061 #define LAPIC_REGISTER_SPURIOUS LAPIC_OFFSET(0x0F0)
0062 #define LAPIC_REGISTER_ICR_LOW LAPIC_OFFSET(0x300)
0063 #define LAPIC_REGISTER_ICR_HIGH LAPIC_OFFSET(0x310)
0064 #define LAPIC_REGISTER_LVT_TIMER LAPIC_OFFSET(0x320)
0065 #define LAPIC_REGISTER_TIMER_INITCNT LAPIC_OFFSET(0x380)
0066 #define LAPIC_REGISTER_TIMER_CURRCNT LAPIC_OFFSET(0x390)
0067 #define LAPIC_REGISTER_TIMER_DIV LAPIC_OFFSET(0x3E0)
0068
0069 #define LAPIC_LVT_MASK 0x10000
0070
0071 #define LAPIC_ICR_HIGH_MASK 0x00FFFFFF
0072 #define LAPIC_ICR_LOW_MASK 0xFFF32000
0073 #define LAPIC_ICR_DELIV_INIT 0x500
0074 #define LAPIC_ICR_DELIV_START 0x600
0075 #define LAPIC_ICR_DELIV_STAT_PEND 0x1000
0076 #define LAPIC_ICR_ASSERT 0x4000
0077 #define LAPIC_ICR_TRIG_LEVEL 0x8000
0078
0079 #define LAPIC_EOI_ACK 0
0080 #define LAPIC_SELECT_TMR_PERIODIC 0x20000
0081 #define LAPIC_SPURIOUS_ENABLE 0x100
0082
0083
0084 #define LAPIC_TIMER_NUM_CALIBRATIONS 5
0085
0086 #define LAPIC_TIMER_DIVIDE_VALUE 16
0087
0088 #define LAPIC_TIMER_SELECT_DIVIDER 3
0089
0090
0091 #define PIT_FREQUENCY 1193180
0092
0093
0094
0095
0096
0097 #define PIT_CALIBRATE_DIVIDER 20
0098 #define PIT_CALIBRATE_TICKS (PIT_FREQUENCY/PIT_CALIBRATE_DIVIDER)
0099
0100
0101
0102
0103
0104 RTEMS_STATIC_ASSERT(
0105 PIT_CALIBRATE_TICKS <= 0xffff,
0106 PIT_CALIBRATE_DIVIDER
0107 );
0108
0109
0110 #define PIT_PORT_CHAN0 0x40
0111 #define PIT_PORT_CHAN1 0x41
0112 #define PIT_PORT_CHAN2 0x42
0113
0114
0115
0116
0117 #define PIT_PORT_CHAN2_GATE 0x61
0118 #define PIT_CHAN2_TIMER_BIT 1
0119 #define PIT_CHAN2_SPEAKER_BIT 2
0120
0121 #define PIT_PORT_MCR 0x43
0122
0123
0124 #define PIT_SELECT_CHAN0 0b00000000
0125 #define PIT_SELECT_CHAN1 0b01000000
0126 #define PIT_SELECT_CHAN2 0b10000000
0127
0128
0129
0130
0131 #define PIT_SELECT_ACCESS_LOHI 0b00110000
0132 #define PIT_SELECT_ONE_SHOT_MODE 0b00000010
0133 #define PIT_SELECT_BINARY_MODE 0
0134
0135 #define PIT_CHAN2_ENABLE(chan2_value) \
0136 \
0137 chan2_value = (inport_byte(PIT_PORT_CHAN2_GATE) | PIT_CHAN2_TIMER_BIT) \
0138 & ~PIT_CHAN2_SPEAKER_BIT; \
0139 outport_byte(PIT_PORT_CHAN2_GATE, chan2_value); \
0140 \
0141 outport_byte( \
0142 PIT_PORT_MCR, \
0143 PIT_SELECT_CHAN2 | PIT_SELECT_ACCESS_LOHI | \
0144 PIT_SELECT_ONE_SHOT_MODE | PIT_SELECT_BINARY_MODE \
0145 ); \
0146
0147 #define PIT_CHAN2_WRITE_TICKS(pit_ticks) \
0148 \
0149 outport_byte(PIT_PORT_CHAN2, pit_ticks & 0xff); \
0150 stub_io_wait(); \
0151 outport_byte(PIT_PORT_CHAN2, (pit_ticks >> 8) & 0xff); \
0152
0153 #define PIT_CHAN2_START_DELAY(chan2_value) \
0154 \
0155 chan2_value &= ~PIT_CHAN2_TIMER_BIT; \
0156 outport_byte(PIT_PORT_CHAN2_GATE, chan2_value); \
0157 chan2_value |= PIT_CHAN2_TIMER_BIT; \
0158 outport_byte(PIT_PORT_CHAN2_GATE, chan2_value); \
0159
0160 #define PIT_CHAN2_WAIT_DELAY(pit_ticks) \
0161 do { \
0162 uint32_t curr_ticks = pit_ticks; \
0163 while ( curr_ticks <= pit_ticks ) { \
0164 \
0165 outport_byte(PIT_PORT_MCR, PIT_SELECT_CHAN2); \
0166 curr_ticks = inport_byte(PIT_PORT_CHAN2); \
0167 curr_ticks |= inport_byte(PIT_PORT_CHAN2) << 8; \
0168 } \
0169 } while(0); \
0170
0171 extern volatile uint32_t* amd64_lapic_base;
0172 extern uint8_t amd64_lapic_to_cpu_map[xAPIC_MAX_APIC_ID + 1];
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183 bool lapic_initialize(void);
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193 uint32_t lapic_timer_calc_ticks(uint64_t desired_freq_hz);
0194
0195
0196
0197
0198
0199
0200 void lapic_timer_enable(uint32_t reload_value);
0201
0202 #ifdef RTEMS_SMP
0203
0204
0205
0206
0207
0208 uint32_t lapic_get_num_of_procesors(void);
0209
0210
0211
0212
0213
0214
0215
0216 void lapic_send_ipi(uint32_t target_cpu_index, uint8_t isr_vector);
0217
0218
0219
0220
0221
0222
0223
0224 void lapic_start_ap(uint32_t cpu_index, uint8_t page_vector);
0225 #endif
0226
0227
0228
0229
0230
0231 uint8_t inline lapic_get_id(void)
0232 {
0233
0234 return amd64_lapic_base[LAPIC_REGISTER_ID]>>24;
0235 }
0236
0237
0238
0239
0240 void inline lapic_eoi(void)
0241 {
0242 amd64_lapic_base[LAPIC_REGISTER_EOI] = LAPIC_EOI_ACK;
0243 }
0244
0245 #ifdef __cplusplus
0246 }
0247 #endif
0248
0249 #endif