mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2026-06-06 09:06:30 +00:00
hv: add fixup to trampline code
Now, trampline code is used by both AP start and BSP s3 resume. For s3 resume, ACPI (5.2.10 Firmware ACPI Control Structure (FACS). table 5-37) defines the real mode address should be set to: realmode address = CS(waking_vec >> 4): IP(wakeing_vec & 0x000F) But not all bootloader (like ABL) follow ACPI definition about the CS:IP setup before jump to trampline code for S3 resume. To handle all these cases, a long jmp is issued at very beginning of trampline code to fixup the CS:IP setup. After the fixup, the CS is set to: (waking_vect >> 4), the IP is set to: (the_address_ of_next_instruction_of_long_jmp & 0xF). Which is aligned with ACPI definition. Another thing is that we can't calculate the fixup CS and IP value. The reason is related with limitations of real mode (can't get current ip address without stack). So we calculate the CS and IP when preparing the trampline code. Signed-off-by: Zheng Gen <gen.zheng@intel.com> Signed-off-by: Yin Fengwei <fengwei.yin@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com> Acked-by: Eddie Dong <Eddie.dong@intel.com>
This commit is contained in:
@@ -606,6 +606,32 @@ int cpu_find_logical_id(uint32_t lapic_id)
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern uint16_t trampline_fixup_cs[];
|
||||
extern uint16_t trampline_fixup_ip[];
|
||||
extern uint32_t trampline_fixup_target;
|
||||
void prepare_trampline(void)
|
||||
{
|
||||
uint64_t val;
|
||||
|
||||
/*Copy segment for AP initialization code below 1MB */
|
||||
memcpy_s(_ld_trampline_start,
|
||||
(unsigned long)&_ld_trampline_size,
|
||||
_ld_trampline_load,
|
||||
(unsigned long)&_ld_trampline_size);
|
||||
|
||||
/*
|
||||
* calculate the fixup CS:IP according to fixup target address
|
||||
* dynamically.
|
||||
*
|
||||
* FIXME:
|
||||
* the val should be set to runtime address of trampline code
|
||||
* after trampline relocation is enabled.
|
||||
*/
|
||||
val = (uint64_t) &trampline_fixup_target;
|
||||
trampline_fixup_cs[0] = (uint16_t)(val >> 4) & 0xFFFF;
|
||||
trampline_fixup_ip[0] = (uint16_t)(val & 0xf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start all secondary CPUs.
|
||||
*/
|
||||
@@ -614,11 +640,7 @@ void start_cpus()
|
||||
uint32_t timeout;
|
||||
uint32_t expected_up;
|
||||
|
||||
/*Copy segment for AP initialization code below 1MB */
|
||||
memcpy_s(_ld_trampline_start,
|
||||
(unsigned long)&_ld_trampline_size,
|
||||
_ld_trampline_load,
|
||||
(unsigned long)&_ld_trampline_size);
|
||||
prepare_trampline();
|
||||
|
||||
/* Set flag showing number of CPUs expected to be up to all
|
||||
* cpus
|
||||
|
||||
Reference in New Issue
Block a user