arm.S 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. #include <lkmc.h>
  2. .global _start
  3. _start:
  4. /* Make all CPUs except CPU0 sleep by default. */
  5. mrc p15, 0, r0, c0, c0, 5
  6. ands r0, r0, 3
  7. bne lkmc_cpu_not_0
  8. /* Prepare the stack for main, mandatory for C code. */
  9. ldr sp, =lkmc_stack_top
  10. /* Enable floating point.
  11. * Code copied from: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0409h/CHDEGGFF.html
  12. * Without this, SIMD operations such as vmov raise an exception.
  13. */
  14. mrc p15, 0, r0, c1, c0, 2 /* Read CPACR into r0 */
  15. orr r0, r0, 3 << 20 /* OR in User and Privileged access for CP10 */
  16. orr r0, r0, 3 << 22 /* OR in User and Privileged access for CP11 */
  17. bic r0, r0, 3 << 30 /* Clear ASEDIS/D32DIS if set */
  18. mcr p15, 0, r0, c1, c0, 2 /* Store new access permissions into CPACR */
  19. isb /* Ensure side-effect of CPACR is visible */
  20. mov r0, 1 << 30 /* Create value with FPEXC (bit 30) set in r0 */
  21. vmsr fpexc, r0 /* Enable VFP and SIMD extensions */
  22. /* https://cirosantilli.com/linux-kernel-module-cheat#magic-failure-string */
  23. ldr r0, =lkmc_baremetal_on_exit_callback
  24. bl on_exit
  25. /* Run main. */
  26. mov r0, 0
  27. #if 0
  28. /* Just turn CLI args off for now since not supported.
  29. * https://cirosantilli.com/linux-kernel-module-cheat#gem5-baremetal-arm-cli-args */
  30. ldr r0, =lkmc_argc
  31. ldr r0, [r0]
  32. ldr r1, =lkmc_argv
  33. #else
  34. /* Run main. */
  35. mov r0, 0
  36. #endif
  37. bl main
  38. /* If main returns, exit. */
  39. bl exit
  40. /* Default action for CPUs besides the first one: sleep forever. */
  41. LKMC_WEAK(lkmc_cpu_not_0)
  42. wfe
  43. b lkmc_cpu_not_0