Skip to content

Commit ddd03d6

Browse files
fyin1lijinxia
authored andcommitted
hv: add suspend/resume callback for lapic.
They will be called when acrn enter S3. NOTE: it's only needed for native BSP because all APs are offline. Signed-off-by: Zheng Gen <gen.zheng@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent a06f2d6 commit ddd03d6

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

hypervisor/arch/x86/intr_lapic.c

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ struct lapic_info {
135135
};
136136

137137
static struct lapic_info lapic_info;
138+
static struct lapic_regs saved_lapic_regs;
139+
static union lapic_base_msr lapic_base_msr;
138140

139141
static inline uint32_t read_lapic_reg32(uint32_t offset)
140142
{
@@ -180,8 +182,6 @@ static void map_lapic(void)
180182

181183
int early_init_lapic(void)
182184
{
183-
union lapic_base_msr lapic_base_msr;
184-
185185
/* Get local APIC base address */
186186
lapic_base_msr.value = msr_read(MSR_IA32_APIC_BASE);
187187

@@ -266,6 +266,56 @@ void save_lapic(struct lapic_regs *regs)
266266
regs->tdcr = read_lapic_reg32(LAPIC_DIVIDE_CONFIGURATION_REGISTER);
267267
}
268268

269+
static void restore_lapic(struct lapic_regs *regs)
270+
{
271+
write_lapic_reg32(LAPIC_ID_REGISTER, regs->id);
272+
write_lapic_reg32(LAPIC_TASK_PRIORITY_REGISTER, regs->tpr);
273+
write_lapic_reg32(LAPIC_LOGICAL_DESTINATION_REGISTER, regs->ldr );
274+
write_lapic_reg32(LAPIC_DESTINATION_FORMAT_REGISTER, regs->dfr );
275+
write_lapic_reg32(LAPIC_SPURIOUS_VECTOR_REGISTER, regs->svr );
276+
write_lapic_reg32(LAPIC_LVT_TIMER_REGISTER, regs->lvtt );
277+
278+
write_lapic_reg32(LAPIC_LVT_LINT0_REGISTER, regs->lvt0 );
279+
write_lapic_reg32(LAPIC_LVT_LINT1_REGISTER, regs->lvt1 );
280+
281+
write_lapic_reg32(LAPIC_LVT_ERROR_REGISTER, regs->lvterr );
282+
write_lapic_reg32(LAPIC_INITIAL_COUNT_REGISTER, regs->ticr );
283+
write_lapic_reg32(LAPIC_DIVIDE_CONFIGURATION_REGISTER, regs->tdcr );
284+
285+
286+
write_lapic_reg32(LAPIC_ARBITRATION_PRIORITY_REGISTER, regs->apr );
287+
write_lapic_reg32(LAPIC_PROCESSOR_PRIORITY_REGISTER, regs->ppr );
288+
write_lapic_reg32(LAPIC_TRIGGER_MODE_REGISTER_0, regs->tmr[0] );
289+
write_lapic_reg32(LAPIC_TRIGGER_MODE_REGISTER_1, regs->tmr[1] );
290+
write_lapic_reg32(LAPIC_TRIGGER_MODE_REGISTER_2, regs->tmr[2] );
291+
write_lapic_reg32(LAPIC_TRIGGER_MODE_REGISTER_3, regs->tmr[3] );
292+
write_lapic_reg32(LAPIC_TRIGGER_MODE_REGISTER_4, regs->tmr[4] );
293+
write_lapic_reg32(LAPIC_TRIGGER_MODE_REGISTER_5, regs->tmr[5] );
294+
write_lapic_reg32(LAPIC_TRIGGER_MODE_REGISTER_6, regs->tmr[6] );
295+
write_lapic_reg32(LAPIC_TRIGGER_MODE_REGISTER_7, regs->tmr[7] );
296+
write_lapic_reg32(LAPIC_CURRENT_COUNT_REGISTER, regs->tccr );
297+
}
298+
299+
void suspend_lapic(void)
300+
{
301+
uint32_t val = 0;
302+
303+
save_lapic(&saved_lapic_regs);
304+
305+
/* disable APIC with software flag */
306+
val = read_lapic_reg32(LAPIC_SPURIOUS_VECTOR_REGISTER);
307+
write_lapic_reg32(LAPIC_SPURIOUS_VECTOR_REGISTER,
308+
(~LAPIC_SVR_APIC_ENABLE_MASK) & val);
309+
}
310+
311+
void resume_lapic(void)
312+
{
313+
msr_write(MSR_IA32_APIC_BASE, lapic_base_msr.value);
314+
315+
/* ACPI software flag will be restored also */
316+
restore_lapic(&saved_lapic_regs);
317+
}
318+
269319
int send_lapic_eoi(void)
270320
{
271321
write_lapic_reg32(LAPIC_EOI_REGISTER, 0);

hypervisor/include/arch/x86/lapic.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,4 +167,7 @@ int send_startup_ipi(enum intr_cpu_startup_shorthand cpu_startup_shorthand,
167167
/* API to send an IPI to a single guest */
168168
void send_single_ipi(uint32_t pcpu_id, uint32_t vector);
169169

170+
void suspend_lapic(void);
171+
void resume_lapic(void);
172+
170173
#endif /* INTR_LAPIC_H */

0 commit comments

Comments
 (0)