boot.S 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * boot.S
  3. *
  4. * Boot code
  5. *
  6. * Copyright (C) 2020 Sylvain Munaut <tnt@246tNt.com>
  7. *
  8. * Permission to use, copy, modify, and/or distribute this software for any
  9. * purpose with or without fee is hereby granted, provided that the above
  10. * copyright notice and this permission notice appear in all copies.
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  13. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  14. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  15. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  16. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  17. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  18. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  19. */
  20. #ifndef FLASH_APP_ADDR
  21. #define FLASH_APP_ADDR 0x00100000
  22. #endif
  23. #define BOOT_DEBUG
  24. .section .text.start
  25. .global _start
  26. _start:
  27. #ifdef BOOT_DEBUG
  28. // Set UART divisor
  29. li a0, 0x82000004
  30. li a1, 23
  31. sw a1, 0(a0)
  32. #endif
  33. // Delay boot
  34. li t0, 0x01000000
  35. 1:
  36. addi t0, t0, -1
  37. bne t0, zero, 1b
  38. // SPI init
  39. jal spi_init
  40. // Setup reboot code
  41. li t0, 0x0002006f
  42. sw t0, 0(zero)
  43. // Jump to main code in flash
  44. li ra, (0x40000000 + FLASH_APP_ADDR)
  45. ret
  46. .equ SPI_BASE, 0x80000000
  47. .equ SPI_CSR, 4 * 0x00
  48. .equ SPI_RF, 4 * 0x03
  49. spi_init:
  50. // Save return address
  51. // -------------------
  52. mv t6, ra
  53. // Flash QSPI enable
  54. // -----------------
  55. li t5, SPI_BASE
  56. // Request external control
  57. li t0, 0x00000004
  58. sw t0, SPI_CSR(t5)
  59. li t0, 0x00000002
  60. sw t0, SPI_CSR(t5)
  61. // Enable QSPI (0x38)
  62. li t0, 0x38000000
  63. sw t0, 0x40(t5)
  64. // Read and discard response
  65. lw t0, SPI_RF(t5)
  66. // Release external control
  67. li t0, 0x00000004
  68. sw t0, SPI_CSR(t5)
  69. // Flash QSPI config
  70. // -----------------
  71. // Request external control
  72. li t0, 0x00000004
  73. sw t0, SPI_CSR(t5)
  74. li t0, 0x00000002
  75. sw t0, SPI_CSR(t5)
  76. // Set QSPI parameters (dummy=6, wrap=64b)
  77. li t0, 0xc0230000
  78. sw t0, 0x74(t5)
  79. // Release external control
  80. li t0, 0x00000004
  81. sw t0, SPI_CSR(t5)
  82. // PSRAM init
  83. // ----------
  84. // Request external control
  85. li t0, 0x00000004
  86. sw t0, SPI_CSR(t5)
  87. li t0, 0x00000012
  88. sw t0, SPI_CSR(t5)
  89. // Enable QSPI (0x35)
  90. li t0, 0x35000000
  91. sw t0, 0x40(t5)
  92. // Read and discard response
  93. lw t0, SPI_RF(t5)
  94. // Release external control
  95. li t0, 0x00000004
  96. sw t0, SPI_CSR(t5)
  97. // Return
  98. // ------
  99. mv ra, t6
  100. ret
  101. #ifdef BOOT_DEBUG
  102. // Agument in a0
  103. // Clobbers a0, t0-t3
  104. print_hex:
  105. li t0, 0x82000000
  106. li t1, 8
  107. la t2, hexchar
  108. 1:
  109. srli t3, a0, 28
  110. add t3, t3, t2
  111. lb t3, 0(t3)
  112. sw t3, 0(t0)
  113. slli a0, a0, 4
  114. addi t1, t1, -1
  115. bne zero, t1, 1b
  116. print_nl:
  117. li t0, 0x82000000
  118. li a0, '\r'
  119. sw a0, 0(t0)
  120. li a0, '\n'
  121. sw a0, 0(t0)
  122. ret
  123. hexchar:
  124. .ascii "0123456789abcdef"
  125. #endif