wakeup.S 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /*
  2. * Copyright (C) 2017, Bin Meng <bmeng.cn@gmail.com>
  3. *
  4. * From coreboot src/arch/x86/wakeup.S
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include <asm/acpi_s3.h>
  9. #include <asm/processor.h>
  10. #include <asm/processor-flags.h>
  11. #define RELOCATED(x) ((x) - __wakeup + WAKEUP_BASE)
  12. #define CODE_SEG (X86_GDT_ENTRY_16BIT_CS * X86_GDT_ENTRY_SIZE)
  13. #define DATA_SEG (X86_GDT_ENTRY_16BIT_DS * X86_GDT_ENTRY_SIZE)
  14. .code32
  15. .globl __wakeup
  16. __wakeup:
  17. /* First prepare the jmp to the resume vector */
  18. mov 0x4(%esp), %eax /* vector */
  19. /* last 4 bits of linear addr are taken as offset */
  20. andw $0x0f, %ax
  21. movw %ax, (__wakeup_offset)
  22. mov 0x4(%esp), %eax
  23. /* the rest is taken as segment */
  24. shr $4, %eax
  25. movw %ax, (__wakeup_segment)
  26. /* Activate the right segment descriptor real mode */
  27. ljmp $CODE_SEG, $RELOCATED(1f)
  28. 1:
  29. /* 16 bit code from here on... */
  30. .code16
  31. /*
  32. * Load the segment registers w/ properly configured segment
  33. * descriptors. They will retain these configurations (limits,
  34. * writability, etc.) once protected mode is turned off.
  35. */
  36. mov $DATA_SEG, %ax
  37. mov %ax, %ds
  38. mov %ax, %es
  39. mov %ax, %fs
  40. mov %ax, %gs
  41. mov %ax, %ss
  42. /* Turn off protection */
  43. movl %cr0, %eax
  44. andl $~X86_CR0_PE, %eax
  45. movl %eax, %cr0
  46. /* Now really going into real mode */
  47. ljmp $0, $RELOCATED(1f)
  48. 1:
  49. movw $0x0, %ax
  50. movw %ax, %ds
  51. movw %ax, %es
  52. movw %ax, %ss
  53. movw %ax, %fs
  54. movw %ax, %gs
  55. /*
  56. * This is a FAR JMP to the OS waking vector.
  57. * The C code changes the address to be correct.
  58. */
  59. .byte 0xea
  60. __wakeup_offset = RELOCATED(.)
  61. .word 0x0000
  62. __wakeup_segment = RELOCATED(.)
  63. .word 0x0000
  64. .globl __wakeup_size
  65. __wakeup_size:
  66. .long . - __wakeup