xo1-wakeup.S 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. .text
  3. #include <linux/linkage.h>
  4. #include <asm/segment.h>
  5. #include <asm/page.h>
  6. #include <asm/pgtable_32.h>
  7. .macro writepost,value
  8. movb $0x34, %al
  9. outb %al, $0x70
  10. movb $\value, %al
  11. outb %al, $0x71
  12. .endm
  13. wakeup_start:
  14. # OFW lands us here, running in protected mode, with a
  15. # kernel-compatible GDT already setup.
  16. # Clear any dangerous flags
  17. pushl $0
  18. popfl
  19. writepost 0x31
  20. # Set up %cr3
  21. movl $initial_page_table - __PAGE_OFFSET, %eax
  22. movl %eax, %cr3
  23. movl saved_cr4, %eax
  24. movl %eax, %cr4
  25. movl saved_cr0, %eax
  26. movl %eax, %cr0
  27. # Control registers were modified, pipeline resync is needed
  28. jmp 1f
  29. 1:
  30. movw $__KERNEL_DS, %ax
  31. movw %ax, %ss
  32. movw %ax, %ds
  33. movw %ax, %es
  34. movw %ax, %fs
  35. movw %ax, %gs
  36. lgdt saved_gdt
  37. lidt saved_idt
  38. lldt saved_ldt
  39. ljmp $(__KERNEL_CS),$1f
  40. 1:
  41. movl %cr3, %eax
  42. movl %eax, %cr3
  43. wbinvd
  44. # Go back to the return point
  45. jmp ret_point
  46. save_registers:
  47. sgdt saved_gdt
  48. sidt saved_idt
  49. sldt saved_ldt
  50. pushl %edx
  51. movl %cr4, %edx
  52. movl %edx, saved_cr4
  53. movl %cr0, %edx
  54. movl %edx, saved_cr0
  55. popl %edx
  56. movl %ebx, saved_context_ebx
  57. movl %ebp, saved_context_ebp
  58. movl %esi, saved_context_esi
  59. movl %edi, saved_context_edi
  60. pushfl
  61. popl saved_context_eflags
  62. RET
  63. restore_registers:
  64. movl saved_context_ebp, %ebp
  65. movl saved_context_ebx, %ebx
  66. movl saved_context_esi, %esi
  67. movl saved_context_edi, %edi
  68. pushl saved_context_eflags
  69. popfl
  70. RET
  71. SYM_CODE_START(do_olpc_suspend_lowlevel)
  72. call save_processor_state
  73. call save_registers
  74. # This is the stack context we want to remember
  75. movl %esp, saved_context_esp
  76. pushl $3
  77. call xo1_do_sleep
  78. jmp wakeup_start
  79. .p2align 4,,7
  80. ret_point:
  81. movl saved_context_esp, %esp
  82. writepost 0x32
  83. call restore_registers
  84. call restore_processor_state
  85. RET
  86. SYM_CODE_END(do_olpc_suspend_lowlevel)
  87. .data
  88. saved_gdt: .long 0,0
  89. saved_idt: .long 0,0
  90. saved_ldt: .long 0
  91. saved_cr4: .long 0
  92. saved_cr0: .long 0
  93. saved_context_esp: .long 0
  94. saved_context_edi: .long 0
  95. saved_context_esi: .long 0
  96. saved_context_ebx: .long 0
  97. saved_context_ebp: .long 0
  98. saved_context_eflags: .long 0