1 /*
2  * Copyright (C) 2018-2022 Intel Corporation.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef ARCH_X86_LAPIC_H
8 #define ARCH_X86_LAPIC_H
9 
10 #include <types.h>
11 
12 /* x2APIC Interrupt Command Register (ICR) structure */
13 union apic_icr {
14 	uint64_t value;
15 	struct {
16 		uint32_t lo_32;
17 		uint32_t hi_32;
18 	} value_32;
19 	struct {
20 		uint32_t vector:8;
21 		uint32_t delivery_mode:3;
22 		uint32_t destination_mode:1;
23 		uint32_t rsvd_1:2;
24 		uint32_t level:1;
25 		uint32_t trigger_mode:1;
26 		uint32_t rsvd_2:2;
27 		uint32_t shorthand:2;
28 		uint32_t rsvd_3:12;
29 		uint32_t dest_field:32;
30 	} bits;
31 };
32 
33 /**
34  * @defgroup lapic_ext_apis LAPIC External Interfaces
35  *
36  * This is a group that includes LAPIC External Interfaces.
37  *
38  * @{
39  */
40 
41 /**
42  * @brief Enable LAPIC in x2APIC mode
43  *
44  * Enable LAPIC in x2APIC mode via MSR writes.
45  *
46  */
47 void early_init_lapic(void);
48 
49 /**
50  * @brief Suspend LAPIC
51  *
52  * Suspend LAPIC by getting the APIC base addr and saving the registers.
53  */
54 void suspend_lapic(void);
55 
56 /**
57  * @brief Resume LAPIC
58  *
59  * Resume LAPIC by setting the APIC base addr and restoring the registers.
60  */
61 void resume_lapic(void);
62 
63 /**
64  * @brief Get the LAPIC ID
65  *
66  * Get the LAPIC ID via MSR read.
67  *
68  * @return LAPIC ID
69  */
70 uint32_t get_cur_lapic_id(void);
71 
72 /**
73  * @}
74  */
75 /* End of lapic_ext_apis */
76 
77 void init_lapic(uint16_t pcpu_id);
78 void send_lapic_eoi(void);
79 
80 /**
81  * @defgroup ipi_ext_apis IPI External Interfaces
82  *
83  * This is a group that includes IPI External Interfaces.
84  *
85  * @{
86  */
87 
88 /**
89  * @brief Send an SIPI to a specific cpu
90  *
91  * Send an Startup IPI to a specific cpu, to notify the cpu to start booting.
92  *
93  * @param[in]	dest_pcpu_id The id of destination physical cpu
94  * @param[in]	cpu_startup_start_address The address for the dest pCPU to start running
95  *
96  */
97 void send_startup_ipi(uint16_t dest_pcpu_id, uint64_t cpu_startup_start_address);
98 
99 /**
100  * @brief Send an IPI to multiple pCPUs
101  *
102  * @param[in]	dest_mask The mask of destination physical cpus
103  * @param[in]	vector The vector of interrupt
104  */
105 void send_dest_ipi_mask(uint32_t dest_mask, uint32_t vector);
106 
107 /**
108  * @brief Send an IPI to a single pCPU
109  *
110  * @param[in]	pcpu_id The id of destination physical cpu
111  * @param[in]	vector The vector of interrupt
112  */
113 void send_single_ipi(uint16_t pcpu_id, uint32_t vector);
114 
115 /**
116  * @}
117  */
118 /* End of ipi_ext_apis */
119 
120 /**
121  * @brief Send an INIT signal to a single pCPU
122  *
123  * @param[in] pcpu_id The id of destination physical cpu
124  */
125 void send_single_init(uint16_t pcpu_id);
126 
127 void kick_pcpu(uint16_t pcpu_id);
128 
129 #endif /* ARCH_X86_LAPIC_H */
130