commit 4bd1aedd867266f7f05e28b8edbba3ceac9b6d62
parent e4552941012ea76bbfebbcd9d88f18c40287650b
Author: Matsuda Kenji <info@mtkn.jp>
Date: Fri, 14 Apr 2023 11:50:54 +0900
make something which doesn't work
Diffstat:
A | boot2_sram.s | | | 152 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | mach.s | | | 61 | ++++++++++++++++++++++++++++++------------------------------- |
2 files changed, 182 insertions(+), 31 deletions(-)
diff --git a/boot2_sram.s b/boot2_sram.s
@@ -0,0 +1,152 @@
+// Copyright (c) 2019-2021 Raspberry Pi (Trading) Ltd.
+// SPDX-License-Identifier: BSD-3-Clause
+
+.cpu cortex-m0plus
+.thumb
+
+ .section .boot2
+ .global setup_ssi
+ .thumb_func
+setup_ssi:
+ push {r4, r5, r6, r7, lr}
+
+ // setup QSPI pad
+ ldr r4, pads_qspi_base
+ ldr r1, =(0 << 4 | 0 << 1 | 1) // 2mA, schmitt off, slew fast
+ str r1, [r4, #0x4] // PADS_QSPI: GPIO_QSPI_SCLK
+
+ // r4 should not be changed from this point on
+ ldr r4, xip_ssi_base
+
+ // set SSI standard SPI
+ // disable SSI
+ mov r1, #0
+ str r1, [r4, #0x8] // SSI: SSIENR
+ //set divider
+ mov r1, #0x2
+ str r1, [r4, #0x14] // SSI: BAUDR
+ // set 1-cycle sample delay.
+ mov r1, #1
+ mov r2, #0xf0
+ str r1, [r4, r2] // SSI: RX_SAMPLE_DLY
+ // setup SSI
+ ldr r1, =(7 << 16 | 3 << 8) // 8bit data frame size, eeprom
+ str r1, [r4, #0] // SSI: CTRLR0
+ mov r1, #0 // NDF = 0
+ str r1, [r4, #0x4] // SSI: CTRLR1
+ // enable SSI
+ mov r1, #1
+ str r1, [r4, #0x8] // SSI: SSIENR
+
+ // set flash QSPI
+ // write enable
+ mov r1, #0x06 // write enable
+ str r1, [r4, #0x60] // SSI: DR0
+ bl wait_ssi
+ ldr r1, [r4, #0x60] // SSI: DR0
+ // enable QSPI
+ mov r1, #0x31 // write status register-2
+ str r1, [r4, #0x60] // SSI: DR0
+ mov r1, #0x2 // quad enable
+ str r1, [r4, #0x60] // SSI: DR0
+ bl wait_ssi
+ ldr r1, [r4, #0x60] // SSI: DR0
+ ldr r1, [r4, #0x60] // SSI: DR0
+wait_sreg:
+ mov r1, #0x5 // read status register-1
+ // This str is required twice if TMOD = 0.
+ // In this case, /CS signal is set to high just
+ // after the first str instruction and the flash
+ // doesn't shift out the status register.
+ // On the other hand, If TMOD = 3 (eeprom),
+ // then the /CS is kept to low until NDF + 1
+ // data frames are captured.
+ // Shiran Kedo.
+ str r1, [r4, #0x60] // SSI: DR0
+ bl wait_ssi
+ ldr r1, [r4, #0x60] // SSI: DR0
+ mov r2, #1 // BUSY flag
+ tst r1, r2
+ bne wait_sreg
+
+ // set SSI QSPI
+ // disable SSI
+ mov r1, #0
+ str r1, [r4, #0x8] // SSI: SSIENR
+ // set up QSPI
+ // DFS is said to be the number of clocks of a data frame - 1.
+ // But in QSPI mode, a frame is 32 bits and is transfered in 8 clocks.
+ // However, if DFS is set to 7, It doesn't work.
+ // Maybe this is a bug of the documentation.
+ ldr r1, =(2 << 21 | 31 << 16 | 3 << 8) // quad, 32bit data frame, eeprom
+ str r1, [r4, #0] // SSI: CTRLR0
+ ldr r1, =(4 << 11 | 2 << 8 | 6 << 2 | 1 << 0)
+ mov r2, #0xf4
+ str r1, [r4, r2] // SSI: SPI_CTRLR0
+ // re-enable SSI
+ mov r1, #1
+ str r1, [r4, #0x8] // SSI: SSIENR
+
+ // this code should be rewritten using dma.
+ mov r5, #0xeb
+ lsl r5, r5, #24
+ ldr r6, boot2_end
+ lsl r6, r6, #8
+ lsr r6, r6, #8
+ add r5, r5, r6 // flash read command
+ ldr r6, sram_base // sram dst address
+ ldr r7, etext
+ sub r7, r0, r3
+ lsr r7, #2 // counter
+sram_cpy:
+ str r5, [r4, #0x60] // SSI: DR0
+ bl wait_ssi
+ ldr r0, [r4, #0x60] // SSI: DR0
+ str r0, [r6, #0]
+ add r5, r5, #0x4
+ add r6, r6, #0x4
+ sub r7, r7, #0x1
+ bne sram_cpy
+
+ // exit from boot2
+ pop {r4, r5, r6, r7}
+ pop {r0}
+ cmp r0, #0
+ beq initial_boot
+ bx r0
+initial_boot:
+ ldr r0, sram_base
+ ldr r1, m0plus_vtor
+ str r0, [r1, #0] // M0PLUS: VTOR
+ ldr r1, [r0, #4] // entry point
+ ldr r0, [r0, #0] // stack pointer
+ mov sp, r0
+ bx r1
+
+wait_ssi:
+ // asumes that r4 is xip_ssi_base
+ ldr r1, [r4, #0x28] // SSI: SR
+ mov r2, #4 // TFE
+ tst r1, r2
+ beq wait_ssi
+ mov r2, #1 // BUSY
+ tst r1, r2
+ bne wait_ssi
+ bx lr
+
+ .align 2
+boot2_end:
+ .word 0x10000000 + 0x100
+xip_ssi_base:
+ .word 0x18000000
+sram_base:
+ .word 0x20000000
+pads_qspi_base:
+ .word 0x40020000
+m0plus_vtor:
+ .word 0xe0000000 + 0xed08
+etext:
+ .word _etext
+literals:
+ .ltorg
+
diff --git a/mach.s b/mach.s
@@ -16,7 +16,7 @@ hang:
.global init
.thumb_func
init:
- push {lr}
+ push {r4, lr}
// unreset gpio and pll_sys and uart0
mov r1, #1
lsl r0, r1, #5 // io_bank0
@@ -134,54 +134,53 @@ pll_lock:
lsl r1, r1, #5
str r1, [r0, #0x2c] // UART0_UARTLCR_H
+ ldr r0, =(0 << 21 | 32 << 16 | 3 << 8) // SSI: CTRLR0
+ ldr r1, =(0x0 << 24 | 0 << 11 | 0 << 8 | 0 << 2 | 0) // SSI: SPI_CTRLR0
+ bl setup_ssi
bl exit_xip
- ldr r3, xip_ssi_base
+ ldr r4, xip_ssi_base
- mov r1, #0x06 // write enable
- str r1, [r3, #0x60] // SSI: DR0
- bl wait_ssi
- bl ssi_drain
+ ldr r0, =(0 << 21 | 32 << 16 | 3 << 8) // SSI: CTRLR0
+ ldr r1, =(0x0 << 24 | 0 << 11 | 0 << 8 | 0 << 2 | 0) // SSI: SPI_CTRLR0
+ bl setup_ssi
+
+ mov r0, #0x03
+ lsl r0, r0, #24
+ str r0, [r4, #0x60] // SSI: DR0
- mov r1, #0x05 // read status register-1
- str r1, [r3, #0x60] // SSI: DR0
bl wait_ssi
bl ssi_print
- mov r1, #0x35 // read status register-2
+
+ pop {r4, pc}
+
+exit_xip:
+ push {lr}
+ mov r1, #0
+ str r1, [r3, #0x60] // SSI: DR0
+ str r1, [r3, #0x60] // SSI: DR0
str r1, [r3, #0x60] // SSI: DR0
- bl wait_ssi
- bl ssi_print
- mov r1, #0x15 // read status register-3
str r1, [r3, #0x60] // SSI: DR0
bl wait_ssi
- bl ssi_print
-
+ bl ssi_drain
pop {pc}
-exit_xip:
+setup_ssi:
push {lr}
-
ldr r3, xip_ssi_base
// disable ssi
- mov r1, #0
- str r1, [r3, #0x8] // SSI: SSIENR
- ldr r1, =(0 << 21 | 7 << 16 | 3 << 8)
- str r1, [r3, #0] // SSI: CTRLR0
- mov r1, #0 // NDF
- str r1, [r3, #4] // SSI: CTRLR1
+ mov r2, #0
+ str r2, [r3, #0x8] // SSI: SSIENR
+ // setup SSI
+ str r0, [r3, #0] // SSI: CTRLR0
+ mov r2, #0 // NDF
+ str r2, [r3, #4] // SSI: CTRLR1
// setup SPI
- ldr r1, =(0x0 << 24 | 0 << 11 | 2 << 8 | 0 << 2 | 0)
mov r2, #0xf4
str r1, [r3, r2] // SSI: SPI_CTRLR0
// reenable SSI
- mov r1, #1
- str r1, [r3, #0x8] // SSI: SSIENR
- // exit xip mode
- mov r1, #0x00
- str r1, [r3, #0x60] // SSI: DR0
- bl wait_ssi
- bl ssi_drain
-
+ mov r2, #1
+ str r2, [r3, #0x8] // SSI: SSIENR
pop {pc}
wait_ssi: