relocate_kernel.S 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. * relocate_kernel.S - put the kernel image in place to boot
  3. * Copyright (C) 2002-2005 Eric Biederman <ebiederm@xmission.com>
  4. *
  5. * This source code is licensed under the GNU General Public License,
  6. * Version 2. See the file COPYING for more details.
  7. */
  8. #include <linux/linkage.h>
  9. /*
  10. * Must be relocatable PIC code callable as a C function, that once
  11. * it starts can not use the previous processes stack.
  12. */
  13. .globl relocate_new_kernel
  14. .code64
  15. relocate_new_kernel:
  16. /* %rdi page_list
  17. * %rsi reboot_code_buffer
  18. * %rdx start address
  19. * %rcx page_table
  20. * %r8 arg5
  21. * %r9 arg6
  22. */
  23. /* zero out flags, and disable interrupts */
  24. pushq $0
  25. popfq
  26. /* set a new stack at the bottom of our page... */
  27. lea 4096(%rsi), %rsp
  28. /* store the parameters back on the stack */
  29. pushq %rdx /* store the start address */
  30. /* Set cr0 to a known state:
  31. * 31 1 == Paging enabled
  32. * 18 0 == Alignment check disabled
  33. * 16 0 == Write protect disabled
  34. * 3 0 == No task switch
  35. * 2 0 == Don't do FP software emulation.
  36. * 0 1 == Proctected mode enabled
  37. */
  38. movq %cr0, %rax
  39. andq $~((1<<18)|(1<<16)|(1<<3)|(1<<2)), %rax
  40. orl $((1<<31)|(1<<0)), %eax
  41. movq %rax, %cr0
  42. /* Set cr4 to a known state:
  43. * 10 0 == xmm exceptions disabled
  44. * 9 0 == xmm registers instructions disabled
  45. * 8 0 == performance monitoring counter disabled
  46. * 7 0 == page global disabled
  47. * 6 0 == machine check exceptions disabled
  48. * 5 1 == physical address extension enabled
  49. * 4 0 == page size extensions disabled
  50. * 3 0 == Debug extensions disabled
  51. * 2 0 == Time stamp disable (disabled)
  52. * 1 0 == Protected mode virtual interrupts disabled
  53. * 0 0 == VME disabled
  54. */
  55. movq $((1<<5)), %rax
  56. movq %rax, %cr4
  57. jmp 1f
  58. 1:
  59. /* Switch to the identity mapped page tables,
  60. * and flush the TLB.
  61. */
  62. movq %rcx, %cr3
  63. /* Do the copies */
  64. movq %rdi, %rcx /* Put the page_list in %rcx */
  65. xorq %rdi, %rdi
  66. xorq %rsi, %rsi
  67. jmp 1f
  68. 0: /* top, read another word for the indirection page */
  69. movq (%rbx), %rcx
  70. addq $8, %rbx
  71. 1:
  72. testq $0x1, %rcx /* is it a destination page? */
  73. jz 2f
  74. movq %rcx, %rdi
  75. andq $0xfffffffffffff000, %rdi
  76. jmp 0b
  77. 2:
  78. testq $0x2, %rcx /* is it an indirection page? */
  79. jz 2f
  80. movq %rcx, %rbx
  81. andq $0xfffffffffffff000, %rbx
  82. jmp 0b
  83. 2:
  84. testq $0x4, %rcx /* is it the done indicator? */
  85. jz 2f
  86. jmp 3f
  87. 2:
  88. testq $0x8, %rcx /* is it the source indicator? */
  89. jz 0b /* Ignore it otherwise */
  90. movq %rcx, %rsi /* For ever source page do a copy */
  91. andq $0xfffffffffffff000, %rsi
  92. movq $512, %rcx
  93. rep ; movsq
  94. jmp 0b
  95. 3:
  96. /* To be certain of avoiding problems with self-modifying code
  97. * I need to execute a serializing instruction here.
  98. * So I flush the TLB by reloading %cr3 here, it's handy,
  99. * and not processor dependent.
  100. */
  101. movq %cr3, %rax
  102. movq %rax, %cr3
  103. /* set all of the registers to known values */
  104. /* leave %rsp alone */
  105. xorq %rax, %rax
  106. xorq %rbx, %rbx
  107. xorq %rcx, %rcx
  108. xorq %rdx, %rdx
  109. xorq %rsi, %rsi
  110. xorq %rdi, %rdi
  111. xorq %rbp, %rbp
  112. xorq %r8, %r8
  113. xorq %r9, %r9
  114. xorq %r10, %r9
  115. xorq %r11, %r11
  116. xorq %r12, %r12
  117. xorq %r13, %r13
  118. xorq %r14, %r14
  119. xorq %r15, %r15
  120. ret
  121. relocate_new_kernel_end:
  122. .globl relocate_new_kernel_size
  123. relocate_new_kernel_size:
  124. .quad relocate_new_kernel_end - relocate_new_kernel