|
35 | 35 | #include <stdint.h> |
36 | 36 |
|
37 | 37 | #include <x86/common.h> |
| 38 | +#include <x86/gdt.h> |
38 | 39 |
|
39 | 40 | #define barrier() __asm__ __volatile__ ("":::"memory"); |
40 | 41 |
|
@@ -371,4 +372,89 @@ void x86_log_memory_load(uint32_t start, uint32_t end, const char *name) |
371 | 372 | { |
372 | 373 | wolfBoot_printf("mem: [ 0x%x, 0x%x ] - %s (0x%x) \n\r", start, end, name, end - start); |
373 | 374 | } |
| 375 | + |
| 376 | +#if !defined(BUILD_LOADER_STAGE1) |
| 377 | +int x86_run_fsp_32bit(void* api, void* arg) |
| 378 | +{ |
| 379 | + uint32_t status; |
| 380 | + __asm__ volatile ( |
| 381 | + /* arg on the stack, will be used as arg */ |
| 382 | + "mov %[arg], %%rax\n" |
| 383 | + "shl $32, %%rax\n" |
| 384 | + "or %[api], %%rax\n" |
| 385 | + "push %%rax\n" |
| 386 | + "push %[SEG_COMP]\n" |
| 387 | + "lea (1f), %%rax\n" |
| 388 | + "push %%rax\n" |
| 389 | + "retfq\n" |
| 390 | + "1:\n" |
| 391 | + /* we are now in compatibility mode */ |
| 392 | + ".code32\n" |
| 393 | + /* disable paging */ |
| 394 | + "mov %%cr0, %%eax\n" |
| 395 | + "mov %[PG], %%edx\n" |
| 396 | + "not %%edx\n" |
| 397 | + "and %%edx, %%eax\n" |
| 398 | + "mov %%eax, %%cr0\n" |
| 399 | + /* disable EFER.LME */ |
| 400 | + "mov $0xc0000080, %%ecx\n" |
| 401 | + "rdmsr\n" |
| 402 | + "mov %[LME], %%ecx\n" |
| 403 | + "not %%ecx\n" |
| 404 | + "and %%ecx, %%eax\n" |
| 405 | + "mov $0xc0000080, %%ecx\n" |
| 406 | + "wrmsr\n" |
| 407 | + /* disable PAE */ |
| 408 | + "mov %%cr4, %%eax\n" |
| 409 | + "mov %[PAE], %%edx\n" |
| 410 | + "not %%edx\n" |
| 411 | + "and %%edx, %%eax\n" |
| 412 | + "mov %%eax, %%cr4\n" |
| 413 | + /* get api from stack */ |
| 414 | + "pop %%eax\n" |
| 415 | + "call *%%eax\n" |
| 416 | + /* remove parameter from the stack */ |
| 417 | + "add $4, %%esp\n" |
| 418 | + /* save status to ebx */ |
| 419 | + "mov %%eax, %%ebx\n" |
| 420 | + /* enable PAE */ |
| 421 | + "mov %%cr4, %%eax\n" |
| 422 | + "or %[PAE], %%eax\n" |
| 423 | + "mov %%eax, %%cr4\n" |
| 424 | + /* enable EFER_LME */ |
| 425 | + "mov $0xc0000080, %%ecx\n" |
| 426 | + "rdmsr\n" |
| 427 | + "or %[LME], %%eax\n" |
| 428 | + "mov $0xc0000080, %%ecx\n" |
| 429 | + "wrmsr\n" |
| 430 | + /* setup far pointer on the stack */ |
| 431 | + "push %[SEG_LONG]\n" |
| 432 | + "push $2f\n" |
| 433 | + /* enable paging */ |
| 434 | + "mov %%cr0, %%eax\n" |
| 435 | + "or %[PG], %%eax\n" |
| 436 | + "mov %%eax, %%cr0\n" |
| 437 | + "retf\n" |
| 438 | + "2:\n" |
| 439 | + /* back in long mode */ |
| 440 | + ".code64\n" |
| 441 | + /* save status */ |
| 442 | + "mov %%ebx, %[status]\n" |
| 443 | + :[status]"=m"(status) |
| 444 | + :[SEG_COMP]"i"(GDT_CS_32BIT_COMPAT), |
| 445 | + [SEG_LONG]"i"(GDT_CS_64BIT), |
| 446 | + [PG]"i"(CR0_PG_BIT), |
| 447 | + [LME]"i"(IA32_EFER_LME), |
| 448 | + [PAE]"i"(CR4_PAE_BIT), |
| 449 | + [api]"r"(api), |
| 450 | + [arg]"r"(arg) |
| 451 | + : "rax", "rbx", "rcx", "rdx"); |
| 452 | + return status; |
| 453 | +} |
| 454 | +#else |
| 455 | +int x86_run_fsp_32bit(void* api, void* arg) |
| 456 | +{ |
| 457 | + return 0; |
| 458 | +} |
| 459 | +#endif /* !STAGE1 */ |
374 | 460 | #endif /* COMMON_H_ */ |
0 commit comments