8
8
#include <schedule.h>
9
9
#include <version.h>
10
10
11
+ #ifdef CONFIG_EFI_STUB
12
+ #include <acrn_efi.h>
13
+ #endif
14
+
11
15
spinlock_t trampline_spinlock = {
12
16
.head = 0 ,
13
17
.tail = 0
@@ -608,30 +612,66 @@ int cpu_find_logical_id(uint32_t lapic_id)
608
612
return -1 ;
609
613
}
610
614
611
- extern uint16_t trampline_fixup_cs [];
612
- extern uint16_t trampline_fixup_ip [];
613
- extern uint32_t trampline_fixup_target ;
614
- void prepare_trampline (void )
615
+ static void update_trampline_code_refs (uint64_t dest_pa )
615
616
{
617
+ void * ptr ;
616
618
uint64_t val ;
617
-
618
- /*Copy segment for AP initialization code below 1MB */
619
- memcpy_s (_ld_trampline_start ,
620
- (unsigned long )& _ld_trampline_size ,
621
- _ld_trampline_load ,
622
- (unsigned long )& _ld_trampline_size );
619
+ int i ;
623
620
624
621
/*
625
622
* calculate the fixup CS:IP according to fixup target address
626
623
* dynamically.
627
624
*
628
- * FIXME:
629
- * the val should be set to runtime address of trampline code
630
- * after trampline relocation is enabled.
625
+ * trampline code starts in real mode,
626
+ * so the target addres is HPA
631
627
*/
632
- val = (uint64_t ) & trampline_fixup_target ;
633
- trampline_fixup_cs [0 ] = (uint16_t )(val >> 4 ) & 0xFFFF ;
634
- trampline_fixup_ip [0 ] = (uint16_t )(val & 0xf );
628
+ val = dest_pa + (uint64_t )trampline_fixup_target ;
629
+
630
+ ptr = HPA2HVA (dest_pa + (uint64_t )trampline_fixup_cs );
631
+ * (uint16_t * )(ptr ) = (uint16_t )(val >> 4 ) & 0xFFFF ;
632
+
633
+ ptr = HPA2HVA (dest_pa + (uint64_t )trampline_fixup_ip );
634
+ * (uint16_t * )(ptr ) = (uint16_t )(val & 0xf );
635
+
636
+ /* Update temporary page tables */
637
+ ptr = HPA2HVA (dest_pa + (uint64_t )CPU_Boot_Page_Tables_ptr );
638
+ * (uint32_t * )(ptr ) += dest_pa ;
639
+
640
+ ptr = HPA2HVA (dest_pa + (uint64_t )CPU_Boot_Page_Tables_Start );
641
+ * (uint64_t * )(ptr ) += dest_pa ;
642
+
643
+ ptr = HPA2HVA (dest_pa + (uint64_t )trampline_pdpt_addr );
644
+ for (i = 0 ; i < 4 ; i ++ )
645
+ * (uint64_t * )(ptr + sizeof (uint64_t ) * i ) += dest_pa ;
646
+
647
+ /* update the gdt base pointer with relocated offset */
648
+ ptr = HPA2HVA (dest_pa + (uint64_t )trampline_gdt_ptr );
649
+ * (uint64_t * )(ptr + 2 ) += dest_pa ;
650
+
651
+ /* update trampline jump pointer with relocated offset */
652
+ ptr = HPA2HVA (dest_pa + (uint64_t )trampline_start64_fixup );
653
+ * (uint32_t * )ptr += dest_pa ;
654
+ }
655
+
656
+ static uint64_t prepare_trampline (void )
657
+ {
658
+ uint64_t size , dest_pa ;
659
+
660
+ size = (uint64_t )_ld_trampline_end - (uint64_t )trampline_start16 ;
661
+ #ifndef CONFIG_EFI_STUB
662
+ dest_pa = e820_alloc_low_memory (CONFIG_LOW_RAM_SIZE );
663
+ #else
664
+ dest_pa = (uint64_t )get_ap_trampline_buf ();
665
+ #endif
666
+
667
+ pr_dbg ("trampline code: %llx size %x" , dest_pa , size );
668
+
669
+ /* Copy segment for AP initialization code below 1MB */
670
+ memcpy_s (HPA2HVA (dest_pa ), size , _ld_trampline_load , size );
671
+ update_trampline_code_refs (dest_pa );
672
+ trampline_start16_paddr = dest_pa ;
673
+
674
+ return dest_pa ;
635
675
}
636
676
637
677
/*
@@ -641,8 +681,9 @@ void start_cpus()
641
681
{
642
682
uint32_t timeout ;
643
683
uint32_t expected_up ;
684
+ uint64_t startup_paddr ;
644
685
645
- prepare_trampline ();
686
+ startup_paddr = prepare_trampline ();
646
687
647
688
/* Set flag showing number of CPUs expected to be up to all
648
689
* cpus
@@ -651,7 +692,7 @@ void start_cpus()
651
692
652
693
/* Broadcast IPIs to all other CPUs */
653
694
send_startup_ipi (INTR_CPU_STARTUP_ALL_EX_SELF ,
654
- -1U , (( uint64_t ) trampline_start16 ) );
695
+ -1U , startup_paddr );
655
696
656
697
/* Wait until global count is equal to expected CPU up count or
657
698
* configured time-out has expired
0 commit comments