diff options
| -rw-r--r-- | arch/i386/kernel/efi.c | 89 |
1 files changed, 73 insertions, 16 deletions
diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c index b92c7f0a358a..8f9c624ace6f 100644 --- a/arch/i386/kernel/efi.c +++ b/arch/i386/kernel/efi.c | |||
| @@ -473,6 +473,70 @@ static inline void __init check_range_for_systab(efi_memory_desc_t *md) | |||
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | /* | 475 | /* |
| 476 | * Wrap all the virtual calls in a way that forces the parameters on the stack. | ||
| 477 | */ | ||
| 478 | |||
| 479 | #define efi_call_virt(f, args...) \ | ||
| 480 | ((efi_##f##_t __attribute__((regparm(0)))*)efi.systab->runtime->f)(args) | ||
| 481 | |||
| 482 | static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) | ||
| 483 | { | ||
| 484 | return efi_call_virt(get_time, tm, tc); | ||
| 485 | } | ||
| 486 | |||
| 487 | static efi_status_t virt_efi_set_time (efi_time_t *tm) | ||
| 488 | { | ||
| 489 | return efi_call_virt(set_time, tm); | ||
| 490 | } | ||
| 491 | |||
| 492 | static efi_status_t virt_efi_get_wakeup_time (efi_bool_t *enabled, | ||
| 493 | efi_bool_t *pending, | ||
| 494 | efi_time_t *tm) | ||
| 495 | { | ||
| 496 | return efi_call_virt(get_wakeup_time, enabled, pending, tm); | ||
| 497 | } | ||
| 498 | |||
| 499 | static efi_status_t virt_efi_set_wakeup_time (efi_bool_t enabled, | ||
| 500 | efi_time_t *tm) | ||
| 501 | { | ||
| 502 | return efi_call_virt(set_wakeup_time, enabled, tm); | ||
| 503 | } | ||
| 504 | |||
| 505 | static efi_status_t virt_efi_get_variable (efi_char16_t *name, | ||
| 506 | efi_guid_t *vendor, u32 *attr, | ||
| 507 | unsigned long *data_size, void *data) | ||
| 508 | { | ||
| 509 | return efi_call_virt(get_variable, name, vendor, attr, data_size, data); | ||
| 510 | } | ||
| 511 | |||
| 512 | static efi_status_t virt_efi_get_next_variable (unsigned long *name_size, | ||
| 513 | efi_char16_t *name, | ||
| 514 | efi_guid_t *vendor) | ||
| 515 | { | ||
| 516 | return efi_call_virt(get_next_variable, name_size, name, vendor); | ||
| 517 | } | ||
| 518 | |||
| 519 | static efi_status_t virt_efi_set_variable (efi_char16_t *name, | ||
| 520 | efi_guid_t *vendor, | ||
| 521 | unsigned long attr, | ||
| 522 | unsigned long data_size, void *data) | ||
| 523 | { | ||
| 524 | return efi_call_virt(set_variable, name, vendor, attr, data_size, data); | ||
| 525 | } | ||
| 526 | |||
| 527 | static efi_status_t virt_efi_get_next_high_mono_count (u32 *count) | ||
| 528 | { | ||
| 529 | return efi_call_virt(get_next_high_mono_count, count); | ||
| 530 | } | ||
| 531 | |||
| 532 | static void virt_efi_reset_system (int reset_type, efi_status_t status, | ||
| 533 | unsigned long data_size, | ||
| 534 | efi_char16_t *data) | ||
| 535 | { | ||
| 536 | efi_call_virt(reset_system, reset_type, status, data_size, data); | ||
| 537 | } | ||
| 538 | |||
| 539 | /* | ||
| 476 | * This function will switch the EFI runtime services to virtual mode. | 540 | * This function will switch the EFI runtime services to virtual mode. |
| 477 | * Essentially, look through the EFI memmap and map every region that | 541 | * Essentially, look through the EFI memmap and map every region that |
| 478 | * has the runtime attribute bit set in its memory descriptor and update | 542 | * has the runtime attribute bit set in its memory descriptor and update |
| @@ -525,22 +589,15 @@ void __init efi_enter_virtual_mode(void) | |||
| 525 | * pointers in the runtime service table to the new virtual addresses. | 589 | * pointers in the runtime service table to the new virtual addresses. |
| 526 | */ | 590 | */ |
| 527 | 591 | ||
| 528 | efi.get_time = (efi_get_time_t *) efi.systab->runtime->get_time; | 592 | efi.get_time = virt_efi_get_time; |
| 529 | efi.set_time = (efi_set_time_t *) efi.systab->runtime->set_time; | 593 | efi.set_time = virt_efi_set_time; |
| 530 | efi.get_wakeup_time = (efi_get_wakeup_time_t *) | 594 | efi.get_wakeup_time = virt_efi_get_wakeup_time; |
| 531 | efi.systab->runtime->get_wakeup_time; | 595 | efi.set_wakeup_time = virt_efi_set_wakeup_time; |
| 532 | efi.set_wakeup_time = (efi_set_wakeup_time_t *) | 596 | efi.get_variable = virt_efi_get_variable; |
| 533 | efi.systab->runtime->set_wakeup_time; | 597 | efi.get_next_variable = virt_efi_get_next_variable; |
| 534 | efi.get_variable = (efi_get_variable_t *) | 598 | efi.set_variable = virt_efi_set_variable; |
| 535 | efi.systab->runtime->get_variable; | 599 | efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; |
| 536 | efi.get_next_variable = (efi_get_next_variable_t *) | 600 | efi.reset_system = virt_efi_reset_system; |
| 537 | efi.systab->runtime->get_next_variable; | ||
| 538 | efi.set_variable = (efi_set_variable_t *) | ||
| 539 | efi.systab->runtime->set_variable; | ||
| 540 | efi.get_next_high_mono_count = (efi_get_next_high_mono_count_t *) | ||
| 541 | efi.systab->runtime->get_next_high_mono_count; | ||
| 542 | efi.reset_system = (efi_reset_system_t *) | ||
| 543 | efi.systab->runtime->reset_system; | ||
| 544 | } | 601 | } |
| 545 | 602 | ||
| 546 | void __init | 603 | void __init |
