boot.S 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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. // Setup reboot code
  31. li t0, 0x0002006f
  32. sw t0, 0(zero)
  33. // Jump to main code in flash
  34. li ra, (0x40000000 + FLASH_APP_ADDR)
  35. ret
  36. // ---------------------------------------------------------------------------
  37. // SPI code
  38. // ---------------------------------------------------------------------------
  39. .equ SPI_BASE, 0x80000000
  40. .equ SPI_CSR, 4 * 0x00
  41. .equ SPI_RF, 4 * 0x03
  42. spi_init:
  43. // Save return address
  44. // -------------------
  45. mv t6, ra
  46. // Flash QSPI enable
  47. // -----------------
  48. li t5, SPI_BASE
  49. // Request external control
  50. li t0, 0x00000004
  51. sw t0, SPI_CSR(t5)
  52. li t0, 0x00000002
  53. sw t0, SPI_CSR(t5)
  54. // Enable QSPI (0x38)
  55. li t0, 0x38000000
  56. sw t0, 0x40(t5)
  57. // Read and discard response
  58. lw t0, SPI_RF(t5)
  59. // Release external control
  60. li t0, 0x00000004
  61. sw t0, SPI_CSR(t5)
  62. // Flash QSPI config
  63. // -----------------
  64. // Request external control
  65. li t0, 0x00000004
  66. sw t0, SPI_CSR(t5)
  67. li t0, 0x00000002
  68. sw t0, SPI_CSR(t5)
  69. // Set QSPI parameters (dummy=6, wrap=64b)
  70. li t0, 0xc0230000
  71. sw t0, 0x74(t5)
  72. // Release external control
  73. li t0, 0x00000004
  74. sw t0, SPI_CSR(t5)
  75. // PSRAM init
  76. // ----------
  77. // Request external control
  78. li t0, 0x00000004
  79. sw t0, SPI_CSR(t5)
  80. li t0, 0x00000012
  81. sw t0, SPI_CSR(t5)
  82. // Enable QSPI (0x35)
  83. li t0, 0x35000000
  84. sw t0, 0x40(t5)
  85. // Read and discard response
  86. lw t0, SPI_RF(t5)
  87. // Release external control
  88. li t0, 0x00000004
  89. sw t0, SPI_CSR(t5)
  90. // Return
  91. // ------
  92. mv ra, t6
  93. ret
  94. // ---------------------------------------------------------------------------
  95. // Debug helpers
  96. // ---------------------------------------------------------------------------
  97. #ifdef BOOT_DEBUG
  98. // Agument in a0
  99. // Clobbers a0, t0-t3
  100. print_hex:
  101. li t0, UART_BASE
  102. li t1, 8
  103. la t2, hexchar
  104. 1:
  105. srli t3, a0, 28
  106. add t3, t3, t2
  107. lb t3, 0(t3)
  108. sw t3, 0(t0)
  109. slli a0, a0, 4
  110. addi t1, t1, -1
  111. bne zero, t1, 1b
  112. print_nl:
  113. li t0, UART_BASE
  114. li a0, '\r'
  115. sw a0, 0(t0)
  116. li a0, '\n'
  117. sw a0, 0(t0)
  118. ret
  119. hexchar:
  120. .ascii "0123456789abcdef"
  121. #endif