aarch64.S 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #include <lkmc.h>
  2. .global _start
  3. _start:
  4. /* Make all CPUs except CPU0 sleep by default. */
  5. mrs x0, mpidr_el1
  6. ands x0, x0, 3
  7. bne lkmc_cpu_not_0
  8. /* Load the vector table. */
  9. ldr x0, =lkmc_vector_table
  10. msr vbar_el1, x0
  11. /* https://cirosantilli.com/linux-kernel-module-cheat#aarch64-baremetal-neon-setup */
  12. /* CPACR_EL1.FPEN */
  13. mov x1, 0x3 << 20
  14. /* CPACR_EL1.ZEN */
  15. orr x1, x1, 0x3 << 16
  16. msr cpacr_el1, x1
  17. isb
  18. /* Prepare the stack for main, mandatory for C code. */
  19. ldr x0, =lkmc_stack_top
  20. mov sp, x0
  21. /* https://cirosantilli.com/linux-kernel-module-cheat#magic-failure-string */
  22. adr x0, lkmc_baremetal_on_exit_callback
  23. bl on_exit
  24. /* Setup CLI arguments and run main. */
  25. ldr x0, =lkmc_argc
  26. ldr x0, [x0]
  27. ldr x1, =lkmc_argv
  28. bl main
  29. /* If main returns, exit. */
  30. bl exit
  31. LKMC_VECTOR_TABLE
  32. /* Default handler for exceptions. This is called after some basic
  33. * setup done on the initial handler. Since this is a weak symbol,
  34. * you can redefine it in your own example, and your definition
  35. * will take precedence. */
  36. LKMC_WEAK(lkmc_vector_trap_handler)
  37. ldr x0, =lkmc_vector_trap_handler_error_message
  38. bl puts
  39. bl abort
  40. lkmc_vector_trap_handler_error_message:
  41. .asciz "error: unexpected interrupt"
  42. /* Default action for CPUs besides the first one: sleep forever. */
  43. LKMC_WEAK(lkmc_cpu_not_0)
  44. wfe
  45. b lkmc_cpu_not_0