mirror of https://github.com/wolfSSL/wolfBoot.git
x86: add wrapper to run 32bit code in 64bit long mode
parent
6358153372
commit
b8a81de965
|
@ -68,4 +68,5 @@ int cpuid_is_1gb_page_supported();
|
||||||
void switch_to_long_mode(uint64_t *entry, uint32_t page_table);
|
void switch_to_long_mode(uint64_t *entry, uint32_t page_table);
|
||||||
void x86_log_memory_load(uint32_t start, uint32_t end, const char *name);
|
void x86_log_memory_load(uint32_t start, uint32_t end, const char *name);
|
||||||
void hlt();
|
void hlt();
|
||||||
|
int x86_run_fsp_32bit(void* api, void* arg);
|
||||||
#endif /* COMMON_H */
|
#endif /* COMMON_H */
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <x86/common.h>
|
#include <x86/common.h>
|
||||||
|
#include <x86/gdt.h>
|
||||||
|
|
||||||
#define barrier() __asm__ __volatile__ ("":::"memory");
|
#define barrier() __asm__ __volatile__ ("":::"memory");
|
||||||
|
|
||||||
|
@ -371,4 +372,89 @@ void x86_log_memory_load(uint32_t start, uint32_t end, const char *name)
|
||||||
{
|
{
|
||||||
wolfBoot_printf("mem: [ 0x%x, 0x%x ] - %s (0x%x) \n\r", start, end, name, end - start);
|
wolfBoot_printf("mem: [ 0x%x, 0x%x ] - %s (0x%x) \n\r", start, end, name, end - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(BUILD_LOADER_STAGE1)
|
||||||
|
int x86_run_fsp_32bit(void* api, void* arg)
|
||||||
|
{
|
||||||
|
uint32_t status;
|
||||||
|
__asm__ volatile (
|
||||||
|
/* arg on the stack, will be used as arg */
|
||||||
|
"mov %[arg], %%rax\n"
|
||||||
|
"shl $32, %%rax\n"
|
||||||
|
"or %[api], %%rax\n"
|
||||||
|
"push %%rax\n"
|
||||||
|
"push %[SEG_COMP]\n"
|
||||||
|
"lea (1f), %%rax\n"
|
||||||
|
"push %%rax\n"
|
||||||
|
"retfq\n"
|
||||||
|
"1:\n"
|
||||||
|
/* we are now in compatibility mode */
|
||||||
|
".code32\n"
|
||||||
|
/* disable paging */
|
||||||
|
"mov %%cr0, %%eax\n"
|
||||||
|
"mov %[PG], %%edx\n"
|
||||||
|
"not %%edx\n"
|
||||||
|
"and %%edx, %%eax\n"
|
||||||
|
"mov %%eax, %%cr0\n"
|
||||||
|
/* disable EFER.LME */
|
||||||
|
"mov $0xc0000080, %%ecx\n"
|
||||||
|
"rdmsr\n"
|
||||||
|
"mov %[LME], %%ecx\n"
|
||||||
|
"not %%ecx\n"
|
||||||
|
"and %%ecx, %%eax\n"
|
||||||
|
"mov $0xc0000080, %%ecx\n"
|
||||||
|
"wrmsr\n"
|
||||||
|
/* disable PAE */
|
||||||
|
"mov %%cr4, %%eax\n"
|
||||||
|
"mov %[PAE], %%edx\n"
|
||||||
|
"not %%edx\n"
|
||||||
|
"and %%edx, %%eax\n"
|
||||||
|
"mov %%eax, %%cr4\n"
|
||||||
|
/* get api from stack */
|
||||||
|
"pop %%eax\n"
|
||||||
|
"call *%%eax\n"
|
||||||
|
/* remove parameter from the stack */
|
||||||
|
"add $4, %%esp\n"
|
||||||
|
/* save status to ebx */
|
||||||
|
"mov %%eax, %%ebx\n"
|
||||||
|
/* enable PAE */
|
||||||
|
"mov %%cr4, %%eax\n"
|
||||||
|
"or %[PAE], %%eax\n"
|
||||||
|
"mov %%eax, %%cr4\n"
|
||||||
|
/* enable EFER_LME */
|
||||||
|
"mov $0xc0000080, %%ecx\n"
|
||||||
|
"rdmsr\n"
|
||||||
|
"or %[LME], %%eax\n"
|
||||||
|
"mov $0xc0000080, %%ecx\n"
|
||||||
|
"wrmsr\n"
|
||||||
|
/* setup far pointer on the stack */
|
||||||
|
"push %[SEG_LONG]\n"
|
||||||
|
"push $2f\n"
|
||||||
|
/* enable paging */
|
||||||
|
"mov %%cr0, %%eax\n"
|
||||||
|
"or %[PG], %%eax\n"
|
||||||
|
"mov %%eax, %%cr0\n"
|
||||||
|
"retf\n"
|
||||||
|
"2:\n"
|
||||||
|
/* back in long mode */
|
||||||
|
".code64\n"
|
||||||
|
/* save status */
|
||||||
|
"mov %%ebx, %[status]\n"
|
||||||
|
:[status]"=m"(status)
|
||||||
|
:[SEG_COMP]"i"(GDT_CS_32BIT_COMPAT),
|
||||||
|
[SEG_LONG]"i"(GDT_CS_64BIT),
|
||||||
|
[PG]"i"(CR0_PG_BIT),
|
||||||
|
[LME]"i"(IA32_EFER_LME),
|
||||||
|
[PAE]"i"(CR4_PAE_BIT),
|
||||||
|
[api]"r"(api),
|
||||||
|
[arg]"r"(arg)
|
||||||
|
: "rax", "rbx", "rcx", "rdx");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int x86_run_fsp_32bit(void* api, void* arg)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* !STAGE1 */
|
||||||
#endif /* COMMON_H_ */
|
#endif /* COMMON_H_ */
|
||||||
|
|
Loading…
Reference in New Issue