@@ -135,6 +135,8 @@ struct lapic_info {
135
135
};
136
136
137
137
static struct lapic_info lapic_info ;
138
+ static struct lapic_regs saved_lapic_regs ;
139
+ static union lapic_base_msr lapic_base_msr ;
138
140
139
141
static inline uint32_t read_lapic_reg32 (uint32_t offset )
140
142
{
@@ -180,8 +182,6 @@ static void map_lapic(void)
180
182
181
183
int early_init_lapic (void )
182
184
{
183
- union lapic_base_msr lapic_base_msr ;
184
-
185
185
/* Get local APIC base address */
186
186
lapic_base_msr .value = msr_read (MSR_IA32_APIC_BASE );
187
187
@@ -266,6 +266,56 @@ void save_lapic(struct lapic_regs *regs)
266
266
regs -> tdcr = read_lapic_reg32 (LAPIC_DIVIDE_CONFIGURATION_REGISTER );
267
267
}
268
268
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
+
269
319
int send_lapic_eoi (void )
270
320
{
271
321
write_lapic_reg32 (LAPIC_EOI_REGISTER , 0 );
0 commit comments