2022-07-14 | gnu: system: Add fusermount3 to setuid-programs....Fixes <https://issues.guix.gnu.org/47716>.
* gnu/system.scm (%setuid-programs): Add /bin/fusermount3 from the fuse-3
package.
Reported-by: raingloom <raingloom@riseup.net>
| Maxim Cournoyer |
nrf52_info *chip,
+ const uint8_t *buffer, uint32_t offset, uint32_t count)
+{
+ int res;
+ /* Need to perform reads to fill any gaps we need to preserve in the first page,
+ before the start of buffer, or in the last page, after the end of buffer */
+ uint32_t first_page = offset / chip->code_page_size;
+ uint32_t last_page = DIV_ROUND_UP(offset+count, chip->code_page_size);
+
+ uint32_t first_page_offset = first_page * chip->code_page_size;
+ uint32_t last_page_offset = last_page * chip->code_page_size;
+
+ LOG_DEBUG("Padding write from 0x%08"PRIx32"-0x%08"PRIx32" as 0x%08"PRIx32"-0x%08"PRIx32,
+ offset, offset+count, first_page_offset, last_page_offset);
+
+ uint32_t page_cnt = last_page - first_page;
+ uint8_t buffer_to_flash[page_cnt * chip->code_page_size];
+
+ /* Fill in any space between start of first page and start of buffer */
+ uint32_t pre = offset - first_page_offset;
+ if (pre > 0) {
+ res = target_read_memory(bank->target, first_page_offset, 1, pre, buffer_to_flash);
+ if (res != ERROR_OK)
+ return res;
+ }
+
+ /* Fill in main contents of buffer */
+ memcpy(buffer_to_flash + pre, buffer, count);
+
+ /* Fill in any space between end of buffer and end of last page */
+ uint32_t post = last_page_offset - (offset + count);
+ if (post > 0) {
+ /* Retrieve the full row contents from Flash */
+ res = target_read_memory(bank->target, offset + count, 1, post, buffer_to_flash + pre + count);
+ if (res != ERROR_OK)
+ return res;
+ }
+
+ return nrf52_write_pages(bank, first_page_offset, last_page_offset, buffer_to_flash);
+}
+
+static int nrf52_uicr_flash_write(struct flash_bank *bank,
+ struct nrf52_info *chip,
+ const uint8_t *buffer, uint32_t offset, uint32_t count)
+{
+ int res;
+ uint32_t nrf52_uicr_size = chip->code_page_size;
+ uint8_t uicr[nrf52_uicr_size];
+ struct flash_sector *sector = &bank->sectors[0];
+
+ if ((offset + count) > nrf52_uicr_size)
+ return ERROR_FAIL;
+
+ res = target_read_memory(bank->target, NRF52_UICR_BASE_ADDR, 1, nrf52_uicr_size, uicr);
+
+ if (res != ERROR_OK)
+ return res;
+
+ if (sector->is_erased != 1) {
+ res = nrf52_erase_page(bank, chip, sector);
+ if (res != ERROR_OK)
+ return res;
+ }
+
+ memcpy(&uicr[offset], buffer, count);
+
+ res = nrf52_nvmc_write_enable(chip);
+ if (res != ERROR_OK)
+ return res;
+
+ res = nrf52_ll_flash_write(chip, NRF52_UICR_BASE_ADDR, uicr, nrf52_uicr_size);
+ if (res != ERROR_OK) {
+ nrf52_nvmc_read_only(chip);
+ return res;
+ }
+
+ return nrf52_nvmc_read_only(chip);
+}
+
+
+static int nrf52_write(struct flash_bank *bank, const uint8_t *buffer,
+ uint32_t offset, uint32_t count)
+{
+ struct nrf52_info *chip = bank->driver_priv;
+ assert(chip != NULL);
+
+ return chip->bank[bank->bank_number].write(bank, chip, buffer, offset, count);
+}
+
+
+FLASH_BANK_COMMAND_HANDLER(nrf52_flash_bank_command)
+{
+ static struct nrf52_info *chip;
+
+ assert(bank != NULL);
+
+ switch (bank->base) {
+ case NRF52_FLASH_BASE_ADDR:
+ bank->bank_number = 0;
+ break;
+ case NRF52_UICR_BASE_ADDR:
+ bank->bank_number = 1;
+ break;
+ default:
+ LOG_ERROR("Invalid bank address 0x%08" PRIx32, bank->base);
+ return ERROR_FAIL;
+ }
+
+ if (!chip) {
+ /* Create a new chip */
+ chip = calloc(1, sizeof(*chip));
+ assert(chip != NULL);
+
+ chip->target = bank->target;
+ }
+
+ switch (bank->base) {
+ case NRF52_FLASH_BASE_ADDR:
+ chip->bank[bank->bank_number].write = nrf52_code_flash_write;
+ break;
+ case NRF52_UICR_BASE_ADDR:
+ chip->bank[bank->bank_number].write = nrf52_uicr_flash_write;
+ break;
+ }
+
+ chip->bank[bank->bank_number].probed = false;
+ bank->driver_priv = chip;
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(nrf52_handle_mass_erase_command)
+{
+ int res;
+ struct flash_bank *bank = NULL;
+ struct target *target = get_current_target(CMD_CTX);
+
+ res = get_flash_bank_by_addr(target, NRF52_FLASH_BASE_ADDR, true, &bank);
+ if (res != ERROR_OK)
+ return res;
+
+ assert(bank != NULL);
+
+ struct nrf52_info *chip = bank->driver_priv;
+ assert(chip != NULL);
+
+ res = nrf52_erase_all(chip);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to erase the chip");
+ nrf52_protect_check(bank);
+ return res;
+ }
+
+ for (int i = 0; i < bank->num_sectors; i++)
+ bank->sectors[i].is_erased = 1;
+
+ res = nrf52_protect_check(bank);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Failed to check chip's write protection");
+ return res;
+ }
+
+ res = get_flash_bank_by_addr(target, NRF52_UICR_BASE_ADDR, true, &bank);
+ if (res != ERROR_OK)
+ return res;
+
+ bank->sectors[0].is_erased = 1;
+
+ return ERROR_OK;
+}
+
+static int nrf52_info(struct flash_bank *bank, char *buf, int buf_size)
+{
+ int res;
+ uint32_t ficr[2];
+ struct nrf52_info *chip = bank->driver_priv;
+ assert(chip != NULL);
+
+ res = target_read_u32(chip->target, NRF52_FICR_CODEPAGESIZE_ADDR, &ficr[0]);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Couldn't read NVMC_READY register");
+ return res;
+ }
+
+ res = target_read_u32(chip->target, NRF52_FICR_CODESIZE_ADDR, &ficr[1]);
+ if (res != ERROR_OK) {
+ LOG_ERROR("Couldn't read NVMC_READY register");
+ return res;
+ }
+
+ snprintf(buf, buf_size,
+ "\n--------nRF52 Series Device--------\n\n"
+ "\n[factory information control block]\n"
+ "code page size: %"PRIu32"B\n"
+ "code memory size: %"PRIu32"kB\n",
+ ficr[0],
+ (ficr[1] * ficr[0]) / 1024);
+
+ return ERROR_OK;
+}
+
+static const struct command_registration nrf52_exec_command_handlers[] = {
+ {
+ .name = "mass_erase",
+ .handler = nrf52_handle_mass_erase_command,
+ .mode = COMMAND_EXEC,
+ .help = "Erase all flash contents of the chip.",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration nrf52_command_handlers[] = {
+ {
+ .name = "nrf52",
+ .mode = COMMAND_ANY,
+ .help = "nrf52 flash command group",
+ .usage = "",
+ .chain = nrf52_exec_command_handlers,
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+struct flash_driver nrf52_flash = {
+ .name = "nrf52",
+ .commands = nrf52_command_handlers,
+ .flash_bank_command = nrf52_flash_bank_command,
+ .info = nrf52_info,
+ .erase = nrf52_erase,
+ .protect = nrf52_protect,
+ .write = nrf52_write,
+ .read = default_flash_read,
+ .probe = nrf52_probe,
+ .auto_probe = nrf52_auto_probe,
+ .erase_check = default_flash_blank_check,
+ .protect_check = nrf52_protect_check,
+};
diff --git a/tcl/target/nrf52.cfg b/tcl/target/nrf52.cfg
index c1cbf1a..41a22ff 100644
--- a/tcl/target/nrf52.cfg
+++ b/tcl/target/nrf52.cfg
@@ -10,6 +10,13 @@ if { [info exists CHIPNAME] } {
set _CHIPNAME nrf52
}
+# Work-area is a space in RAM used for flash programming, by default use 16kB.
+if { [info exists WORKAREASIZE] } {
+ set _WORKAREASIZE $WORKAREASIZE
+} else {
+ set _WORKAREASIZE 0x4000
+}
+
if { [info exists CPUTAPID] } {
set _CPUTAPID $CPUTAPID
} else {
@@ -22,7 +29,15 @@ set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME
adapter_khz 10000
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
if { ![using_hla] } {
cortex_m reset_config sysresetreq
}
+
+flash bank $_CHIPNAME.flash nrf52 0x00000000 0 1 1 $_TARGETNAME
+flash bank $_CHIPNAME.uicr nrf52 0x10001000 0 1 1 $_TARGETNAME
+
+adapter_khz 1000
+
+$_TARGETNAME configure -event reset-end {}