|
10 | 10 | #include <stdint.h>
|
11 | 11 | #include <stdbool.h>
|
12 | 12 | #include "eboot.h"
|
| 13 | +#include "eboot_command.h" |
13 | 14 | extern void* flashchip;
|
14 | 15 |
|
15 | 16 | #define SWRST do { (*((volatile uint32_t*) 0x60000700)) |= 0x80000000; } while(0);
|
@@ -71,9 +72,100 @@ int load_app_from_flash_raw(const uint32_t flash_addr)
|
71 | 72 | }
|
72 | 73 |
|
73 | 74 |
|
| 75 | + |
| 76 | +int erase(const uint32_t start, const uint32_t size) |
| 77 | +{ |
| 78 | + if (start & (FLASH_SECTOR_SIZE - 1) != 0) { |
| 79 | + return 1; |
| 80 | + } |
| 81 | + |
| 82 | + const uint32_t sectors_per_block = FLASH_BLOCK_SIZE / FLASH_SECTOR_SIZE; |
| 83 | + uint32_t current_sector = start / FLASH_SECTOR_SIZE; |
| 84 | + uint32_t sector_count = (size + FLASH_SECTOR_SIZE - 1) / FLASH_SECTOR_SIZE; |
| 85 | + const uint32_t end = current_sector + sector_count; |
| 86 | + |
| 87 | + for (; current_sector < end && (current_sector & (sectors_per_block-1)); |
| 88 | + ++current_sector, --sector_count) { |
| 89 | + if (SPIEraseSector(current_sector)) { |
| 90 | + return 2; |
| 91 | + } |
| 92 | + } |
| 93 | + |
| 94 | + for (;current_sector + sectors_per_block <= end; |
| 95 | + current_sector += sectors_per_block, |
| 96 | + sector_count -= sectors_per_block) { |
| 97 | + if (SPIEraseBlock(current_sector / sectors_per_block)) { |
| 98 | + return 3; |
| 99 | + } |
| 100 | + } |
| 101 | + |
| 102 | + for (; current_sector < end; |
| 103 | + ++current_sector, --sector_count) { |
| 104 | + if (SPIEraseSector(current_sector)) { |
| 105 | + return 4; |
| 106 | + } |
| 107 | + } |
| 108 | + |
| 109 | + return 0; |
| 110 | +} |
| 111 | + |
| 112 | +int copy_raw(const uint32_t src_addr, |
| 113 | + const uint32_t dst_addr, |
| 114 | + const uint32_t size) |
| 115 | +{ |
| 116 | + // require regions to be aligned |
| 117 | + if (src_addr & 0xfff != 0 || |
| 118 | + dst_addr & 0xfff != 0) { |
| 119 | + return 1; |
| 120 | + } |
| 121 | + |
| 122 | + if (erase(dst_addr, size)) { |
| 123 | + return 2; |
| 124 | + } |
| 125 | + |
| 126 | + const uint32_t buffer_size = 4096; |
| 127 | + uint8_t buffer[buffer_size]; |
| 128 | + |
| 129 | + const uint32_t end = src_addr + size; |
| 130 | + uint32_t saddr = src_addr; |
| 131 | + uint32_t daddr = dst_addr; |
| 132 | + uint32_t left = size; |
| 133 | + while (saddr < end) { |
| 134 | + uint32_t will_copy = (left < buffer_size) ? left : buffer_size; |
| 135 | + if (SPIRead(saddr, buffer, will_copy)) { |
| 136 | + return 3; |
| 137 | + } |
| 138 | + if (SPIWrite(daddr, buffer, will_copy)) { |
| 139 | + return 4; |
| 140 | + } |
| 141 | + saddr += will_copy; |
| 142 | + daddr += will_copy; |
| 143 | + left -= will_copy; |
| 144 | + } |
| 145 | + |
| 146 | + return 0; |
| 147 | +} |
| 148 | + |
| 149 | + |
| 150 | + |
74 | 151 | void main()
|
75 | 152 | {
|
76 |
| - int res = load_app_from_flash_raw(0); |
| 153 | + int res = 9; |
| 154 | + struct eboot_command cmd; |
| 155 | + |
| 156 | + eboot_command_read(&cmd); |
| 157 | + |
| 158 | + if (cmd.action == ACTION_COPY_RAW) { |
| 159 | + res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2]); |
| 160 | + if (res == 0) { |
| 161 | + cmd.action = ACTION_LOAD_APP; |
| 162 | + } |
| 163 | + } |
| 164 | + |
| 165 | + if (cmd.action == ACTION_LOAD_APP) { |
| 166 | + res = load_app_from_flash_raw(0); |
| 167 | + } |
| 168 | + |
77 | 169 | if (res) {
|
78 | 170 | ets_putc('\n');
|
79 | 171 | ets_putc('#');
|
|
0 commit comments