boot.S 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * boot.S
  3. *
  4. * Boot code
  5. *
  6. * Copyright (C) 2020-2022 Sylvain Munaut <tnt@246tNt.com>
  7. * SPDX-License-Identifier: MIT
  8. */
  9. #define BOOT_DEBUG
  10. #ifndef FLASH_APP_ADDR
  11. #define FLASH_APP_ADDR 0x00100000
  12. #endif
  13. .equ UART_BASE, 0x82000000
  14. .section .text.start
  15. .global _start
  16. _start:
  17. #ifdef BOOT_DEBUG
  18. // Set UART divisor
  19. li a0, UART_BASE
  20. li a1, 23
  21. sw a1, 4(a0)
  22. #endif
  23. // Delay boot
  24. li t0, 0x01000000
  25. 1:
  26. addi t0, t0, -1
  27. bne t0, zero, 1b
  28. // SPI init
  29. jal spi_init
  30. // Print a test value to UART to ensure it's working
  31. li a0, 0xDEADBEEF
  32. jal print_hex
  33. // Setup reboot code
  34. li t0, 0x0002006f
  35. sw t0, 0(zero)
  36. // Jump to main code in flash
  37. li ra, (0x40000000 + FLASH_APP_ADDR)
  38. ret
  39. // ---------------------------------------------------------------------------
  40. // SPI code
  41. // ---------------------------------------------------------------------------
  42. .equ SPI_BASE, 0x80000000
  43. .equ SPI_CSR, 4 * 0x00
  44. .equ SPI_RF, 4 * 0x03
  45. spi_init:
  46. // Save return address
  47. // -------------------
  48. mv t6, ra
  49. // Flash QSPI enable
  50. // -----------------
  51. li t5, SPI_BASE
  52. // Request external control
  53. li t0, 0x00000004
  54. sw t0, SPI_CSR(t5)
  55. li t0, 0x00000002
  56. sw t0, SPI_CSR(t5)
  57. // Enable QSPI (0x38)
  58. li t0, 0x38000000
  59. sw t0, 0x40(t5)
  60. // Read and discard response
  61. lw t0, SPI_RF(t5)
  62. // Release external control
  63. li t0, 0x00000004
  64. sw t0, SPI_CSR(t5)
  65. // Flash QSPI config
  66. // -----------------
  67. // Request external control
  68. li t0, 0x00000004
  69. sw t0, SPI_CSR(t5)
  70. li t0, 0x00000002
  71. sw t0, SPI_CSR(t5)
  72. // Set QSPI parameters (dummy=6, wrap=64b)
  73. li t0, 0xc0230000
  74. sw t0, 0x74(t5)
  75. // Release external control
  76. li t0, 0x00000004
  77. sw t0, SPI_CSR(t5)
  78. // PSRAM init
  79. // ----------
  80. // Request external control
  81. li t0, 0x00000004
  82. sw t0, SPI_CSR(t5)
  83. li t0, 0x00000012
  84. sw t0, SPI_CSR(t5)
  85. // Enable QSPI (0x35)
  86. li t0, 0x35000000
  87. sw t0, 0x40(t5)
  88. // Read and discard response
  89. lw t0, SPI_RF(t5)
  90. // Release external control
  91. li t0, 0x00000004
  92. sw t0, SPI_CSR(t5)
  93. // Return
  94. // ------
  95. mv ra, t6
  96. ret
  97. // ---------------------------------------------------------------------------
  98. // Debug helpers
  99. // ---------------------------------------------------------------------------
  100. #ifdef BOOT_DEBUG
  101. // Agument in a0
  102. // Clobbers a0, t0-t3
  103. print_hex:
  104. li t0, UART_BASE
  105. li t1, 8
  106. la t2, hexchar
  107. 1:
  108. srli t3, a0, 28
  109. add t3, t3, t2
  110. lb t3, 0(t3)
  111. sw t3, 0(t0)
  112. slli a0, a0, 4
  113. addi t1, t1, -1
  114. bne zero, t1, 1b
  115. print_nl:
  116. li t0, UART_BASE
  117. li a0, '\r'
  118. sw a0, 0(t0)
  119. li a0, '\n'
  120. sw a0, 0(t0)
  121. ret
  122. hexchar:
  123. .ascii "0123456789abcdef"
  124. #endif