Add flash support for SiFive's Freedom E platforms
[openocd.git] / contrib / loaders / flash / fespi / fespi.S
1 #define SPIFLASH_READ_STATUS 0x05 // Read Status Register
2 #define SPIFLASH_BSY_BIT 0x00000001 // WIP Bit of SPI SR on SMI SR
3
4 // Register offsets
5 #define FESPI_REG_FMT 0x40
6 #define FESPI_REG_TXFIFO 0x48
7 #define FESPI_REG_RXFIFO 0x4c
8 #define FESPI_REG_IP 0x74
9
10 // Fields
11 #define FESPI_IP_TXWM 0x1
12 #define FESPI_FMT_DIR(x) (((x) & 0x1) << 3)
13
14 // To enter, jump to the start of command_table (ie. offset 0).
15 // a0 - FESPI base address
16 // a1 - start address of buffer
17
18 // The buffer contains a "program" in byte sequences. The first byte in a
19 // sequence determines the operation. Some operation will read more data from
20 // the program, while some will not. The operation byte is the offset into
21 // command_table, so eg. 4 means exit, 8 means transmit, and so on.
22
23 .global _start
24 _start:
25 command_table:
26 j main // 0
27 ebreak // 4
28 j tx // 8
29 j txwm_wait // 12
30 j write_reg // 16
31 j wip_wait // 20
32 j set_dir // 24
33
34 // Execute the program.
35 main:
36 lbu t0, 0(a1)
37 addi a1, a1, 1
38 la t1, command_table
39 add t0, t0, t1
40 jr t0
41
42 // Read 1 byte the contains the number of bytes to transmit. Then read those
43 // bytes from the program and transmit them one by one.
44 tx:
45 lbu t1, 0(a1) // read number of bytes to transmit
46 addi a1, a1, 1
47 1: lw t0, FESPI_REG_TXFIFO(a0) // wait for FIFO clear
48 bltz t0, 1b
49 lbu t0, 0(a1) // Load byte to write
50 sw t0, FESPI_REG_TXFIFO(a0)
51 addi a1, a1, 1
52 addi t1, t1, -1
53 bgtz t1, 1b
54 j main
55
56 // Wait until TXWM is set.
57 txwm_wait:
58 1: lw t0, FESPI_REG_IP(a0)
59 andi t0, t0, FESPI_IP_TXWM
60 beqz t0, 1b
61 j main
62
63 // Read 1 byte that contains the offset of the register to write, and 1 byte
64 // that contains the data to write.
65 write_reg:
66 lbu t0, 0(a1) // read register to write
67 add t0, t0, a0
68 lbu t1, 1(a1) // read value to write
69 addi a1, a1, 2
70 sw t1, 0(t0)
71 j main
72
73 wip_wait:
74 li a2, SPIFLASH_READ_STATUS
75 jal txrx_byte
76 // discard first result
77 1: li a2, 0
78 jal txrx_byte
79 andi t0, a2, SPIFLASH_BSY_BIT
80 bnez t0, 1b
81 j main
82
83 txrx_byte: // transmit the byte in a2, receive a bit into a2
84 lw t0, FESPI_REG_TXFIFO(a0) // wait for FIFO clear
85 bltz t0, txrx_byte
86 sw a2, FESPI_REG_TXFIFO(a0)
87 1: lw a2, FESPI_REG_RXFIFO(a0)
88 bltz a2, 1b
89 ret
90
91 set_dir:
92 lw t0, FESPI_REG_FMT(a0)
93 li t1, ~(FESPI_FMT_DIR(0xFFFFFFFF))
94 and t0, t0, t1
95 lbu t1, 0(a1) // read value to OR in
96 addi a1, a1, 1
97 or t0, t0, t1
98 sw t0, FESPI_REG_FMT(a0)
99 j main

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)