wakeup.S 1.6 KB

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