machine/rp2040: correct Flash implementation
Signed-off-by: deadprogram <ron@hybridgroup.com>
Этот коммит содержится в:
родитель
5db83f11df
коммит
e6580bfff4
1 изменённых файлов: 21 добавлений и 9 удалений
|
@ -75,8 +75,6 @@ void reset_usb_boot(uint32_t usb_activity_gpio_pin_mask, uint32_t disable_interf
|
||||||
#define FLASH_SECTOR_SIZE (1u << 12)
|
#define FLASH_SECTOR_SIZE (1u << 12)
|
||||||
#define FLASH_BLOCK_SIZE (1u << 16)
|
#define FLASH_BLOCK_SIZE (1u << 16)
|
||||||
|
|
||||||
#define FLASH_UNIQUE_ID_SIZE_BYTES 8
|
|
||||||
|
|
||||||
#define BOOT2_SIZE_WORDS 64
|
#define BOOT2_SIZE_WORDS 64
|
||||||
#define XIP_BASE 0x10000000
|
#define XIP_BASE 0x10000000
|
||||||
|
|
||||||
|
@ -145,7 +143,7 @@ func EnterBootloader() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flash related code
|
// Flash related code
|
||||||
const memoryStart = 0
|
const memoryStart = C.XIP_BASE // memory start for purpose of erase
|
||||||
|
|
||||||
// compile-time check for ensuring we fulfill BlockDevice interface
|
// compile-time check for ensuring we fulfill BlockDevice interface
|
||||||
var _ BlockDevice = flashBlockDevice{}
|
var _ BlockDevice = flashBlockDevice{}
|
||||||
|
@ -157,11 +155,11 @@ type flashBlockDevice struct {
|
||||||
|
|
||||||
// ReadAt reads the given number of bytes from the block device.
|
// ReadAt reads the given number of bytes from the block device.
|
||||||
func (f flashBlockDevice) ReadAt(p []byte, off int64) (n int, err error) {
|
func (f flashBlockDevice) ReadAt(p []byte, off int64) (n int, err error) {
|
||||||
if uintptr(off)+uintptr(len(p)) > FlashDataEnd() {
|
if readAddress(off) > FlashDataEnd() {
|
||||||
return 0, errFlashCannotReadPastEOF
|
return 0, errFlashCannotReadPastEOF
|
||||||
}
|
}
|
||||||
|
|
||||||
data := unsafe.Slice((*byte)(unsafe.Pointer(uintptr(off))), len(p))
|
data := unsafe.Slice((*byte)(unsafe.Pointer(readAddress(off))), len(p))
|
||||||
copy(p, data)
|
copy(p, data)
|
||||||
|
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
|
@ -172,7 +170,7 @@ func (f flashBlockDevice) ReadAt(p []byte, off int64) (n int, err error) {
|
||||||
// If the length of p is not long enough it will be padded with 0xFF bytes.
|
// If the length of p is not long enough it will be padded with 0xFF bytes.
|
||||||
// This method assumes that the destination is already erased.
|
// This method assumes that the destination is already erased.
|
||||||
func (f flashBlockDevice) WriteAt(p []byte, off int64) (n int, err error) {
|
func (f flashBlockDevice) WriteAt(p []byte, off int64) (n int, err error) {
|
||||||
if uintptr(off)+uintptr(len(p)) > FlashDataEnd() {
|
if writeAddress(off)+uintptr(C.XIP_BASE) > FlashDataEnd() {
|
||||||
return 0, errFlashCannotWritePastEOF
|
return 0, errFlashCannotWritePastEOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +180,7 @@ func (f flashBlockDevice) WriteAt(p []byte, off int64) (n int, err error) {
|
||||||
// rp2040 writes to offset, not actual address
|
// rp2040 writes to offset, not actual address
|
||||||
// e.g. real address 0x10003000 is written to at
|
// e.g. real address 0x10003000 is written to at
|
||||||
// 0x00003000
|
// 0x00003000
|
||||||
address := uintptr(off) - C.XIP_BASE
|
address := writeAddress(off)
|
||||||
padded := f.pad(p)
|
padded := f.pad(p)
|
||||||
|
|
||||||
C.flash_range_write(C.uint32_t(address),
|
C.flash_range_write(C.uint32_t(address),
|
||||||
|
@ -223,11 +221,15 @@ func (f flashBlockDevice) EraseBlockSize() int64 {
|
||||||
// supports this. The start and len parameters are in block numbers, use
|
// supports this. The start and len parameters are in block numbers, use
|
||||||
// EraseBlockSize to map addresses to blocks.
|
// EraseBlockSize to map addresses to blocks.
|
||||||
func (f flashBlockDevice) EraseBlocks(start, length int64) error {
|
func (f flashBlockDevice) EraseBlocks(start, length int64) error {
|
||||||
|
address := writeAddress(start * f.EraseBlockSize())
|
||||||
|
if address+uintptr(C.XIP_BASE) > FlashDataEnd() {
|
||||||
|
return errFlashCannotErasePastEOF
|
||||||
|
}
|
||||||
|
|
||||||
state := interrupt.Disable()
|
state := interrupt.Disable()
|
||||||
defer interrupt.Restore(state)
|
defer interrupt.Restore(state)
|
||||||
|
|
||||||
address := uintptr(start*f.EraseBlockSize()) - C.XIP_BASE
|
C.flash_erase_blocks(C.uint32_t(address), C.ulong(length))
|
||||||
C.flash_erase_blocks(C.uint32_t(address), C.ulong(length*f.EraseBlockSize()))
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -242,3 +244,13 @@ func (f flashBlockDevice) pad(p []byte) []byte {
|
||||||
padding := bytes.Repeat([]byte{0xff}, int(paddingNeeded))
|
padding := bytes.Repeat([]byte{0xff}, int(paddingNeeded))
|
||||||
return append(p, padding...)
|
return append(p, padding...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return the correct address to be used for write
|
||||||
|
func writeAddress(off int64) uintptr {
|
||||||
|
return readAddress(off) - uintptr(C.XIP_BASE)
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the correct address to be used for reads
|
||||||
|
func readAddress(off int64) uintptr {
|
||||||
|
return FlashDataStart() + uintptr(off)
|
||||||
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче