Add support for pinning XIP SRAM (#298)

* Allow use of xip_sram in flash binaries

* Add handling for SDK xip_sram pinning

Also add --pin-xip-sram arg, add --no-clear arg to encrypt, and use model for correct pinning and clearing

* Document different clear defaults between seal and encrypt

Also fix seal documentation, as it doesn't sign the binary by default
diff --git a/README.md b/README.md
index 2d50bef..9b80f0b 100644
--- a/README.md
+++ b/README.md
@@ -16,10 +16,10 @@
     picotool config [-s <key> <value>] [-g <group>] <filename> [-t <type>]
     picotool load [--ignore-partitions] [--family <family_id>] [-p <partition>] [-n] [-N] [-u] [-v] [-x] <filename> [-t <type>] [-o
                 <offset>] [device-selection]
-    picotool encrypt [--quiet] [--verbose] [--embed] [--fast-rosc] [--use-mbedtls] [--otp-key-page <page>] [--hash] [--sign] <infile> [-t
-                <type>] [-o <offset>] <outfile> [-t <type>] <aes_key> <iv_salt> <signing_key> <otp>
-    picotool seal [--quiet] [--verbose] [--hash] [--sign] [--clear] <infile> [-t <type>] [-o <offset>] <outfile> [-t <type>] <key> <otp>
-                [--major <major>] [--minor <minor>] [--rollback <rollback> [<rows>..]]
+    picotool encrypt [--quiet] [--verbose] [--embed] [--fast-rosc] [--use-mbedtls] [--otp-key-page <page>] [--hash] [--sign] [--no-clear]
+                [--pin-xip-sram] <infile> [-t <type>] [-o <offset>] <outfile> [-t <type>] <aes_key> <iv_salt> <signing_key> <otp>
+    picotool seal [--quiet] [--verbose] [--hash] [--sign] [--clear] [--pin-xip-sram] <infile> [-t <type>] [-o <offset>] <outfile> [-t
+                <type>] <key> <otp> [--major <major>] [--minor <minor>] [--rollback <rollback> [<rows>..]]
     picotool link [--quiet] [--verbose] <outfile> [-t <type>] <infile1> [-t <type>] <infile2> [-t <type>] [<infile3>] [-t <type>] [-p <pad>]
     picotool save [-p] [-v] [--family <family_id>] <filename> [-t <type>] [device-selection]
     picotool save -a [-v] [--family <family_id>] <filename> [-t <type>] [device-selection]
@@ -607,7 +607,7 @@
 
 `seal` allows you to sign and/or hash a binary to run on RP2350.
 
-By default, it will just sign the binary, but this can be configured with the `--hash` and `--no-sign` arguments.
+By default, it will just add an embedded block to the end containing a relative load map, thus sealing the binary. The `--hash` and `--sign` arguments can be passed to include an hash and a signature; `--major`, `--minor` and `--rollback` can be passed to include a version; and `--clear` or `--pin-xip-sram` can be passed to add load map items indicating whether SRAM should be cleared and whether XIP SRAM should be pinned.
 
 Your signing key must be for the _secp256k1_ curve, in PEM format. You can create a .PEM file with:
 
@@ -621,8 +621,8 @@
     Add final metadata to a binary, optionally including a hash and/or signature.
 
 SYNOPSIS:
-    picotool seal [--quiet] [--verbose] [--hash] [--sign] [--clear] <infile> [-t <type>] [-o <offset>] <outfile> [-t <type>] <key> <otp>
-                [--major <major>] [--minor <minor>] [--rollback <rollback> [<rows>..]]
+    picotool seal [--quiet] [--verbose] [--hash] [--sign] [--clear] [--pin-xip-sram] <infile> [-t <type>] [-o <offset>] <outfile> [-t
+                <type>] <key> <otp> [--major <major>] [--minor <minor>] [--rollback <rollback> [<rows>..]]
 
 OPTIONS:
         --quiet
@@ -645,7 +645,9 @@
         --sign
             Sign the file
         --clear
-            Clear all of SRAM on load
+            Clear all of main SRAM on load
+        --pin-xip-sram
+            Pin XIP SRAM on load
     File to load from
         <infile>
             The file name
@@ -665,7 +667,7 @@
 
 ## encrypt
 
-`encrypt` allows you to encrypt and sign a binary for use on the RP2350. By default, it will sign the encrypted binary, but that can be configured similarly to `picotool seal`. You can either provide your own bootloader to decrypt the binary (see pico-examples/bootloaders/encrypted), or embed a decrypting bootloader into the binary with the `--embed` argument, to create a self-decrypting binary.
+`encrypt` allows you to encrypt and sign a binary for use on the RP2350. By default, it will sign the encrypted binary, but that can be configured similarly to `picotool seal`. You can either provide your own bootloader to decrypt the binary (see pico-examples/bootloaders/encrypted), or embed a decrypting bootloader into the binary with the `--embed` argument, to create a self-decrypting binary. When embedding a bootloader, by default it will add a load map item to clear SRAM on load like the `picotool seal --clear` option - this can be disabled by passing `--no-clear`.
 
 The encrypted binary will have the following structure:
 
@@ -691,8 +693,8 @@
     Encrypt the program.
 
 SYNOPSIS:
-    picotool encrypt [--quiet] [--verbose] [--embed] [--fast-rosc] [--use-mbedtls] [--otp-key-page <page>] [--hash] [--sign] <infile> [-t
-                <type>] [-o <offset>] <outfile> [-t <type>] <aes_key> <iv_salt> <signing_key> <otp>
+    picotool encrypt [--quiet] [--verbose] [--embed] [--fast-rosc] [--use-mbedtls] [--otp-key-page <page>] [--hash] [--sign] [--no-clear]
+                [--pin-xip-sram] <infile> [-t <type>] [-o <offset>] <outfile> [-t <type>] <aes_key> <iv_salt> <signing_key> <otp>
 
 OPTIONS:
         --quiet
@@ -722,6 +724,10 @@
             Hash the encrypted file
         --sign
             Sign the encrypted file
+        --no-clear
+            Don't clear all of main SRAM on load
+        --pin-xip-sram
+            Pin XIP SRAM on load
     File to load from
         <infile>
             The file name
diff --git a/bintool/BUILD.bazel b/bintool/BUILD.bazel
index 8ec1cb6..d4ec42b 100644
--- a/bintool/BUILD.bazel
+++ b/bintool/BUILD.bazel
@@ -24,10 +24,6 @@
         "HAS_MBEDTLS=1",  # Bazel build always has mbedtls.
     ],
     includes = ["."],
-    # In the CMake build, there's a workaround where this library is built with
-    # NO_PICO_PLATFORM, but that define shouldn't propagate to other
-    # dependencies.
-    local_defines = ["NO_PICO_PLATFORM=1"],
     deps = [
         "//elf",
         "//errors",
diff --git a/bintool/CMakeLists.txt b/bintool/CMakeLists.txt
index 4e3edb5..0c3bebf 100644
--- a/bintool/CMakeLists.txt
+++ b/bintool/CMakeLists.txt
@@ -3,7 +3,6 @@
     add_library(bintool STATIC
             bintool.cpp)
     target_compile_definitions(bintool PRIVATE
-            NO_PICO_PLATFORM=1
             HAS_MBEDTLS=0
             )
 
@@ -18,7 +17,6 @@
             bintool.cpp
             mbedtls_wrapper.c)
     target_compile_definitions(bintool PRIVATE
-            NO_PICO_PLATFORM=1
             HAS_MBEDTLS=1
             )
 
diff --git a/bintool/bintool.cpp b/bintool/bintool.cpp
index 26b8b42..5a7f702 100644
--- a/bintool/bintool.cpp
+++ b/bintool/bintool.cpp
@@ -687,22 +687,52 @@
 }
 
 
-std::vector<uint8_t> get_lm_hash_data(elf_file *elf, block *new_block, bool clear_sram = false) {
+bool detect_generic_load_map(std::shared_ptr<load_map_item> load_map, model_t model, bool &pin_xip_sram) {
+    if (load_map == nullptr) {
+        return false;
+    }
+
+    // generic xip pinning from the SDK
+    pin_xip_sram = load_map->entries.size() == 1
+        && load_map->entries[0].storage_address == 0x0
+        && load_map->entries[0].runtime_address == model->xip_sram_start()
+        && load_map->entries[0].size == 0x0;
+    return pin_xip_sram;
+}
+
+
+std::vector<uint8_t> get_lm_hash_data(elf_file *elf, block *new_block, model_t model, bool clear_sram = false, bool pin_xip_sram = false) {
     std::vector<uint8_t> to_hash;
     std::shared_ptr<load_map_item> load_map = new_block->get_item<load_map_item>();
+    if (detect_generic_load_map(load_map, model, pin_xip_sram)) {
+        new_block->items.erase(std::remove(new_block->items.begin(), new_block->items.end(), load_map), new_block->items.end());
+        load_map = nullptr;
+    }
     if (load_map == nullptr) {
         std::vector<load_map_item::entry> entries;
         if (clear_sram) {
             // todo tidy up this way of hashing the uint32_t
-            std::vector<uint32_t> sram_size_vec = {SRAM_END_RP2350 - SRAM_START};
+            std::vector<uint32_t> sram_size_vec = {model->sram_end() - model->sram_start()};
             entries.push_back({
                 0x0,
-                SRAM_START,
+                model->sram_start(),
                 sram_size_vec[0]
             });
             auto sram_size_data = words_to_lsb_bytes(sram_size_vec.begin(), sram_size_vec.end());
             std::copy(sram_size_data.begin(), sram_size_data.end(), std::back_inserter(to_hash));
-            DEBUG_LOG("CLEAR %08x + %08x\n", (int)SRAM_START, (int)sram_size_vec[0]);
+            DEBUG_LOG("CLEAR %08x + %08x\n", (int)model->sram_start(), (int)sram_size_vec[0]);
+        }
+        if (pin_xip_sram) {
+            // todo tidy up this way of hashing the uint32_t
+            std::vector<uint32_t> xip_pin_size_vec = {0x0};
+            entries.push_back({
+                0x0,
+                model->xip_sram_start(),
+                xip_pin_size_vec[0]
+            });
+            auto xip_pin_size_data = words_to_lsb_bytes(xip_pin_size_vec.begin(), xip_pin_size_vec.end());
+            std::copy(xip_pin_size_data.begin(), xip_pin_size_data.end(), std::back_inserter(to_hash));
+            DEBUG_LOG("PIN XIP SRAM %08x + %08x\n", (int)model->xip_sram_start(), (int)xip_pin_size_vec[0]);
         }
         for(const auto &seg : sorted_segs(elf)) {
             if (!seg->is_load()) continue;
@@ -761,24 +791,41 @@
 }
 
 
-std::vector<uint8_t> get_lm_hash_data(std::vector<uint8_t> bin, uint32_t storage_addr, uint32_t runtime_addr, block *new_block, get_more_bin_cb more_cb, bool clear_sram = false) {
+std::vector<uint8_t> get_lm_hash_data(std::vector<uint8_t> bin, uint32_t storage_addr, uint32_t runtime_addr, block *new_block, get_more_bin_cb more_cb, model_t model, bool clear_sram = false, bool pin_xip_sram = false) {
     std::vector<uint8_t> to_hash;
     std::shared_ptr<load_map_item> load_map = new_block->get_item<load_map_item>();
+    if (detect_generic_load_map(load_map, model, pin_xip_sram)) {
+        new_block->items.erase(std::remove(new_block->items.begin(), new_block->items.end(), load_map), new_block->items.end());
+        load_map = nullptr;
+    }
     if (load_map == nullptr) {
-        to_hash.insert(to_hash.begin(), bin.begin(), bin.end());
         std::vector<load_map_item::entry> entries;
         if (clear_sram) {
-            // todo gate this clearing of SRAM
-            std::vector<uint32_t> sram_size_vec = {0x00082000};
+            // todo tidy up this way of hashing the uint32_t
+            std::vector<uint32_t> sram_size_vec = {model->sram_end() - model->sram_start()};
             assert(sram_size_vec[0] % 4 == 0);
             entries.push_back({
                 0x0,
-                0x20000000,
+                model->sram_start(),
                 sram_size_vec[0]
             });
             auto sram_size_data = words_to_lsb_bytes(sram_size_vec.begin(), sram_size_vec.end());
-            to_hash.insert(to_hash.begin(), sram_size_data.begin(), sram_size_data.end());
+            std::copy(sram_size_data.begin(), sram_size_data.end(), std::back_inserter(to_hash));
+            DEBUG_LOG("CLEAR %08x + %08x\n", (int)model->sram_start(), (int)sram_size_vec[0]);
         }
+        if (pin_xip_sram) {
+            // todo tidy up this way of hashing the uint32_t
+            std::vector<uint32_t> xip_pin_size_vec = {0x0};
+            entries.push_back({
+                0x0,
+                model->xip_sram_start(),
+                xip_pin_size_vec[0]
+            });
+            auto xip_pin_size_data = words_to_lsb_bytes(xip_pin_size_vec.begin(), xip_pin_size_vec.end());
+            std::copy(xip_pin_size_data.begin(), xip_pin_size_data.end(), std::back_inserter(to_hash));
+            DEBUG_LOG("PIN XIP SRAM %08x + %08x\n", (int)model->xip_sram_start(), (int)xip_pin_size_vec[0]);
+        }
+        to_hash.insert(to_hash.begin(), bin.begin(), bin.end());
         DEBUG_LOG("HASH %08x + %08x\n", (int)storage_addr, (int)bin.size());
         entries.push_back(
             {
@@ -823,8 +870,8 @@
 }
 
 
-int hash_andor_sign(elf_file *elf, block *new_block, const public_t public_key, const private_t private_key, bool hash_value, bool sign, bool clear_sram) {
-    std::vector<uint8_t> to_hash = get_lm_hash_data(elf, new_block, clear_sram);
+int hash_andor_sign(elf_file *elf, block *new_block, const public_t public_key, const private_t private_key, model_t model, bool hash_value, bool sign, bool clear_sram, bool pin_xip_sram) {
+    std::vector<uint8_t> to_hash = get_lm_hash_data(elf, new_block, model, clear_sram, pin_xip_sram);
 
     hash_andor_sign_block(new_block, public_key, private_key, hash_value, sign, to_hash);
     
@@ -858,8 +905,8 @@
 }
 
 
-std::vector<uint8_t> hash_andor_sign(std::vector<uint8_t> bin, uint32_t storage_addr, uint32_t runtime_addr, block *new_block, const public_t public_key, const private_t private_key, bool hash_value, bool sign, bool clear_sram) {
-    std::vector<uint8_t> to_hash = get_lm_hash_data(bin, storage_addr, runtime_addr, new_block, nullptr, clear_sram);
+std::vector<uint8_t> hash_andor_sign(std::vector<uint8_t> bin, uint32_t storage_addr, uint32_t runtime_addr, block *new_block, const public_t public_key, const private_t private_key, model_t model, bool hash_value, bool sign, bool clear_sram, bool pin_xip_sram) {
+    std::vector<uint8_t> to_hash = get_lm_hash_data(bin, storage_addr, runtime_addr, new_block, nullptr, model, clear_sram, pin_xip_sram);
 
     hash_andor_sign_block(new_block, public_key, private_key, hash_value, sign, to_hash);
 
@@ -872,7 +919,7 @@
 }
 
 
-void verify_block(std::vector<uint8_t> bin, uint32_t storage_addr, uint32_t runtime_addr, block *block, verified_t &hash_verified, verified_t &sig_verified, get_more_bin_cb more_cb) {
+void verify_block(std::vector<uint8_t> bin, uint32_t storage_addr, uint32_t runtime_addr, block *block, model_t model, verified_t &hash_verified, verified_t &sig_verified, get_more_bin_cb more_cb) {
     std::shared_ptr<load_map_item> load_map = block->get_item<load_map_item>();
     std::shared_ptr<hash_def_item> hash_def = block->get_item<hash_def_item>();
     hash_verified = none;
@@ -880,7 +927,7 @@
     if (load_map == nullptr || hash_def == nullptr) {
         return;
     }
-    std::vector<uint8_t> to_hash = get_lm_hash_data(bin, storage_addr, runtime_addr, block, more_cb, false);
+    std::vector<uint8_t> to_hash = get_lm_hash_data(bin, storage_addr, runtime_addr, block, more_cb, model);
 
     // auto it = std::find(block->items.begin(), block->items.end(), hash_def);
     // assert (it != block->items.end());
@@ -941,8 +988,8 @@
 }
 
 
-void encrypt_guts(elf_file *elf, block *new_block, const aes_key_t aes_key, std::vector<uint8_t> &iv_data, std::vector<uint8_t> &enc_data) {
-    std::vector<uint8_t> to_enc = get_lm_hash_data(elf, new_block);
+void encrypt_guts(elf_file *elf, block *new_block, const aes_key_t aes_key, model_t model, std::vector<uint8_t> &iv_data, std::vector<uint8_t> &enc_data) {
+    std::vector<uint8_t> to_enc = get_lm_hash_data(elf, new_block, model);
 
     std::random_device rand{};
     assert(rand.max() - rand.min() >= 256);
@@ -966,11 +1013,11 @@
 }
 
 
-int encrypt(elf_file *elf, block *new_block, const aes_key_t aes_key, const public_t public_key, const private_t private_key, std::vector<uint8_t> iv_salt, bool hash_value, bool sign) {
+int encrypt(elf_file *elf, block *new_block, const aes_key_t aes_key, const public_t public_key, const private_t private_key, model_t model, std::vector<uint8_t> iv_salt, bool hash_value, bool sign) {
 
     std::vector<uint8_t> iv_data;
     std::vector<uint8_t> enc_data;
-    encrypt_guts(elf, new_block, aes_key, iv_data, enc_data);
+    encrypt_guts(elf, new_block, aes_key, model, iv_data, enc_data);
 
     // Salt IV
     assert(iv_data.size() == iv_salt.size());
@@ -1054,13 +1101,13 @@
         new_block->items.erase(std::remove(new_block->items.begin(), new_block->items.end(), load_map), new_block->items.end());
     }
 
-    hash_andor_sign(elf, new_block, public_key, private_key, hash_value, sign);
+    hash_andor_sign(elf, new_block, public_key, private_key, model, hash_value, sign);
 
     return 0;
 }
 
 
-std::vector<uint8_t> encrypt(std::vector<uint8_t> bin, uint32_t storage_addr, uint32_t runtime_addr, block *new_block, const aes_key_t aes_key, const public_t public_key, const private_t private_key, std::vector<uint8_t> iv_salt, bool hash_value, bool sign) {
+std::vector<uint8_t> encrypt(std::vector<uint8_t> bin, uint32_t storage_addr, uint32_t runtime_addr, block *new_block, const aes_key_t aes_key, const public_t public_key, const private_t private_key, model_t model, std::vector<uint8_t> iv_salt, bool hash_value, bool sign) {
     std::random_device rand{};
     assert(rand.max() - rand.min() >= 256);
 
@@ -1114,6 +1161,6 @@
         new_block->items.erase(std::remove(new_block->items.begin(), new_block->items.end(), load_map), new_block->items.end());
     }
 
-    return hash_andor_sign(bin, storage_addr, runtime_addr, new_block, public_key, private_key, hash_value, sign);;
+    return hash_andor_sign(bin, storage_addr, runtime_addr, new_block, public_key, private_key, model, hash_value, sign);
 }
 #endif
diff --git a/bintool/bintool.h b/bintool/bintool.h
index 20029ac..90b4c0b 100644
--- a/bintool/bintool.h
+++ b/bintool/bintool.h
@@ -7,6 +7,7 @@
 #endif
 #include "elf_file.h"
 #include "metadata.h"
+#include "model.h"
 
 typedef enum verified_t {
     none,
@@ -24,9 +25,9 @@
 std::unique_ptr<block> find_first_block(elf_file *elf);
 block place_new_block(elf_file *elf, std::unique_ptr<block> &first_block, bool set_others_ignored=false);
 #if HAS_MBEDTLS
-    int hash_andor_sign(elf_file *elf, block *new_block, const public_t public_key, const private_t private_key, bool hash_value, bool sign, bool clear_sram = false);
-    void encrypt_guts(elf_file *elf, block *new_block, const aes_key_t aes_key, std::vector<uint8_t> &iv_data, std::vector<uint8_t> &enc_data);
-    int encrypt(elf_file *elf, block *new_block, const aes_key_t aes_key, const public_t public_key, const private_t private_key, std::vector<uint8_t> iv_salt, bool hash_value, bool sign);
+    int hash_andor_sign(elf_file *elf, block *new_block, const public_t public_key, const private_t private_key, model_t model, bool hash_value, bool sign, bool clear_sram = false, bool pin_xip_sram = false);
+    void encrypt_guts(elf_file *elf, block *new_block, const aes_key_t aes_key, model_t model, std::vector<uint8_t> &iv_data, std::vector<uint8_t> &enc_data);
+    int encrypt(elf_file *elf, block *new_block, const aes_key_t aes_key, const public_t public_key, const private_t private_key, model_t model, std::vector<uint8_t> iv_salt, bool hash_value, bool sign);
 #endif
 
 // Bins
@@ -37,7 +38,7 @@
 block place_new_block(std::vector<uint8_t> &bin, uint32_t storage_addr, std::unique_ptr<block> &first_block, bool set_others_ignored=false);
 uint32_t calc_checksum(std::vector<uint8_t> bin);
 #if HAS_MBEDTLS
-    std::vector<uint8_t> hash_andor_sign(std::vector<uint8_t> bin, uint32_t storage_addr, uint32_t runtime_addr, block *new_block, const public_t public_key, const private_t private_key, bool hash_value, bool sign, bool clear_sram = false);
-    std::vector<uint8_t> encrypt(std::vector<uint8_t> bin, uint32_t storage_addr, uint32_t runtime_addr, block *new_block, const aes_key_t aes_key, const public_t public_key, const private_t private_key, std::vector<uint8_t> iv_salt, bool hash_value, bool sign);
-    void verify_block(std::vector<uint8_t> bin, uint32_t storage_addr, uint32_t runtime_addr, block *block, verified_t &hash_verified, verified_t &sig_verified, get_more_bin_cb more_cb = nullptr);
+    std::vector<uint8_t> hash_andor_sign(std::vector<uint8_t> bin, uint32_t storage_addr, uint32_t runtime_addr, block *new_block, const public_t public_key, const private_t private_key, model_t model, bool hash_value, bool sign, bool clear_sram = false, bool pin_xip_sram = false);
+    std::vector<uint8_t> encrypt(std::vector<uint8_t> bin, uint32_t storage_addr, uint32_t runtime_addr, block *new_block, const aes_key_t aes_key, const public_t public_key, const private_t private_key, model_t model, std::vector<uint8_t> iv_salt, bool hash_value, bool sign);
+    void verify_block(std::vector<uint8_t> bin, uint32_t storage_addr, uint32_t runtime_addr, block *block, model_t model, verified_t &hash_verified, verified_t &sig_verified, get_more_bin_cb more_cb = nullptr);
 #endif
diff --git a/main.cpp b/main.cpp
index dbd573b..f11cb3d 100644
--- a/main.cpp
+++ b/main.cpp
@@ -549,6 +549,7 @@
         bool hash = false;
         bool sign = false;
         bool clear_sram = false;
+        bool pin_xip_sram = false;
         bool set_tbyb = false;
         uint16_t major_version = 0;
         uint16_t minor_version = 0;
@@ -561,6 +562,7 @@
         bool otp_key_page_set = false;
         bool fast_rosc = false;
         bool use_mbedtls = false;
+        bool no_clear_sram = false;
         uint16_t otp_key_page = 29;
     } encrypt;
 
@@ -918,7 +920,9 @@
             ).force_expand_help(true) +
             (
                 option("--hash").set(settings.seal.hash) % "Hash the encrypted file" +
-                option("--sign").set(settings.seal.sign) % "Sign the encrypted file"
+                option("--sign").set(settings.seal.sign) % "Sign the encrypted file" +
+                option("--no-clear").set(settings.encrypt.no_clear_sram) % "Don't clear all of main SRAM on load" +
+                option("--pin-xip-sram").set(settings.seal.pin_xip_sram) % "Pin XIP SRAM on load"
             ).min(0).doc_non_optional(true) % "Signing Configuration" +
             named_file_selection_x("infile", 0) % "File to load from" +
             (
@@ -950,7 +954,8 @@
             (
                 option("--hash").set(settings.seal.hash) % "Hash the file" +
                 option("--sign").set(settings.seal.sign) % "Sign the file" +
-                option("--clear").set(settings.seal.clear_sram) % "Clear all of SRAM on load"
+                option("--clear").set(settings.seal.clear_sram) % "Clear all of main SRAM on load" +
+                option("--pin-xip-sram").set(settings.seal.pin_xip_sram) % "Pin XIP SRAM on load"
             ).min(0).doc_non_optional(true) % "Configuration" +
             named_file_selection_x("infile", 0) % "File to load from" +
             (
@@ -3336,7 +3341,7 @@
             verified_t sig_verified = none;
         #if HAS_MBEDTLS
             // Pass empty bin, which will be populated by more_cb if there is a signature/hash_value
-            verify_block({}, raw_access.get_binary_start(), raw_access.get_binary_start(), current_block, hash_verified, sig_verified, more_cb);
+            verify_block({}, raw_access.get_binary_start(), raw_access.get_binary_start(), current_block, raw_access.get_model(), hash_verified, sig_verified, more_cb);
         #endif
 
             // Addresses
@@ -5062,7 +5067,7 @@
 
 
 #if HAS_MBEDTLS
-void sign_guts_elf(elf_file* elf, private_t private_key, public_t public_key) {
+void sign_guts_elf(elf_file* elf, private_t private_key, public_t public_key, model_t model) {
     std::unique_ptr<block> first_block = find_first_block(elf);
     if (!first_block) {
         // Throw a clearer error for RP2040 binaries with no block loop
@@ -5147,8 +5152,9 @@
 
     hash_andor_sign(
         elf, &new_block, public_key, private_key,
+        model,
         settings.seal.hash, settings.seal.sign,
-        settings.seal.clear_sram
+        settings.seal.clear_sram, settings.seal.pin_xip_sram
     );
 }
 
@@ -5217,8 +5223,9 @@
     auto sig_data = hash_andor_sign(
         bin, bin_start, bin_start,
         &new_block, public_key, private_key,
+        in.get_model(),
         settings.seal.hash, settings.seal.sign,
-        settings.seal.clear_sram
+        settings.seal.clear_sram, settings.seal.pin_xip_sram
     );
 
     return sig_data;
@@ -5232,6 +5239,9 @@
     bool keyIsShare = false;
     bool ivFromFile = true;
 
+    // Set settings.seal.clear_sram to opposite of settings.encrypt.no_clear_sram
+    settings.seal.clear_sram = !settings.encrypt.no_clear_sram;
+
     aes_key_t aes_key;
     aes_key_share_t aes_key_share;
     std::vector<uint8_t> iv_salt;
@@ -5416,11 +5426,13 @@
             new_block.items.erase(std::remove(new_block.items.begin(), new_block.items.end(), load_map), new_block.items.end());
         }
 
+        model_t model = get_model(0);
+
         if (settings.encrypt.embed) {
             std::vector<uint8_t> iv_data;
             std::vector<uint8_t> enc_data;
             uint32_t data_start_address = SRAM_START;
-            encrypt_guts(elf, &new_block, aes_key, iv_data, enc_data);
+            encrypt_guts(elf, &new_block, aes_key, model, iv_data, enc_data);
 
             // Salt IV
             assert(iv_data.size() == iv_salt.size());
@@ -5433,7 +5445,7 @@
 
             auto program = get_iostream_memory_access<iostream_memory_access>(tmp, filetype::elf, true);
             // todo should be determined from image_def
-            program.set_model(std::make_shared<model_rp2350>());
+            program.set_model(model);
 
             // data_start_addr
             settings.config.key = "data_start_addr";
@@ -5513,14 +5525,13 @@
             }
 
             // Sign the final thing
-            settings.seal.clear_sram = true;
-            sign_guts_elf(enc_elf, private_key, public_key);
+            sign_guts_elf(enc_elf, private_key, public_key, model);
 
             auto out = get_file_idx(ios::out|ios::binary, 1);
             enc_elf->write(out);
             out->close();
         } else {
-            encrypt(elf, &new_block, aes_key, public_key, private_key, iv_salt, settings.seal.hash, settings.seal.sign);
+            encrypt(elf, &new_block, aes_key, public_key, private_key, model, iv_salt, settings.seal.hash, settings.seal.sign);
             auto out = get_file_idx(ios::out|ios::binary, 1);
             elf->write(out);
             out->close();
@@ -5548,7 +5559,7 @@
             new_block.items.erase(std::remove(new_block.items.begin(), new_block.items.end(), load_map), new_block.items.end());
         }
 
-        auto enc_data = encrypt(bin, bin_start, bin_start, &new_block, aes_key, public_key, private_key, iv_salt, settings.seal.hash, settings.seal.sign);
+        auto enc_data = encrypt(bin, bin_start, bin_start, &new_block, aes_key, public_key, private_key, binfile.get_model(), iv_salt, settings.seal.hash, settings.seal.sign);
 
         auto out = get_file_idx(ios::out|ios::binary, 1);
         out->write((const char *)enc_data.data(), enc_data.size());
@@ -5752,7 +5763,7 @@
         elf->read_file(get_file(ios::in|ios::binary));
         // Remove any holes in the ELF file, as these cause issues when signing/hashing
         elf->remove_sh_holes();
-        sign_guts_elf(elf, private_key, public_key);
+        sign_guts_elf(elf, private_key, public_key, get_model(0));
 
         auto out = get_file_idx(ios::out|ios::binary, 1);
         elf->write(out);
@@ -8343,7 +8354,7 @@
     elf_file source_file(settings.verbose);
     elf_file *elf = &source_file;
     elf->read_file(tmp);
-    sign_guts_elf(elf, private_key, public_key);
+    sign_guts_elf(elf, private_key, public_key, program.get_model());
     auto out = std::make_shared<std::stringstream>();
     elf->write(out);
 
diff --git a/model/model.h b/model/model.h
index e17e33c..17bf824 100644
--- a/model/model.h
+++ b/model/model.h
@@ -383,6 +383,7 @@
     address_ranges ranges;
     ranges.emplace_back(model->flash_start(), model->flash_end(), address_range::type::CONTENTS);
     ranges.emplace_back(model->sram_start(), model->sram_end(), address_range::type::NO_CONTENTS);
+    ranges.emplace_back(model->xip_sram_start(), model->xip_sram_end(), address_range::type::NO_CONTENTS);
     if (model->chip() == rp2040) {
         ranges.emplace_back(MAIN_RAM_BANKED_START, MAIN_RAM_BANKED_END, address_range::type::NO_CONTENTS);
     }