Skip to content

Instantly share code, notes, and snippets.

@henrygab
Created October 5, 2019 16:02
Show Gist options
  • Save henrygab/d6d34d585ca3172f8ddf937658089af3 to your computer and use it in GitHub Desktop.
Save henrygab/d6d34d585ca3172f8ddf937658089af3 to your computer and use it in GitHub Desktop.
Validation of changes to flash_cache_read function
Set-StrictMode -Version latest;
# Set to 4096 for actual implementation... set to 4000 to make output easier on human eyes (non-hex output)
[uint32] $FLASH_CACHE_SIZE = 4000; # adjusting for decimal outputs for easier reading
[uint32]$cacheStart = 8 * $FLASH_CACHE_SIZE;
[uint32]$cacheEnd = $cacheStart + $FLASH_CACHE_SIZE;
function flash_cache_read( [uint32] $cache_start_addr, [uint32] $dst, [uint32] $addr, [uint32] $countOfBytes )
{
# Checking against https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/fc6372836b6f2c31fc96d8ad9bc6670f8af0cc47/libraries/InternalFileSytem/src/flash/flash_cache.c
# lines 101-103 check if there's zero overlap with the cache area
# ... the ELSE jumps to lines 126-129, which does a single normal flash cache read
if ($cache_start_addr -eq 0xFFFFFFFF) {
"fcread($dst, $addr, $countOfBytes)";
return;
}
if (($addr -lt $cache_start_addr) -and ($addr + $countOfBytes -le $cache_start_addr)) {
"fcread($dst, $addr, $countOfBytes)";
return;
}
if ($addr -ge ($cache_start_addr + $FLASH_CACHE_SIZE)) {
"fcread($dst, $addr, $countOfBytes)";
return;
}
# else, the read definitely overlaps the cache by at least one byte...
# lines 105-106
[int32] $dst_off = $cache_start_addr - $addr;
[int32] $src_off = 0;
# lines 108-112
if ($dst_off -lt 0) {
$src_off = -$dst_off;
$dst_off = 0;
}
# line 114
[int32] $cache_bytes = 0;
if ($true) {
[int32] $tmp_a = $FLASH_CACHE_SIZE - $src_off;
[int32] $tmp_b = $countOfBytes - $dst_off;
if ($tmp_a -lt 0) {
"*** ERR *** Source offset was greater than FLASH_CACHE_SIZE (param1 at line 114) -- unsafe to use unsigned integers / size_t";
}
if ($tmp_b -lt 0) {
"*** ERR *** Destination offset was greater than count (param2 at line 114) -- unsafe to use unsigned integers / size_t";
}
if ($tmp_a -lt $tmp_b) {
$cache_bytes = $tmp_a;
} else {
$cache_bytes = $tmp_b;
}
}
# line 117
if ($dst_off -ne 0) {
"fcread($dst, $addr, $dst_off)";
}
# line 119
"memcpy($($dst+$dst_off), $($cache_start_addr + $src_off), $cache_bytes)";
# line 123
[int32] $copied = $dst_off + $cache_bytes;
if ($copied -lt 0) {
"*** ERR *** Copied bytes is less than zero !? (overflow?)"
}
if ($copied -lt $countOfBytes) {
"fcread($($dst+$copied), $($addr+$copied), $($countOfBytes - $copied))";
}
return;
}
function alternate_cache_read( [uint32] $cache_start_addr, [uint32] $dst, [uint32] $addr, [uint32] $countOfBytes )
{
# Checking against https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/fc6372836b6f2c31fc96d8ad9bc6670f8af0cc47/libraries/InternalFileSytem/src/flash/flash_cache.c
# lines 102-104 check if there's zero overlap with the cache area
# ... the ELSE jumps to lines 194-197, which does a single normal flash cache read
if ($cache_start_addr -eq 0xFFFFFFFF) {
"fcread($dst, $addr, $countOfBytes)";
return;
}
if (($addr -lt $cache_start_addr) -and ($addr + $countOfBytes -le $cache_start_addr)) {
"fcread($dst, $addr, $countOfBytes)";
return;
}
if ($addr -ge ($cache_start_addr + $FLASH_CACHE_SIZE)) {
"fcread($dst, $addr, $countOfBytes)";
return;
}
# else, the read definitely overlaps the cache by at least one byte...
# lines 110-111
[uint32] $dst_off = 0;
[uint32] $src_off = 0;
# lines 112-121
if ($addr -lt $cache_start_addr) {
$dst_off = $cache_start_addr - $addr;
"fcread($dst, $addr, $dst_off)";
} else {
$src_off = $addr - $cache_start_addr;
}
# line 154
[uint32] $cache_bytes = 0;
if ($true) {
[uint32] $tmp_a = $FLASH_CACHE_SIZE - $src_off;
[uint32] $tmp_b = $countOfBytes - $dst_off;
if ($tmp_a -gt $FLASH_CACHE_SIZE) {
"*** ERR *** Source offset was greater than FLASH_CACHE_SIZE (param1 at line 154) -- unsafe to use unsigned integers / size_t";
}
if ($tmp_b -gt $countOfBytes) {
"*** ERR *** Destination offset was greater than count (param2 at line 154) -- unsafe to use unsigned integers / size_t";
}
if ($tmp_a -lt $tmp_b) {
$cache_bytes = $tmp_a;
} else {
$cache_bytes = $tmp_b;
}
}
# line 178
"memcpy($($dst+$dst_off), $($cache_start_addr + $src_off), $cache_bytes)";
# line 185-191
[uint32] $copied = $dst_off + $cache_bytes;
if ($copied -lt $cache_bytes) {
"*** ERR *** Copied bytes is less than zero !? (overflow?)"
}
if ($copied -lt $countOfBytes) {
"fcread($($dst+$copied), $($addr+$copied), $($countOfBytes - $copied))";
}
return;
}
[uint32]$destination = 777777;
[uint32]$addressToRead = 0;
[uint32]$bytesToRead = 4 * $FLASH_CACHE_SIZE;
for ($addressToRead = 0; $addressToRead -lt $cacheEnd + $bytesToRead + ($FLASH_CACHE_SIZE*2); $addressToRead += $FLASH_CACHE_SIZE/2) {
"------------------------------------";
"start address: $addressToRead";
flash_cache_read -cache_start_addr $cacheStart -dst $destination -addr $addressToRead -countOfBytes $bytesToRead;
"...";
alternate_cache_read -cache_start_addr $cacheStart -dst $destination -addr $addressToRead -countOfBytes $bytesToRead;
}
"------------------------------------";
"";
"Next iteration..."
"";
$bytesToRead = $FLASH_CACHE_SIZE / 4;
for ($addressToRead = $cacheStart - ($FLASH_CACHE_SIZE/4); $addressToRead -le $cacheEnd; $addressToRead += $FLASH_CACHE_SIZE/8) {
"------------------------------------";
"start address: $addressToRead";
flash_cache_read -cache_start_addr $cacheStart -dst $destination -addr $addressToRead -countOfBytes $bytesToRead;
"...";
alternate_cache_read -cache_start_addr $cacheStart -dst $destination -addr $addressToRead -countOfBytes $bytesToRead;
}
"------------------------------------";
"";
"Large spanning write..."
"";
$bytesToRead = $cacheStart + $FLASH_CACHE_SIZE * 2;
$addressToRead = 0;
flash_cache_read -cache_start_addr $cacheStart -dst $destination -addr $addressToRead -countOfBytes $bytesToRead;
"...";
alternate_cache_read -cache_start_addr $cacheStart -dst $destination -addr $addressToRead -countOfBytes $bytesToRead;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment