Repository: probe-rs/probe-rs
Pull request #2475 (2024-05-18 18:46:57)

Chip autodetection framework
Implemented for ATSAM D21 (DA1) and D51 (E51, E53, E54) series and all the supported Espressif chips, slightly scrappy but illustrates most of what I had in mind.

ARM parts are a bit hacky with the known hard-wired AP address but improving that needs some more flexibility from the ARM probe impl. Also my ATSAM devices all use MemAp 0 so I think it's not an unfair assumption to make in the specific impl.

Cc #2449 although not closing that as device support needs to be added in later.

There are some SAMDA1 devices we recognise but don't support. I suspect the yaml is older than the documentation I found, but updating the target is out of scope of this PR.


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 22b66324..f52814ea 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -496,9 +496,9 @@ dependencies = [
 
 [[package]]
 name = "clap_complete"
-version = "4.5.5"
+version = "4.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2020fa13af48afc65a9a87335bda648309ab3d154cd03c7ff95b378c7ed39c4"
+checksum = "fbca90c87c2a04da41e95d1856e8bcd22f159bdbfa147314d2ce5218057b0e58"
 dependencies = [
  "clap",
 ]
@@ -1489,19 +1489,21 @@ dependencies = [
 
 [[package]]
 name = "hyper-rustls"
-version = "0.26.0"
+version = "0.27.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c"
+checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155"
 dependencies = [
  "futures-util",
  "http",
  "hyper",
  "hyper-util",
  "rustls",
+ "rustls-native-certs",
  "rustls-pki-types",
  "tokio",
  "tokio-rustls",
  "tower-service",
+ "webpki-roots",
 ]
 
 [[package]]
@@ -1524,124 +1526,6 @@ dependencies = [
  "tracing",
 ]
 
-[[package]]
-name = "icu_collections"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
-dependencies = [
- "displaydoc",
- "yoke",
- "zerofrom",
- "zerovec",
-]
-
-[[package]]
-name = "icu_locid"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
-dependencies = [
- "displaydoc",
- "litemap",
- "tinystr",
- "writeable",
- "zerovec",
-]
-
-[[package]]
-name = "icu_locid_transform"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e"
-dependencies = [
- "displaydoc",
- "icu_locid",
- "icu_locid_transform_data",
- "icu_provider",
- "tinystr",
- "zerovec",
-]
-
-[[package]]
-name = "icu_locid_transform_data"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e"
-
-[[package]]
-name = "icu_normalizer"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
-dependencies = [
- "displaydoc",
- "icu_collections",
- "icu_normalizer_data",
- "icu_properties",
- "icu_provider",
- "smallvec",
- "utf16_iter",
- "utf8_iter",
- "write16",
- "zerovec",
-]
-
-[[package]]
-name = "icu_normalizer_data"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
-
-[[package]]
-name = "icu_properties"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f8ac670d7422d7f76b32e17a5db556510825b29ec9154f235977c9caba61036"
-dependencies = [
- "displaydoc",
- "icu_collections",
- "icu_locid_transform",
- "icu_properties_data",
- "icu_provider",
- "tinystr",
- "zerovec",
-]
-
-[[package]]
-name = "icu_properties_data"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
-
-[[package]]
-name = "icu_provider"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
-dependencies = [
- "displaydoc",
- "icu_locid",
- "icu_provider_macros",
- "stable_deref_trait",
- "tinystr",
- "writeable",
- "yoke",
- "zerofrom",
- "zerovec",
-]
-
-[[package]]
-name = "icu_provider_macros"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.60",
-]
-
 [[package]]
 name = "ident_case"
 version = "1.0.1"
@@ -1650,14 +1534,12 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
 
 [[package]]
 name = "idna"
-version = "1.0.0"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4716a3a0933a1d01c2f72450e89596eb51dd34ef3c211ccd875acdf1f8fe47ed"
+checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
 dependencies = [
- "icu_normalizer",
- "icu_properties",
- "smallvec",
- "utf8_iter",
+ "unicode-bidi",
+ "unicode-normalization",
 ]
 
 [[package]]
@@ -1907,12 +1789,6 @@ version = "0.4.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
 
-[[package]]
-name = "litemap"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704"
-
 [[package]]
 name = "lock_api"
 version = "0.4.11"
@@ -2066,9 +1942,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
 
 [[package]]
 name = "miniz_oxide"
-version = "0.7.3"
+version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae"
+checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
 dependencies = [
  "adler",
 ]
@@ -2394,6 +2270,12 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
 
+[[package]]
+name = "ppv-lite86"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+
 [[package]]
 name = "predicates"
 version = "3.1.0"
@@ -2612,6 +2494,53 @@ dependencies = [
  "memchr",
 ]
 
+[[package]]
+name = "quinn"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e4ceeeeabace7857413798eb1ffa1e9c905a9946a57d81fb69b4b71c4d8eb3ad"
+dependencies = [
+ "bytes",
+ "pin-project-lite",
+ "quinn-proto",
+ "quinn-udp",
+ "rustc-hash",
+ "rustls",
+ "thiserror",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "quinn-proto"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ddf517c03a109db8100448a4be38d498df8a210a99fe0e1b9eaf39e78c640efe"
+dependencies = [
+ "bytes",
+ "rand",
+ "ring",
+ "rustc-hash",
+ "rustls",
+ "slab",
+ "thiserror",
+ "tinyvec",
+ "tracing",
+]
+
+[[package]]
+name = "quinn-udp"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9096629c45860fc7fb143e125eb826b5e721e10be3263160c7d60ca832cf8c46"
+dependencies = [
+ "libc",
+ "once_cell",
+ "socket2",
+ "tracing",
+ "windows-sys 0.52.0",
+]
+
 [[package]]
 name = "quote"
 version = "1.0.36"
@@ -2627,6 +2556,36 @@ version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
 
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom",
+]
+
 [[package]]
 name = "ratatui"
 version = "0.26.3"
@@ -2713,9 +2672,9 @@ checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
 
 [[package]]
 name = "reqwest"
-version = "0.12.4"
+version = "0.12.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10"
+checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37"
 dependencies = [
  "base64",
  "bytes",
@@ -2734,6 +2693,7 @@ dependencies = [
  "once_cell",
  "percent-encoding",
  "pin-project-lite",
+ "quinn",
  "rustls",
  "rustls-native-certs",
  "rustls-pemfile",
@@ -2814,6 +2774,12 @@ version = "0.1.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
 
+[[package]]
+name = "rustc-hash"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
 [[package]]
 name = "rustix"
 version = "0.38.34"
@@ -2829,11 +2795,11 @@ dependencies = [
 
 [[package]]
 name = "rustls"
-version = "0.22.4"
+version = "0.23.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432"
+checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402"
 dependencies = [
- "log",
+ "once_cell",
  "ring",
  "rustls-pki-types",
  "rustls-webpki",
@@ -2866,15 +2832,15 @@ dependencies = [
 
 [[package]]
 name = "rustls-pki-types"
-version = "1.5.0"
+version = "1.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "beb461507cee2c2ff151784c52762cf4d9ff6a61f3e80968600ed24fa837fa54"
+checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d"
 
 [[package]]
 name = "rustls-webpki"
-version = "0.102.3"
+version = "0.102.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3bce581c0dd41bce533ce695a1437fa16a7ab5ac3ccfa99fe1a620a7885eabf"
+checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e"
 dependencies = [
  "ring",
  "rustls-pki-types",
@@ -3382,20 +3348,9 @@ dependencies = [
 
 [[package]]
 name = "sync_wrapper"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
-
-[[package]]
-name = "synstructure"
-version = "0.13.1"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.60",
-]
+checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
 
 [[package]]
 name = "tap"
@@ -3583,15 +3538,20 @@ dependencies = [
 ]
 
 [[package]]
-name = "tinystr"
-version = "0.7.6"
+name = "tinyvec"
+version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
+checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
 dependencies = [
- "displaydoc",
- "zerovec",
+ "tinyvec_macros",
 ]
 
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+
 [[package]]
 name = "tokio"
 version = "1.38.0"
@@ -3622,9 +3582,9 @@ dependencies = [
 
 [[package]]
 name = "tokio-rustls"
-version = "0.25.0"
+version = "0.26.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
+checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
 dependencies = [
  "rustls",
  "rustls-pki-types",
@@ -3864,6 +3824,12 @@ dependencies = [
  "version_check",
 ]
 
+[[package]]
+name = "unicode-bidi"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
+
 [[package]]
 name = "unicode-ident"
 version = "1.0.12"
@@ -3876,6 +3842,15 @@ version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
 
+[[package]]
+name = "unicode-normalization"
+version = "0.1.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
+dependencies = [
+ "tinyvec",
+]
+
 [[package]]
 name = "unicode-segmentation"
 version = "1.11.0"
@@ -3922,9 +3897,9 @@ dependencies = [
 
 [[package]]
 name = "url"
-version = "2.5.1"
+version = "2.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7c25da092f0a868cdf09e8674cd3b7ef3a7d92a24253e663a2fb85e2496de56"
+checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
 dependencies = [
  "form_urlencoded",
  "idna",
@@ -3938,18 +3913,6 @@ version = "2.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
 
-[[package]]
-name = "utf16_iter"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
-
-[[package]]
-name = "utf8_iter"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
-
 [[package]]
 name = "utf8parse"
 version = "0.2.1"
@@ -4288,18 +4251,6 @@ dependencies = [
  "windows-sys 0.48.0",
 ]
 
-[[package]]
-name = "write16"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
-
-[[package]]
-name = "writeable"
-version = "0.5.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
-
 [[package]]
 name = "wyz"
 version = "0.5.1"
@@ -4356,30 +4307,6 @@ version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
 
-[[package]]
-name = "yoke"
-version = "0.7.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5"
-dependencies = [
- "serde",
- "stable_deref_trait",
- "yoke-derive",
- "zerofrom",
-]
-
-[[package]]
-name = "yoke-derive"
-version = "0.7.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.60",
- "synstructure",
-]
-
 [[package]]
 name = "zero"
 version = "0.1.3"
@@ -4407,55 +4334,12 @@ dependencies = [
  "syn 2.0.60",
 ]
 
-[[package]]
-name = "zerofrom"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55"
-dependencies = [
- "zerofrom-derive",
-]
-
-[[package]]
-name = "zerofrom-derive"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.60",
- "synstructure",
-]
-
 [[package]]
 name = "zeroize"
 version = "1.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"
 
-[[package]]
-name = "zerovec"
-version = "0.10.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb2cc8827d6c0994478a15c53f374f46fbd41bea663d809b14744bc42e6b109c"
-dependencies = [
- "yoke",
- "zerofrom",
- "zerovec-derive",
-]
-
-[[package]]
-name = "zerovec-derive"
-version = "0.10.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.60",
-]
-
 [[package]]
 name = "zip"
 version = "2.1.3"
diff --git a/changelog/added-STM32F205RGEx.md b/changelog/added-STM32F205RGEx.md
new file mode 100644
index 00000000..50799011
--- /dev/null
+++ b/changelog/added-STM32F205RGEx.md
@@ -0,0 +1,1 @@
+Added STM32F205RGEx target information
\ No newline at end of file
diff --git a/changelog/added-chip-identification.md b/changelog/added-chip-identification.md
new file mode 100644
index 00000000..72b27d21
--- /dev/null
+++ b/changelog/added-chip-identification.md
@@ -0,0 +1,1 @@
+`probe-rs` can now automatically detect nRF, ESP32 and certain ATSAM devices without `--chip`
\ No newline at end of file
diff --git a/changelog/added-memory-access.md b/changelog/added-memory-access.md
new file mode 100644
index 00000000..766955ed
--- /dev/null
+++ b/changelog/added-memory-access.md
@@ -0,0 +1,1 @@
+Added `MemoryAccess` attributes to `RamRegion`, `NvmRegion` and `GenericRegion`
\ No newline at end of file
diff --git a/changelog/changed-flash-algo-stack.md b/changelog/changed-flash-algo-stack.md
new file mode 100644
index 00000000..7695822b
--- /dev/null
+++ b/changelog/changed-flash-algo-stack.md
@@ -0,0 +1,1 @@
+probe-rs no longer reserves all remaining memory for the flash algorithm's stack.
\ No newline at end of file
diff --git a/changelog/changed-is-boot-memory.md b/changelog/changed-is-boot-memory.md
new file mode 100644
index 00000000..3b626784
--- /dev/null
+++ b/changelog/changed-is-boot-memory.md
@@ -0,0 +1,1 @@
+Moved `RamRegion::is_boot_memory` to `MemoryAccess::boot`
\ No newline at end of file
diff --git a/probe-rs-target/src/chip_detection.rs b/probe-rs-target/src/chip_detection.rs
new file mode 100644
index 00000000..7d1907bb
--- /dev/null
+++ b/probe-rs-target/src/chip_detection.rs
@@ -0,0 +1,111 @@
+//! Chip detection information.
+
+use std::collections::HashMap;
+
+use serde::{Deserialize, Serialize};
+
+/// Vendor-specific chip detection information.
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub enum ChipDetectionMethod {
+    /// Microchip ATSAM chip detection information.
+    AtsamDsu(AtsamDsuDetection),
+
+    /// Espressif chip detection information.
+    Espressif(EspressifDetection),
+
+    /// Nordic Semiconductor FICR CONFIGID-based chip detection information.
+    NordicConfigId(NordicConfigIdDetection),
+
+    /// Nordic Semiconductor FICR INFO-based chip detection information.
+    NordicFicrInfo(NordicFicrDetection),
+}
+
+impl ChipDetectionMethod {
+    /// Returns the ATSAM detection information if available.
+    pub fn as_atsam_dsu(&self) -> Option<&AtsamDsuDetection> {
+        if let Self::AtsamDsu(v) = self {
+            Some(v)
+        } else {
+            None
+        }
+    }
+
+    /// Returns the Espressif detection information if available.
+    pub fn as_espressif(&self) -> Option<&EspressifDetection> {
+        if let Self::Espressif(v) = self {
+            Some(v)
+        } else {
+            None
+        }
+    }
+
+    /// Returns the Nordic CONFIGID detection information if available.
+    pub fn as_nordic_configid(&self) -> Option<&NordicConfigIdDetection> {
+        if let Self::NordicConfigId(v) = self {
+            Some(v)
+        } else {
+            None
+        }
+    }
+
+    /// Returns the Nordic FICR detection information if available.
+    pub fn as_nordic_ficr(&self) -> Option<&NordicFicrDetection> {
+        if let Self::NordicFicrInfo(v) = self {
+            Some(v)
+        } else {
+            None
+        }
+    }
+}
+
+/// Microchip ATSAM chip detection information when the device contains a DSU.
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct AtsamDsuDetection {
+    /// DSU DID register, Processor field
+    pub processor: u8,
+
+    /// DSU DID register, Family field
+    pub family: u8,
+
+    /// DSU DID register, Series field
+    pub series: u8,
+
+    /// Devsel => Target field value
+    pub variants: HashMap<u8, String>,
+}
+
+/// Espressif chip detection information.
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct EspressifDetection {
+    /// Debug module IDCODE
+    pub idcode: u32,
+
+    /// Magic chip value => Target name.
+    pub variants: HashMap<u32, String>,
+}
+
+/// Nordic FICR CONFIGID-based chip detection information.
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct NordicConfigIdDetection {
+    /// FICR CONFIGID address
+    pub configid_address: u32,
+
+    /// CONFIGID.HWID => Target name.
+    pub hwid: HashMap<u32, String>,
+}
+
+/// Nordic FICR INFO-based chip detection information.
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct NordicFicrDetection {
+    /// FICR INFO.PART address
+    pub part_address: u32,
+
+    /// FICR INFO.VARIANT address
+    pub variant_address: u32,
+
+    /// The value of INFO.PART
+    pub part: u32,
+
+    /// INFO.VARIANT => Target name.
+    pub variants: HashMap<u32, String>,
+}
diff --git a/probe-rs-target/src/chip_family.rs b/probe-rs-target/src/chip_family.rs
index 2f0f4ed9..3c6ce539 100644
--- a/probe-rs-target/src/chip_family.rs
+++ b/probe-rs-target/src/chip_family.rs
@@ -1,5 +1,5 @@
 use crate::serialize::hex_jep106_option;
-use crate::CoreAccessOptions;
+use crate::{chip_detection::ChipDetectionMethod, CoreAccessOptions};
 
 use super::chip::Chip;
 use super::flash_algorithm::RawFlashAlgorithm;
@@ -183,6 +183,9 @@ pub struct ChipFamily {
     /// The JEP106 code of the manufacturer.
     #[serde(serialize_with = "hex_jep106_option")]
     pub manufacturer: Option<JEP106Code>,
+    /// The method(s) that may be able to identify targets in this family.
+    #[serde(default)]
+    pub chip_detection: Vec<ChipDetectionMethod>,
     /// The `target-gen` process will set this to `true`.
     /// Please change this to `false` if this file is modified from the generated, or is a manually created target description.
     #[serde(default)]
diff --git a/probe-rs-target/src/lib.rs b/probe-rs-target/src/lib.rs
index ab90f2a6..96e0a414 100644
--- a/probe-rs-target/src/lib.rs
+++ b/probe-rs-target/src/lib.rs
@@ -12,6 +12,7 @@
 //!
 
 mod chip;
+pub mod chip_detection;
 mod chip_family;
 mod flash_algorithm;
 mod flash_properties;
@@ -28,6 +29,6 @@ pub use chip_family::{
 pub use flash_algorithm::{RawFlashAlgorithm, TransferEncoding};
 pub use flash_properties::FlashProperties;
 pub use memory::{
-    GenericRegion, MemoryRange, MemoryRegion, NvmRegion, PageInfo, RamRegion, SectorDescription,
-    SectorInfo,
+    GenericRegion, MemoryAccess, MemoryRange, MemoryRegion, NvmRegion, PageInfo, RamRegion,
+    SectorDescription, SectorInfo,
 };
diff --git a/probe-rs-target/src/memory.rs b/probe-rs-target/src/memory.rs
index 771a67b6..250b9c15 100644
--- a/probe-rs-target/src/memory.rs
+++ b/probe-rs-target/src/memory.rs
@@ -10,14 +10,41 @@ pub struct NvmRegion {
     /// Address range of the region
     #[serde(serialize_with = "hex_range")]
     pub range: Range<u64>,
-    /// True if the chip boots from this memory
-    #[serde(default)]
-    pub is_boot_memory: bool,
     /// List of cores that can access this region
     pub cores: Vec<String>,
     /// True if the memory region is an alias of a different memory region.
     #[serde(default)]
     pub is_alias: bool,
+    /// Access permissions for the region.
+    #[serde(default)]
+    pub access: Option<MemoryAccess>,
+}
+
+impl NvmRegion {
+    /// Returns the access permissions for the region.
+    pub fn access(&self) -> MemoryAccess {
+        self.access.unwrap_or_default()
+    }
+
+    /// Returns whether the region is readable.
+    pub fn is_readable(&self) -> bool {
+        self.access().read
+    }
+
+    /// Returns whether the region is writable.
+    pub fn is_writable(&self) -> bool {
+        self.access().write
+    }
+
+    /// Returns whether the region is executable.
+    pub fn is_executable(&self) -> bool {
+        self.access().execute
+    }
+
+    /// Returns whether the region is boot memory.
+    pub fn is_boot_memory(&self) -> bool {
+        self.access().boot
+    }
 }
 
 impl NvmRegion {
@@ -29,6 +56,38 @@ impl NvmRegion {
     }
 }
 
+fn default_true() -> bool {
+    true
+}
+
+/// Represents access permissions of a region in RAM.
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
+pub struct MemoryAccess {
+    /// True if the region is readable.
+    #[serde(default = "default_true")]
+    pub read: bool,
+    /// True if the region is writable.
+    #[serde(default = "default_true")]
+    pub write: bool,
+    /// True if the region is executable.
+    #[serde(default = "default_true")]
+    pub execute: bool,
+    /// True if the chip boots from this memory
+    #[serde(default)]
+    pub boot: bool,
+}
+
+impl Default for MemoryAccess {
+    fn default() -> Self {
+        MemoryAccess {
+            read: true,
+            write: true,
+            execute: true,
+            boot: false,
+        }
+    }
+}
+
 /// Represents a region in RAM.
 #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
 pub struct RamRegion {
@@ -37,11 +96,38 @@ pub struct RamRegion {
     /// Address range of the region
     #[serde(serialize_with = "hex_range")]
     pub range: Range<u64>,
-    /// True if the chip boots from this memory
-    #[serde(default)]
-    pub is_boot_memory: bool,
     /// List of cores that can access this region
     pub cores: Vec<String>,
+    /// Access permissions for the region.
+    #[serde(default)]
+    pub access: Option<MemoryAccess>,
+}
+
+impl RamRegion {
+    /// Returns the access permissions for the region.
+    pub fn access(&self) -> MemoryAccess {
+        self.access.unwrap_or_default()
+    }
+
+    /// Returns whether the region is readable.
+    pub fn is_readable(&self) -> bool {
+        self.access().read
+    }
+
+    /// Returns whether the region is writable.
+    pub fn is_writable(&self) -> bool {
+        self.access().write
+    }
+
+    /// Returns whether the region is executable.
+    pub fn is_executable(&self) -> bool {
+        self.access().execute
+    }
+
+    /// Returns whether the region is boot memory.
+    pub fn is_boot_memory(&self) -> bool {
+        self.access().boot
+    }
 }
 
 /// Represents a generic region.
@@ -54,6 +140,31 @@ pub struct GenericRegion {
     pub range: Range<u64>,
     /// List of cores that can access this region
     pub cores: Vec<String>,
+    /// Access permissions for the region.
+    #[serde(default)]
+    pub access: Option<MemoryAccess>,
+}
+
+impl GenericRegion {
+    /// Returns the access permissions for the region.
+    pub fn access(&self) -> MemoryAccess {
+        self.access.unwrap_or_default()
+    }
+
+    /// Returns whether the region is readable.
+    pub fn is_readable(&self) -> bool {
+        self.access().read
+    }
+
+    /// Returns whether the region is writable.
+    pub fn is_writable(&self) -> bool {
+        self.access().write
+    }
+
+    /// Returns whether the region is executable.
+    pub fn is_executable(&self) -> bool {
+        self.access().execute
+    }
 }
 
 /// Holds information about a specific, individual flash
diff --git a/probe-rs-tools/src/bin/probe-rs/cmd/dap_server/server/debugger.rs b/probe-rs-tools/src/bin/probe-rs/cmd/dap_server/server/debugger.rs
index ff6e6d32..29f9a917 100644
--- a/probe-rs-tools/src/bin/probe-rs/cmd/dap_server/server/debugger.rs
+++ b/probe-rs-tools/src/bin/probe-rs/cmd/dap_server/server/debugger.rs
@@ -440,21 +440,6 @@ impl Debugger {
             return Err(bad_config);
         }
 
-        if requested_target_session_type == TargetSessionType::AttachRequest {
-            // Since VSCode doesn't do field validation checks for relationships in launch.json request types, check it here.
-            if self.config.flashing_config.flashing_enabled
-                || self.config.flashing_config.halt_after_reset
-                || self.config.flashing_config.full_chip_erase
-                || self.config.flashing_config.restore_unwritten_bytes
-            {
-                let error = DebuggerError::Other(anyhow!(
-                                            "Please do not use any of the `flashing_enabled`, `reset_after_flashing`, halt_after_reset`, `full_chip_erase`, or `restore_unwritten_bytes` options when using `attach` request type."));
-
-                debug_adapter.send_response::<()>(launch_attach_request, Err(&error))?;
-                return Err(error);
-            }
-        }
-
         debug_adapter
             .set_console_log_level(self.config.console_log_level.unwrap_or(ConsoleLog::Console));
 
diff --git a/probe-rs/src/architecture/arm/communication_interface.rs b/probe-rs/src/architecture/arm/communication_interface.rs
index 6909ee16..a183ca1b 100644
--- a/probe-rs/src/architecture/arm/communication_interface.rs
+++ b/probe-rs/src/architecture/arm/communication_interface.rs
@@ -867,7 +867,7 @@ impl DapAccess for ArmCommunicationInterface<Initialized> {
 /// Information about the chip target we are currently attached to.
 /// This can be used for discovery, tho, for now it does not work optimally,
 /// as some manufacturers (e.g. ST Microelectronics) violate the spec and thus need special discovery procedures.
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy)]
 pub struct ArmChipInfo {
     /// The JEP106 code of the manufacturer of this chip target.
     pub manufacturer: JEP106Code,
diff --git a/probe-rs/src/config/registry.rs b/probe-rs/src/config/registry.rs
index a1ef31e5..f98ae049 100644
--- a/probe-rs/src/config/registry.rs
+++ b/probe-rs/src/config/registry.rs
@@ -41,6 +41,7 @@ fn add_generic_targets(vec: &mut Vec<ChipFamily>) {
             manufacturer: None,
             generated_from_pack: false,
             pack_file_release: None,
+            chip_detection: vec![],
             variants: vec![
                 Chip::generic_arm("Cortex-M0", CoreType::Armv6m),
                 Chip::generic_arm("Cortex-M0+", CoreType::Armv6m),
@@ -55,6 +56,7 @@ fn add_generic_targets(vec: &mut Vec<ChipFamily>) {
             manufacturer: None,
             generated_from_pack: false,
             pack_file_release: None,
+            chip_detection: vec![],
             variants: vec![Chip::generic_arm("Cortex-M3", CoreType::Armv7m)],
             flash_algorithms: vec![],
             source: TargetDescriptionSource::Generic,
@@ -64,6 +66,7 @@ fn add_generic_targets(vec: &mut Vec<ChipFamily>) {
             manufacturer: None,
             generated_from_pack: false,
             pack_file_release: None,
+            chip_detection: vec![],
             variants: vec![
                 Chip::generic_arm("Cortex-M4", CoreType::Armv7em),
                 Chip::generic_arm("Cortex-M7", CoreType::Armv7em),
@@ -76,6 +79,7 @@ fn add_generic_targets(vec: &mut Vec<ChipFamily>) {
             manufacturer: None,
             generated_from_pack: false,
             pack_file_release: None,
+            chip_detection: vec![],
             variants: vec![
                 Chip::generic_arm("Cortex-M23", CoreType::Armv8m),
                 Chip::generic_arm("Cortex-M33", CoreType::Armv8m),
@@ -90,6 +94,7 @@ fn add_generic_targets(vec: &mut Vec<ChipFamily>) {
             manufacturer: None,
             pack_file_release: None,
             generated_from_pack: false,
+            chip_detection: vec![],
             variants: vec![Chip {
                 name: "riscv".to_owned(),
                 part: None,
diff --git a/probe-rs/src/flashing/builder.rs b/probe-rs/src/flashing/builder.rs
index c8807496..acf0050e 100644
--- a/probe-rs/src/flashing/builder.rs
+++ b/probe-rs/src/flashing/builder.rs
@@ -371,7 +371,7 @@ impl FlashBuilder {
 
 #[cfg(test)]
 mod tests {
-    use probe_rs_target::{FlashProperties, SectorDescription};
+    use probe_rs_target::{FlashProperties, MemoryAccess, SectorDescription};
 
     use super::*;
 
@@ -395,7 +395,10 @@ mod tests {
 
         let region = NvmRegion {
             name: Some("FLASH".into()),
-            is_boot_memory: true,
+            access: Some(MemoryAccess {
+                boot: true,
+                ..Default::default()
+            }),
             range: 0..1 << 16,
             cores: vec!["main".into()],
             is_alias: false,
@@ -424,7 +427,10 @@ mod tests {
 
         let region = NvmRegion {
             name: Some("FLASH".into()),
-            is_boot_memory: true,
+            access: Some(MemoryAccess {
+                boot: true,
+                ..Default::default()
+            }),
             range: 0..1 << 16,
             cores: vec!["main".into()],
             is_alias: false,
diff --git a/probe-rs/src/flashing/flash_algorithm.rs b/probe-rs/src/flashing/flash_algorithm.rs
index 0170a685..275007bf 100644
--- a/probe-rs/src/flashing/flash_algorithm.rs
+++ b/probe-rs/src/flashing/flash_algorithm.rs
@@ -160,7 +160,7 @@ impl FlashAlgorithm {
         true
     }
 
-    const FLASH_ALGO_MIN_STACK_SIZE: u64 = 512;
+    const FLASH_ALGO_STACK_SIZE: u32 = 512;
 
     // Header for RISC-V Flash Algorithms
     const RISCV_FLASH_BLOB_HEADER: [u32; 2] = [riscv::assembly::EBREAK, riscv::assembly::EBREAK];
@@ -274,32 +274,14 @@ impl FlashAlgorithm {
             return Err(FlashError::InvalidFlashAlgorithmLoadAddress { address: addr_load });
         }
 
-        // Memory layout when `data_ram_region == ram_region`:
-        //
-        // Single buffering:
-        //
-        // ++-------------+-----------------------+---------------+ <- RAM region end
-        // || Loader code |         Stack         |  Data buffer  |
-        // ++-------------+-----------------------+---------------+
-        // ^- addr_load   ^- code_end             ^- data_start_addr = stack_top_addr
-        //  ^- code_start                         ^---------------^ buffer_page_size
-        //
-        // Double buffering:
-        //
-        // ++-------------+-------+---------------+---------------+ <- RAM region end
-        // || Loader code | Stack | Data buffer 1 | Data buffer 2 |
-        // ++-------------+-------+---------------+---------------+
-        // ^- addr_load           ^- data_start_addr = stack_top_addr
-        //  ^- code_start         ^---------------^---------------^ buffer_page_size (x2)
-        //                ^- code_end
-        //
-        // Configured stack with single buffer fitting:
-        //
-        // ++-------------+----+------------------+---------------+ <- RAM region end
-        // || Loader code |    |      Stack       |  Data buffer  |
-        // ++-------------+----+------------------+---------------+
-        // ^- addr_load   ^- code_end             ^- data_start_addr = stack_top_addr
-        //  ^- code_start                         ^---------------^ buffer_page_size (x1)
+        // Memory layout:
+        // - Header
+        // - Code
+        // - Data
+        // - Stack
+        // Stack placement depends on the optional `data_load_address` field. If the stack fits
+        // between the code and the data, it will be placed there. Otherwise, it will be placed
+        // after the data.
 
         let code_start = addr_load + header_size;
         let code_size_bytes = (instructions.len() * size_of::<u32>()) as u64;
@@ -307,91 +289,75 @@ impl FlashAlgorithm {
 
         let buffer_page_size = raw.flash_properties.page_size as u64;
 
-        let remaining_ram = ram_region.range.end - code_end;
+        let stack_size = raw.stack_size.unwrap_or(Self::FLASH_ALGO_STACK_SIZE) as u64;
+        tracing::info!("The flash algorithm will be configured with {stack_size} bytes of stack");
 
-        // How much space does a data buffer take up in the current RAM region?
-        // If the data is in a different region, we don't need to account for it for the stack.
-        let buffer_page_size_in_instr_region = if ram_region == data_ram_region {
-            buffer_page_size
+        let data_load_addr = if ram_region == data_ram_region {
+            if let Some(data_load_addr) = raw.data_load_address {
+                data_load_addr
+            } else {
+                // The data is not placed explicitly. We can place it after the code.
+                code_end
+            }
         } else {
-            0
+            // The data is in a different region. We can place it at the start of the region.
+            data_ram_region.range.start
         };
 
-        // Try to find a stack size that fits with at least one page of data.
-        let stack_size = if let Some(configured_stack) = raw.stack_size {
-            // The user has configured a stack size. Let's use it.
-            let stack_size = configured_stack as u64;
+        // Available memory for data depends on where the stack needs to be placed.
+        let mut ram_for_data = data_ram_region.range.end - data_load_addr;
+        if code_end + stack_size > data_load_addr && ram_region == data_ram_region {
+            // Stack can only go after the data, so let's reduce the available size.
+            ram_for_data -= stack_size;
+        }
 
-            // Make sure at least one data page fits into RAM.
-            if buffer_page_size_in_instr_region + stack_size > remaining_ram {
-                // The configured stack size is too large. Let's not try to be too clever about it.
-                return Err(FlashError::InvalidFlashAlgorithmStackSize);
-            }
-            stack_size
+        // To determine the stack bottom, we need to know if the data is double buffered.
+        let double_buffering = if ram_for_data >= 2 * buffer_page_size {
+            // The data may be double buffered
+            // TODO: maybe allow disabling in the target description?
+            true
+        } else if ram_for_data >= buffer_page_size {
+            // The data is not double buffered. Place the stack at the end of the RAM region.
+            false
         } else {
-            // No stack is specified, let's try to use as much as we can.
-            let required_for_double_buffer =
-                2 * buffer_page_size_in_instr_region + Self::FLASH_ALGO_MIN_STACK_SIZE;
-            let required_for_single_buffer =
-                buffer_page_size_in_instr_region + Self::FLASH_ALGO_MIN_STACK_SIZE;
-
-            if remaining_ram >= required_for_double_buffer {
-                // We have space for two pages of data and a stack.
-                remaining_ram - 2 * buffer_page_size_in_instr_region
-            } else if remaining_ram > required_for_single_buffer {
-                // We have space for one page of data and a stack.
-                remaining_ram - buffer_page_size_in_instr_region
-            } else {
-                // We don't have enough space for a stack
-                return Err(FlashError::InvalidFlashAlgorithmStackSize);
-            }
+            // We can't place data and stack.
+            // TODO: this should probably be done in the target validation.
+            // TODO: make the errors a bit more meaningful.
+            return Err(FlashError::InvalidFlashAlgorithmStackSize);
         };
-        tracing::info!("The flash algorithm will be configured with {stack_size} bytes of stack");
 
-        // We have the stack size, let's lay out the data block(s)
-        // Determine the bounds of the data region.
-        let data_load_addr = if let Some(data_load_addr) = raw.data_load_address {
-            data_load_addr
-        } else if ram_region == data_ram_region {
-            let remaining_ram = remaining_ram - stack_size;
-
-            let data_size = if remaining_ram >= 2 * buffer_page_size {
-                2 * buffer_page_size
+        // We need to make sure the blocks don't overlap and we have enough memory.
+        let stack_bottom =
+            if code_end + stack_size <= data_load_addr || ram_region != data_ram_region {
+                // Two cases:
+                // - The stack fits between the code and the data.
+                // - The data is in a different region, so we can place
+                //   the stack at the end of the code region.
+                code_end
             } else {
-                buffer_page_size
+                // The data and the stack are in the same region. There is not enough space
+                // for the stack below the data. Place the stack after the data.
+                let page_count = if double_buffering { 2 } else { 1 };
+                data_load_addr + page_count * buffer_page_size
             };
 
-            ram_region.range.end - data_size
-        } else {
-            data_ram_region.range.start
-        };
-        let data_range = data_load_addr..data_ram_region.range.end;
-
         // Now we can place the stack.
-        let stack_top_addr = if ram_region == data_ram_region {
-            // Under the data...
-            data_range.start
-        } else {
-            // ... or the top of the region if data is in a different region.
-            ram_region.range.end
-        };
-        tracing::info!("Stack top: {:#010X}", stack_top_addr);
+        let stack_top_addr = stack_bottom + stack_size;
+        tracing::info!("Stack top: {:#010x}", stack_top_addr);
 
-        // Data buffer 1
-        let first_buffer_start = data_range.start;
-
-        // Data buffer 2
-        let second_buffer_start = first_buffer_start + buffer_page_size;
-        let second_buffer_end = second_buffer_start + buffer_page_size;
+        if stack_top_addr > ram_region.range.end {
+            return Err(FlashError::InvalidFlashAlgorithmStackSize);
+        }
 
         // Determine whether we can use double buffering or not by the remaining RAM region size.
-        let page_buffers = if second_buffer_end <= data_range.end {
-            vec![first_buffer_start, second_buffer_start]
+        let page_buffers = if double_buffering {
+            let second_buffer_start = data_load_addr + buffer_page_size;
+            vec![data_load_addr, second_buffer_start]
         } else {
-            vec![first_buffer_start]
+            vec![data_load_addr]
         };
 
-        tracing::debug!("Page buffers: {:#010X?}", page_buffers);
+        tracing::debug!("Page buffers: {:#010x?}", page_buffers);
 
         let name = raw.name.clone();
 
diff --git a/probe-rs/src/flashing/flasher.rs b/probe-rs/src/flashing/flasher.rs
index e327a3c1..41600162 100644
--- a/probe-rs/src/flashing/flasher.rs
+++ b/probe-rs/src/flashing/flasher.rs
@@ -74,6 +74,10 @@ impl<'session> Flasher<'session> {
             .iter()
             .filter_map(MemoryRegion::as_ram_region)
             .find(|ram| {
+                if !ram.is_executable() {
+                    return false;
+                }
+
                 // If the algorithm has a forced load address, we try to use it.
                 // If not, then follow the CMSIS-Pack spec and use first available RAM region.
                 // In theory, it should be the "first listed in the pack", but the process of
@@ -86,7 +90,7 @@ impl<'session> Flasher<'session> {
                     // algorithm on.
                     ram.range.contains(&load_addr) && ram.cores.contains(core_name)
                 } else {
-                    // Any RAM is okay as long as it's accessible to the core;
+                    // Any executable RAM is okay as long as it's accessible to the core;
                     // the algorithm is presumably position-independent.
                     ram.cores.contains(core_name)
                 }
diff --git a/probe-rs/src/session.rs b/probe-rs/src/session.rs
index 0d9b23f6..449fc7a6 100644
--- a/probe-rs/src/session.rs
+++ b/probe-rs/src/session.rs
@@ -6,7 +6,7 @@ use crate::architecture::riscv::communication_interface::{RiscvDebugInterfaceSta
 use crate::architecture::xtensa::communication_interface::{
     XtensaCommunicationInterface, XtensaDebugInterfaceState, XtensaError,
 };
-use crate::config::{ChipInfo, CoreExt, RegistryError, Target, TargetSelector};
+use crate::config::{CoreExt, RegistryError, Target, TargetSelector};
 use crate::core::{Architecture, CombinedCoreState};
 use crate::probe::fake_probe::FakeProbe;
 use crate::probe::ProbeCreationError;
@@ -815,20 +815,12 @@ impl Drop for Session {
 fn get_target_from_selector(
     target: TargetSelector,
     attach_method: AttachMethod,
-    probe: Probe,
+    mut probe: Probe,
 ) -> Result<(Probe, Target), Error> {
-    let mut probe = probe;
-
     let target = match target {
         TargetSelector::Unspecified(name) => crate::config::get_target_by_name(name)?,
         TargetSelector::Specified(target) => target,
         TargetSelector::Auto => {
-            let mut found_chip = None;
-
-            // We have no information about the target, so we must assume it's using the default DP.
-            // We cannot automatically detect DPs if SWD multi-drop is used.
-            let dp_address = DpAddress::Default;
-
             // At this point we do not know what the target is, so we cannot use the chip specific reset sequence.
             // Thus, we try just using a normal reset for target detection if we want to do so under reset.
             // This can of course fail, but target detection is a best effort, not a guarantee!
@@ -837,58 +829,14 @@ fn get_target_from_selector(
             }
             probe.attach_to_unspecified()?;
 
-            if probe.has_arm_interface() {
-                match probe.try_into_arm_interface() {
-                    Ok(interface) => {
-                        let mut interface = interface
-                            .initialize(DefaultArmSequence::create(), dp_address)
-                            .map_err(|(_probe, err)| err)?;
-
-                        // TODO:
-                        let dp = DpAddress::Default;
-
-                        let found_arm_chip = interface
-                            .read_chip_info_from_rom_table(dp)
-                            .unwrap_or_else(|e| {
-                                tracing::info!("Error during auto-detection of ARM chips: {}", e);
-                                None
-                            });
-
-                        found_chip = found_arm_chip.map(ChipInfo::from);
-
-                        probe = interface.close();
-                    }
-                    Err((returned_probe, err)) => {
-                        probe = returned_probe;
-                        tracing::debug!("Error using ARM interface: {}", err);
-                    }
-                }
-            } else {
-                tracing::debug!("No ARM interface was present. Skipping Riscv autodetect.");
-            }
-
-            if found_chip.is_none() && probe.has_riscv_interface() {
-                match probe.try_get_riscv_interface_builder() {
-                    Ok(factory) => {
-                        let mut state = factory.create_state();
-                        let mut interface = factory.attach(&mut state)?;
-                        let idcode = interface.read_idcode();
-
-                        tracing::debug!("ID Code read over JTAG: {:x?}", idcode);
-                    }
-                    Err(err) => {
-                        tracing::debug!("Error during autodetection of RISC-V chips: {}", err);
-                    }
-                }
-            } else {
-                tracing::debug!("No RISC-V interface was present. Skipping Riscv autodetect.");
-            }
+            let (returned_probe, found_target) = crate::vendor::auto_determine_target(probe)?;
+            probe = returned_probe;
 
             // Now we can deassert reset in case we asserted it before. This is always okay.
             probe.target_reset_deassert()?;
 
-            if let Some(chip) = found_chip {
-                crate::config::get_target_by_chip_info(chip)?
+            if let Some(target) = found_target {
+                target
             } else {
                 return Err(Error::ChipNotFound(RegistryError::ChipAutodetectFailed));
             }
diff --git a/probe-rs/src/vendor/espressif/mod.rs b/probe-rs/src/vendor/espressif/mod.rs
index 854d22ea..8248a11a 100644
--- a/probe-rs/src/vendor/espressif/mod.rs
+++ b/probe-rs/src/vendor/espressif/mod.rs
@@ -1,9 +1,16 @@
 //! Espressif vendor support.
 
-use probe_rs_target::Chip;
+use probe_rs_target::{
+    chip_detection::{ChipDetectionMethod, EspressifDetection},
+    Chip,
+};
 
 use crate::{
-    config::DebugSequence,
+    architecture::{
+        riscv::communication_interface::RiscvCommunicationInterface,
+        xtensa::communication_interface::XtensaCommunicationInterface,
+    },
+    config::{registry, DebugSequence},
     vendor::{
         espressif::sequences::{
             esp32::ESP32, esp32c2::ESP32C2, esp32c3::ESP32C3, esp32c6::ESP32C6, esp32h2::ESP32H2,
@@ -11,10 +18,55 @@ use crate::{
         },
         Vendor,
     },
+    Error, MemoryInterface,
 };
 
 pub mod sequences;
 
+// A magic number that resides in the ROM of Espressif chips. This points to 4 bytes that are mostly
+// unique to each chip variant. There may be some overlap between revisions (e.g. esp32c3)
+// and chips may be placed on modules that are configured significantly
+// differently (esp32 with 1.8V or 3.3V VDD_SDIO).
+// See:
+// - https://github.com/esp-rs/espflash/blob/5c898ac7a37fd6ec7d7c4562585818ac878e5a2f/espflash/src/flasher/stubs.rs#L23
+// - https://github.com/esp-rs/espflash/blob/5c898ac7a37fd6ec7d7c4562585818ac878e5a2f/espflash/src/flasher/mod.rs#L589-L590
+const MAGIC_VALUE_ADDRESS: u64 = 0x4000_1000;
+
+fn get_target_by_magic(info: &EspressifDetection, read_magic: u32) -> Option<String> {
+    for (magic, target) in info.variants.iter() {
+        if *magic == read_magic {
+            return Some(target.clone());
+        }
+    }
+    None
+}
+
+fn try_detect_espressif_chip(
+    probe: &mut impl MemoryInterface,
+    idcode: u32,
+) -> Result<Option<String>, Error> {
+    let families = registry::families_ref();
+    for family in families.iter() {
+        for info in family
+            .chip_detection
+            .iter()
+            .filter_map(ChipDetectionMethod::as_espressif)
+        {
+            if info.idcode != idcode {
+                continue;
+            }
+            let Ok(read_magic) = probe.read_word_32(MAGIC_VALUE_ADDRESS) else {
+                continue;
+            };
+            if let Some(target) = get_target_by_magic(info, read_magic) {
+                return Ok(Some(target));
+            }
+        }
+    }
+
+    Ok(None)
+}
+
 /// Espressif
 #[derive(docsplay::Display)]
 pub struct Espressif;
@@ -41,4 +93,20 @@ impl Vendor for Espressif {
 
         Some(sequence)
     }
+
+    fn try_detect_riscv_chip(
+        &self,
+        probe: &mut RiscvCommunicationInterface,
+        idcode: u32,
+    ) -> Result<Option<String>, Error> {
+        try_detect_espressif_chip(probe, idcode)
+    }
+
+    fn try_detect_xtensa_chip(
+        &self,
+        probe: &mut XtensaCommunicationInterface,
+        idcode: u32,
+    ) -> Result<Option<String>, Error> {
+        try_detect_espressif_chip(probe, idcode)
+    }
 }
diff --git a/probe-rs/src/vendor/microchip/mod.rs b/probe-rs/src/vendor/microchip/mod.rs
index 0ce17d6e..2950b7aa 100644
--- a/probe-rs/src/vendor/microchip/mod.rs
+++ b/probe-rs/src/vendor/microchip/mod.rs
@@ -1,10 +1,15 @@
 //! Microchip vendor support.
 
-use probe_rs_target::Chip;
+use probe_rs_target::{chip_detection::ChipDetectionMethod, Chip};
 
 use crate::{
-    config::DebugSequence,
-    vendor::{microchip::sequences::atsam::AtSAM, Vendor},
+    architecture::arm::{ap::MemoryAp, ApAddress, ArmChipInfo, ArmProbeInterface},
+    config::{registry, DebugSequence},
+    vendor::{
+        microchip::sequences::atsam::{AtSAM, DsuDid},
+        Vendor,
+    },
+    Error,
 };
 
 pub mod sequences;
@@ -28,4 +33,46 @@ impl Vendor for Microchip {
 
         Some(sequence)
     }
+
+    fn try_detect_arm_chip(
+        &self,
+        interface: &mut dyn ArmProbeInterface,
+        chip_info: ArmChipInfo,
+    ) -> Result<Option<String>, Error> {
+        if chip_info.manufacturer.get() != Some("Atmel") || chip_info.part != 0xCD0 {
+            return Ok(None);
+        }
+
+        // FIXME: This is a bit shaky but good enough for now.
+        let access_port = MemoryAp::new(ApAddress::with_default_dp(0));
+        // This device has an Atmel DSU - Read and parse the DSU DID register
+        let did = DsuDid(
+            interface
+                .memory_interface(access_port)?
+                .read_word_32(DsuDid::ADDRESS)?,
+        );
+
+        let families = registry::families_ref();
+        for family in families.iter() {
+            for info in family
+                .chip_detection
+                .iter()
+                .filter_map(ChipDetectionMethod::as_atsam_dsu)
+            {
+                if info.processor != did.processor() as u8
+                    || info.family != did.family() as u8
+                    || info.series != did.series() as u8
+                {
+                    continue;
+                }
+                for (devsel, variant) in info.variants.iter() {
+                    if *devsel == did.devsel() as u8 {
+                        return Ok(Some(variant.clone()));
+                    }
+                }
+            }
+        }
+
+        Ok(None)
+    }
 }
diff --git a/probe-rs/src/vendor/microchip/sequences/atsam.rs b/probe-rs/src/vendor/microchip/sequences/atsam.rs
index af982be5..f957043d 100644
--- a/probe-rs/src/vendor/microchip/sequences/atsam.rs
+++ b/probe-rs/src/vendor/microchip/sequences/atsam.rs
@@ -218,7 +218,7 @@ bitfield! {
     pub revision, _ : 11, 8;
 
     /// This bit field identifies a device within a product family and product series.
-    pub devsel, _ : 8, 0;
+    pub devsel, _ : 7, 0;
 }
 
 impl DsuDid {
diff --git a/probe-rs/src/vendor/mod.rs b/probe-rs/src/vendor/mod.rs
index 067143d0..eb6a8272 100644
--- a/probe-rs/src/vendor/mod.rs
+++ b/probe-rs/src/vendor/mod.rs
@@ -3,10 +3,21 @@
 use std::ops::Deref;
 
 use once_cell::sync::Lazy;
-use parking_lot::{Mutex, MutexGuard};
+use parking_lot::{RwLock, RwLockReadGuard};
 use probe_rs_target::Chip;
 
-use crate::config::DebugSequence;
+use crate::{
+    architecture::{
+        arm::{sequences::DefaultArmSequence, ArmChipInfo, ArmProbeInterface, DpAddress},
+        riscv::communication_interface::RiscvCommunicationInterface,
+        xtensa::communication_interface::{
+            XtensaCommunicationInterface, XtensaDebugInterfaceState,
+        },
+    },
+    config::{registry, ChipInfo, DebugSequence},
+    probe::{DebugProbeError, Probe},
+    Error, Target,
+};
 
 pub mod espressif;
 pub mod infineon;
@@ -21,9 +32,36 @@ pub mod ti;
 pub trait Vendor: Send + Sync + std::fmt::Display {
     /// Tries to create a debug sequence for the given chip.
     fn try_create_debug_sequence(&self, chip: &Chip) -> Option<DebugSequence>;
+
+    /// Tries to identify an ARM chip. Returns `Some(target name)` on success.
+    fn try_detect_arm_chip(
+        &self,
+        _probe: &mut dyn ArmProbeInterface,
+        _chip_info: ArmChipInfo,
+    ) -> Result<Option<String>, Error> {
+        Ok(None)
+    }
+
+    /// Tries to identify an RISC-V chip. Returns `Some(target name)` on success.
+    fn try_detect_riscv_chip(
+        &self,
+        _probe: &mut RiscvCommunicationInterface,
+        _idcode: u32,
+    ) -> Result<Option<String>, Error> {
+        Ok(None)
+    }
+
+    /// Tries to identify an Xtensa chip. Returns `Some(target name)` on success.
+    fn try_detect_xtensa_chip(
+        &self,
+        _probe: &mut XtensaCommunicationInterface,
+        _idcode: u32,
+    ) -> Result<Option<String>, Error> {
+        Ok(None)
+    }
 }
 
-static VENDORS: Lazy<Mutex<Vec<Box<dyn Vendor>>>> = Lazy::new(|| {
+static VENDORS: Lazy<RwLock<Vec<Box<dyn Vendor>>>> = Lazy::new(|| {
     let vendors: Vec<Box<dyn Vendor>> = vec![
         Box::new(microchip::Microchip),
         Box::new(infineon::Infineon),
@@ -35,18 +73,18 @@ static VENDORS: Lazy<Mutex<Vec<Box<dyn Vendor>>>> = Lazy::new(|| {
         Box::new(st::St),
     ];
 
-    Mutex::new(vendors)
+    RwLock::new(vendors)
 });
 
 /// Registers a new vendor.
 pub fn register_vendor(vendor: Box<dyn Vendor>) {
     // Order matters. Prepend to allow users to override the default vendors.
-    VENDORS.lock().insert(0, vendor);
+    VENDORS.write().insert(0, vendor);
 }
 
 /// Returns a readable view of all known vendors.
 fn vendors<'a>() -> impl Deref<Target = [Box<dyn Vendor>]> + 'a {
-    MutexGuard::map(VENDORS.lock(), |v| v.as_mut_slice())
+    RwLockReadGuard::map(VENDORS.read_recursive(), |v| v.as_slice())
 }
 
 /// Tries to create a debug sequence for the given chip.
@@ -60,3 +98,192 @@ pub fn try_create_debug_sequence(chip: &Chip) -> Option<DebugSequence> {
 
     None
 }
+
+fn try_detect_arm_chip(mut probe: Probe) -> Result<(Probe, Option<Target>), Error> {
+    let mut found_target = None;
+
+    if !probe.has_arm_interface() {
+        // No ARM interface available.
+        tracing::debug!("No ARM interface available, skipping detection.");
+        return Ok((probe, None));
+    }
+
+    // We have no information about the target, so we must assume it's using the default DP.
+    // We cannot automatically detect DPs if SWD multi-drop is used.
+    // TODO: collect known DP addresses for known targets.
+    let dp_addresses = [DpAddress::Default];
+
+    for dp_address in dp_addresses {
+        // TODO: do not consume probe
+        match probe.try_into_arm_interface() {
+            Ok(interface) => {
+                let mut interface = interface
+                    .initialize(DefaultArmSequence::create(), dp_address)
+                    .map_err(|(_probe, err)| err)?;
+
+                let found_arm_chip = interface
+                    .read_chip_info_from_rom_table(dp_address)
+                    .unwrap_or_else(|error| {
+                        tracing::debug!("Error during ARM chip detection: {error}");
+                        None
+                    });
+
+                if let Some(found_chip) = found_arm_chip {
+                    let vendors = vendors();
+                    for vendor in vendors.iter() {
+                        // TODO: only consider families with matching JEP106.
+                        if let Some(target_name) =
+                            vendor.try_detect_arm_chip(interface.as_mut(), found_chip)?
+                        {
+                            found_target = Some(registry::get_target_by_name(&target_name)?);
+                            break;
+                        }
+                    }
+
+                    // No vendor-specific match, try to find a target by chip info.
+                    if found_target.is_none() {
+                        found_target = Some(crate::config::get_target_by_chip_info(
+                            ChipInfo::from(found_chip),
+                        )?);
+                    }
+                }
+
+                probe = interface.close();
+            }
+            Err((returned_probe, error)) => {
+                probe = returned_probe;
+                tracing::debug!("Error using ARM interface: {error}");
+            }
+        }
+    }
+
+    Ok((probe, found_target))
+}
+
+fn try_detect_riscv_chip(probe: &mut Probe) -> Result<Option<Target>, Error> {
+    let mut found_target = None;
+
+    match probe.try_get_riscv_interface_builder() {
+        Ok(factory) => {
+            let mut state = factory.create_state();
+            let mut interface = factory.attach(&mut state)?;
+
+            if let Err(error) = interface.enter_debug_mode() {
+                tracing::debug!("Failed to enter RISC-V debug mode: {error}");
+                return Ok(None);
+            }
+
+            match interface.read_idcode() {
+                Ok(Some(idcode)) => {
+                    tracing::debug!("ID code read over JTAG: {idcode:#x}");
+                    let vendors = vendors();
+                    for vendor in vendors.iter() {
+                        // TODO: only consider families with matching JEP106.
+                        if let Some(target_name) =
+                            vendor.try_detect_riscv_chip(&mut interface, idcode)?
+                        {
+                            found_target = Some(registry::get_target_by_name(target_name)?);
+                            break;
+                        }
+                    }
+                }
+                Ok(_) => tracing::debug!("No RISC-V ID code returned."),
+                Err(error) => tracing::debug!("Error during RISC-V chip detection: {error}"),
+            }
+
+            // TODO: disable debug module
+        }
+
+        Err(DebugProbeError::InterfaceNotAvailable { .. }) => {
+            tracing::debug!("No RISC-V interface available, skipping detection.");
+        }
+
+        Err(error) => {
+            tracing::debug!("Error during RISC-V chip detection: {error}");
+        }
+    }
+
+    Ok(found_target)
+}
+
+fn try_detect_xtensa_chip(probe: &mut Probe) -> Result<Option<Target>, Error> {
+    let mut found_target = None;
+
+    let mut state = XtensaDebugInterfaceState::default();
+    match probe.try_get_xtensa_interface(&mut state) {
+        Ok(mut interface) => {
+            if let Err(error) = interface.enter_debug_mode() {
+                tracing::debug!("Failed to enter Xtensa debug mode: {error}");
+                return Ok(None);
+            }
+
+            match interface.read_idcode() {
+                Ok(idcode) => {
+                    tracing::debug!("ID code read over JTAG: {idcode:#x}");
+                    let vendors = vendors();
+                    for vendor in vendors.iter() {
+                        // TODO: only consider families with matching JEP106.
+                        if let Some(target_name) =
+                            vendor.try_detect_xtensa_chip(&mut interface, idcode)?
+                        {
+                            found_target = Some(registry::get_target_by_name(target_name)?);
+                            break;
+                        }
+                    }
+                }
+                Err(error) => tracing::debug!("Error during Xtensa chip detection: {error}"),
+            }
+
+            // TODO: disable debug module
+        }
+
+        Err(DebugProbeError::InterfaceNotAvailable { .. }) => {
+            tracing::debug!("No Xtensa interface available, skipping detection.");
+        }
+
+        Err(error) => {
+            tracing::debug!("Error during autodetection of Xtensa chips: {error}");
+        }
+    }
+
+    Ok(found_target)
+}
+
+/// Tries to identify the chip using the given probe.
+pub(crate) fn auto_determine_target(mut probe: Probe) -> Result<(Probe, Option<Target>), Error> {
+    tracing::info!("Auto-detecting target");
+    let mut found_target = None;
+
+    // Xtensa and RISC-V interfaces don't need moving the probe. For clarity, their
+    // handlers work with the borrowed probe, and we use these wrappers to adapt to the
+    // ARM way of moving in and out of the probe.
+    fn try_detect_riscv_chip_wrapper(mut probe: Probe) -> Result<(Probe, Option<Target>), Error> {
+        try_detect_riscv_chip(&mut probe).map(|found_target| (probe, found_target))
+    }
+
+    fn try_detect_xtensa_chip_wrapper(mut probe: Probe) -> Result<(Probe, Option<Target>), Error> {
+        try_detect_xtensa_chip(&mut probe).map(|found_target| (probe, found_target))
+    }
+
+    type DetectFn = fn(Probe) -> Result<(Probe, Option<Target>), Error>;
+    const ARCHITECTURES: &[DetectFn] = &[
+        try_detect_arm_chip,
+        try_detect_riscv_chip_wrapper,
+        try_detect_xtensa_chip_wrapper,
+    ];
+
+    for architecture in ARCHITECTURES {
+        let (returned_probe, target) = architecture(probe)?;
+
+        probe = returned_probe;
+        if let Some(target) = target {
+            tracing::info!("Found target: {}", target.name);
+            found_target = Some(target);
+            break;
+        }
+    }
+
+    probe.detach()?;
+
+    Ok((probe, found_target))
+}
diff --git a/probe-rs/src/vendor/nordicsemi/mod.rs b/probe-rs/src/vendor/nordicsemi/mod.rs
index 53123ed0..89880dd9 100644
--- a/probe-rs/src/vendor/nordicsemi/mod.rs
+++ b/probe-rs/src/vendor/nordicsemi/mod.rs
@@ -1,13 +1,23 @@
 //! Nordic Semiconductor vendor support.
 
-use probe_rs_target::Chip;
+use std::collections::{hash_map::Entry, HashMap};
+
+use probe_rs_target::{
+    chip_detection::{NordicConfigIdDetection, NordicFicrDetection},
+    Chip,
+};
 
 use crate::{
-    config::DebugSequence,
+    architecture::arm::{
+        ap::MemoryAp, memory::adi_v5_memory_interface::ArmProbe, ApAddress, ArmChipInfo,
+        ArmProbeInterface,
+    },
+    config::{registry, DebugSequence},
     vendor::{
         nordicsemi::sequences::{nrf52::Nrf52, nrf53::Nrf5340, nrf91::Nrf9160},
         Vendor,
     },
+    Error,
 };
 
 pub mod sequences;
@@ -30,4 +40,100 @@ impl Vendor for NordicSemi {
 
         Some(sequence)
     }
+
+    fn try_detect_arm_chip(
+        &self,
+        probe: &mut dyn ArmProbeInterface,
+        chip_info: ArmChipInfo,
+    ) -> Result<Option<String>, Error> {
+        if chip_info.manufacturer.get() != Some("Nordic VLSI ASA") {
+            return Ok(None);
+        }
+
+        // FIXME: This is a bit shaky but good enough for now.
+        let access_port = MemoryAp::new(ApAddress::with_default_dp(0));
+        let mut memory_interface = probe.memory_interface(access_port)?;
+
+        // Cache to avoid reading the same register multiple times
+        let mut register_values: HashMap<u32, u32> = HashMap::new();
+
+        let families = registry::families_ref();
+        for family in families.iter() {
+            for info in family.chip_detection.iter() {
+                let target = if let Some(spec) = info.as_nordic_ficr() {
+                    ficr_info_detect(&mut register_values, memory_interface.as_mut(), spec)
+                } else if let Some(spec) = info.as_nordic_configid() {
+                    configid_detect(&mut register_values, memory_interface.as_mut(), spec)
+                } else {
+                    // Family does not have a Nordic specific detection method
+                    continue;
+                };
+
+                if target.is_some() {
+                    // We have a match
+                    return Ok(target);
+                }
+            }
+        }
+
+        Ok(None)
+    }
+}
+
+fn ficr_info_detect(
+    register_values: &mut HashMap<u32, u32>,
+    memory_interface: &mut dyn ArmProbe,
+    spec: &NordicFicrDetection,
+) -> Option<String> {
+    // Read the PART register, if not already read
+    if let Some(part) = read_register_cached(register_values, memory_interface, spec.part_address) {
+        if part != spec.part {
+            return None;
+        }
+
+        // Read the VARIANT register, if not already read
+        if let Some(variant) =
+            read_register_cached(register_values, memory_interface, spec.variant_address)
+        {
+            return spec.variants.get(&variant).cloned();
+        }
+    }
+
+    None
+}
+
+fn configid_detect(
+    register_values: &mut HashMap<u32, u32>,
+    memory_interface: &mut dyn ArmProbe,
+    spec: &NordicConfigIdDetection,
+) -> Option<String> {
+    // Read the CONFIGID register, if not already read
+    if let Some(configid) =
+        read_register_cached(register_values, memory_interface, spec.configid_address)
+    {
+        let hwid = configid & 0xFFFF;
+
+        // Match the HWID
+        return spec.hwid.get(&hwid).cloned();
+    }
+
+    None
+}
+
+fn read_register_cached(
+    register_values: &mut HashMap<u32, u32>,
+    memory_interface: &mut dyn ArmProbe,
+    address: u32,
+) -> Option<u32> {
+    match register_values.entry(address) {
+        Entry::Occupied(value) => Some(*value.get()),
+        Entry::Vacant(e) => {
+            if let Ok(value) = memory_interface.read_word_32(address as u64) {
+                e.insert(value);
+                Some(value)
+            } else {
+                None
+            }
+        }
+    }
 }
diff --git a/probe-rs/targets/AT32F4_Series.yaml b/probe-rs/targets/AT32F4_Series.yaml
index 040dea80..45f856c0 100644
--- a/probe-rs/targets/AT32F4_Series.yaml
+++ b/probe-rs/targets/AT32F4_Series.yaml
@@ -5353,7 +5353,6 @@ flash_algorithms:
   pc_erase_sector: 0x13f
   pc_erase_all: 0xfb
   data_section_offset: 0x26c
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -5374,7 +5373,6 @@ flash_algorithms:
   pc_erase_sector: 0x163
   pc_erase_all: 0x10d
   data_section_offset: 0x26c
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x1ffff800
@@ -5395,7 +5393,6 @@ flash_algorithms:
   pc_erase_sector: 0x1b1
   pc_erase_all: 0x15b
   data_section_offset: 0x2d0
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -5416,7 +5413,6 @@ flash_algorithms:
   pc_erase_sector: 0x1c1
   pc_erase_all: 0x16b
   data_section_offset: 0x2dc
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -5437,7 +5433,6 @@ flash_algorithms:
   pc_erase_sector: 0x1b1
   pc_erase_all: 0x15b
   data_section_offset: 0x2d0
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -5458,7 +5453,6 @@ flash_algorithms:
   pc_erase_sector: 0x1c1
   pc_erase_all: 0x16b
   data_section_offset: 0x2dc
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -5480,7 +5474,6 @@ flash_algorithms:
   pc_erase_sector: 0x191
   pc_erase_all: 0x10d
   data_section_offset: 0x378
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -5502,7 +5495,6 @@ flash_algorithms:
   pc_erase_sector: 0x173
   pc_erase_all: 0x13f
   data_section_offset: 0x298
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -5523,7 +5515,6 @@ flash_algorithms:
   pc_erase_sector: 0x173
   pc_erase_all: 0x13f
   data_section_offset: 0x298
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x1fffa400
@@ -5544,7 +5535,6 @@ flash_algorithms:
   pc_erase_sector: 0x1af
   pc_erase_all: 0x153
   data_section_offset: 0x2ac
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x1ffff800
@@ -5566,7 +5556,6 @@ flash_algorithms:
   pc_erase_sector: 0x173
   pc_erase_all: 0x13f
   data_section_offset: 0x298
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -5588,7 +5577,6 @@ flash_algorithms:
   pc_erase_sector: 0x18b
   pc_erase_all: 0x147
   data_section_offset: 0x26c
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -5609,7 +5597,6 @@ flash_algorithms:
   pc_erase_sector: 0x1ab
   pc_erase_all: 0x159
   data_section_offset: 0x290
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x1ffff800
@@ -5630,7 +5617,6 @@ flash_algorithms:
   pc_erase_sector: 0x1fd
   pc_erase_all: 0x1a7
   data_section_offset: 0x324
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -5651,7 +5637,6 @@ flash_algorithms:
   pc_erase_sector: 0x1fd
   pc_erase_all: 0x1a7
   data_section_offset: 0x324
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -5673,7 +5658,6 @@ flash_algorithms:
   pc_erase_sector: 0x1dd
   pc_erase_all: 0x159
   data_section_offset: 0x378
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -5695,7 +5679,6 @@ flash_algorithms:
   pc_erase_sector: 0x121
   pc_erase_all: 0xdd
   data_section_offset: 0x254
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -5716,7 +5699,6 @@ flash_algorithms:
   pc_erase_sector: 0x141
   pc_erase_all: 0xef
   data_section_offset: 0x250
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x1ffff800
@@ -5737,7 +5719,6 @@ flash_algorithms:
   pc_erase_sector: 0x13d
   pc_erase_all: 0x1b3
   data_section_offset: 0x2e4
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -5758,7 +5739,6 @@ flash_algorithms:
   pc_erase_sector: 0x13d
   pc_erase_all: 0x1b3
   data_section_offset: 0x2e8
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -5779,7 +5759,6 @@ flash_algorithms:
   pc_erase_sector: 0x13d
   pc_erase_all: 0x1b3
   data_section_offset: 0x2e8
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -5800,7 +5779,6 @@ flash_algorithms:
   pc_erase_sector: 0x13d
   pc_erase_all: 0x1b3
   data_section_offset: 0x2e8
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -5821,7 +5799,6 @@ flash_algorithms:
   pc_erase_sector: 0x13d
   pc_erase_all: 0x1b3
   data_section_offset: 0x2e8
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -5842,7 +5819,6 @@ flash_algorithms:
   pc_erase_sector: 0x14d
   pc_erase_all: 0x1c3
   data_section_offset: 0x2f0
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -5863,7 +5839,6 @@ flash_algorithms:
   pc_erase_sector: 0x14d
   pc_erase_all: 0x1c3
   data_section_offset: 0x2f4
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -5884,7 +5859,6 @@ flash_algorithms:
   pc_erase_sector: 0x14d
   pc_erase_all: 0x1c3
   data_section_offset: 0x2f4
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -5905,7 +5879,6 @@ flash_algorithms:
   pc_erase_sector: 0x14d
   pc_erase_all: 0x1c3
   data_section_offset: 0x2f4
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -5926,7 +5899,6 @@ flash_algorithms:
   pc_erase_sector: 0x14d
   pc_erase_all: 0x1c3
   data_section_offset: 0x2f4
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -5947,7 +5919,6 @@ flash_algorithms:
   pc_erase_sector: 0x13d
   pc_erase_all: 0x1b3
   data_section_offset: 0x2e4
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -5968,7 +5939,6 @@ flash_algorithms:
   pc_erase_sector: 0x13d
   pc_erase_all: 0x1b3
   data_section_offset: 0x2e8
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -5989,7 +5959,6 @@ flash_algorithms:
   pc_erase_sector: 0x13d
   pc_erase_all: 0x1b3
   data_section_offset: 0x2e8
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -6010,7 +5979,6 @@ flash_algorithms:
   pc_erase_sector: 0x13d
   pc_erase_all: 0x1b3
   data_section_offset: 0x2e8
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -6031,7 +5999,6 @@ flash_algorithms:
   pc_erase_sector: 0x13d
   pc_erase_all: 0x1b3
   data_section_offset: 0x2e8
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -6052,7 +6019,6 @@ flash_algorithms:
   pc_erase_sector: 0x14d
   pc_erase_all: 0x1c3
   data_section_offset: 0x2f0
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -6073,7 +6039,6 @@ flash_algorithms:
   pc_erase_sector: 0x14d
   pc_erase_all: 0x1c3
   data_section_offset: 0x2f4
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -6094,7 +6059,6 @@ flash_algorithms:
   pc_erase_sector: 0x14d
   pc_erase_all: 0x1c3
   data_section_offset: 0x2f4
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -6115,7 +6079,6 @@ flash_algorithms:
   pc_erase_sector: 0x14d
   pc_erase_all: 0x1c3
   data_section_offset: 0x2f4
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -6136,7 +6099,6 @@ flash_algorithms:
   pc_erase_sector: 0x14d
   pc_erase_all: 0x1c3
   data_section_offset: 0x2f4
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8400000
@@ -6158,7 +6120,6 @@ flash_algorithms:
   pc_erase_sector: 0x121
   pc_erase_all: 0xdd
   data_section_offset: 0x254
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -6180,7 +6141,6 @@ flash_algorithms:
   pc_erase_sector: 0x1b1
   pc_erase_all: 0xe3
   data_section_offset: 0x2d8
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -6201,7 +6161,6 @@ flash_algorithms:
   pc_erase_sector: 0x189
   pc_erase_all: 0xe3
   data_section_offset: 0x298
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x1fffac00
@@ -6222,7 +6181,6 @@ flash_algorithms:
   pc_erase_sector: 0x13f
   pc_erase_all: 0xf5
   data_section_offset: 0x218
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x1ffff800
@@ -6244,7 +6202,6 @@ flash_algorithms:
   pc_erase_sector: 0x1b1
   pc_erase_all: 0xe3
   data_section_offset: 0x2d8
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -6266,7 +6223,6 @@ flash_algorithms:
   pc_erase_sector: 0x1b1
   pc_erase_all: 0xe3
   data_section_offset: 0x2d8
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -6287,7 +6243,6 @@ flash_algorithms:
   pc_erase_sector: 0x189
   pc_erase_all: 0xe3
   data_section_offset: 0x298
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x1fffe400
@@ -6308,7 +6263,6 @@ flash_algorithms:
   pc_erase_sector: 0x13f
   pc_erase_all: 0xf5
   data_section_offset: 0x218
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x1ffff800
@@ -6330,7 +6284,6 @@ flash_algorithms:
   pc_erase_sector: 0x1b1
   pc_erase_all: 0xe3
   data_section_offset: 0x2d8
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -6352,7 +6305,6 @@ flash_algorithms:
   pc_erase_sector: 0x1b1
   pc_erase_all: 0xe3
   data_section_offset: 0x2d8
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -6374,7 +6326,6 @@ flash_algorithms:
   pc_erase_sector: 0x153
   pc_erase_all: 0x11f
   data_section_offset: 0x278
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -6395,7 +6346,6 @@ flash_algorithms:
   pc_erase_sector: 0x153
   pc_erase_all: 0x11f
   data_section_offset: 0x278
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x1fffa400
@@ -6416,7 +6366,6 @@ flash_algorithms:
   pc_erase_sector: 0x18f
   pc_erase_all: 0x133
   data_section_offset: 0x28c
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x1ffff800
@@ -6438,7 +6387,6 @@ flash_algorithms:
   pc_erase_sector: 0x153
   pc_erase_all: 0x11f
   data_section_offset: 0x278
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -6460,7 +6408,6 @@ flash_algorithms:
   pc_erase_sector: 0x1e9
   pc_erase_all: 0x109
   data_section_offset: 0x30c
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -6481,7 +6428,6 @@ flash_algorithms:
   pc_erase_sector: 0x1bf
   pc_erase_all: 0x109
   data_section_offset: 0x2cc
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x1fffe400
@@ -6502,7 +6448,6 @@ flash_algorithms:
   pc_erase_sector: 0x169
   pc_erase_all: 0x11b
   data_section_offset: 0x240
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x1ffff800
@@ -6524,7 +6469,6 @@ flash_algorithms:
   pc_erase_sector: 0x1e9
   pc_erase_all: 0x109
   data_section_offset: 0x30c
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -6546,7 +6490,6 @@ flash_algorithms:
   pc_erase_sector: 0x12d
   pc_erase_all: 0xf9
   data_section_offset: 0x254
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -6567,7 +6510,6 @@ flash_algorithms:
   pc_erase_sector: 0x175
   pc_erase_all: 0x119
   data_section_offset: 0x2a0
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x1fffc000
@@ -6589,7 +6531,6 @@ flash_algorithms:
   pc_erase_sector: 0x12d
   pc_erase_all: 0xf9
   data_section_offset: 0x254
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -6611,7 +6552,6 @@ flash_algorithms:
   pc_erase_sector: 0x179
   pc_erase_all: 0x115
   data_section_offset: 0x378
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -6633,7 +6573,6 @@ flash_algorithms:
   pc_erase_sector: 0x179
   pc_erase_all: 0x115
   data_section_offset: 0x374
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x8000000
@@ -6654,7 +6593,6 @@ flash_algorithms:
   pc_erase_sector: 0x175
   pc_erase_all: 0x119
   data_section_offset: 0x2a0
-  data_load_address: 0x20001800
   flash_properties:
     address_range:
       start: 0x1fffc000
diff --git a/probe-rs/targets/MIMXRT1050.yaml b/probe-rs/targets/MIMXRT1050.yaml
index eff50ac7..f08eee7d 100644
--- a/probe-rs/targets/MIMXRT1050.yaml
+++ b/probe-rs/targets/MIMXRT1050.yaml
@@ -59,6 +59,7 @@ flash_algorithms:
   default: true
   instructions: cLUFRgxGFkYC4A/MD8UQPhAu+tIILgLTA8wDxQg+BC4H0wHMAcU2HwPgIXgpcGQcbRx2HvnScL1AunBHQLpwR0C6cEdAunBHQLpwR0C6cEdAunBHwLpwR8C6cEfAunBHwLpwR8C6cEfAunBHwLpwRxy1L0gAkC9IAYlJCEkAAYEtSQqJUghSAAqBAogEI1IHACoC2gKImkMCgAiIQAcC1QiImEMIgCZIJElBYCVJgWABaIAikUMgIhFDAWAiSWpGSUQAIALwrPoAKAXRHklJRADw7v0AKADQASAcvQAgcEcZSRC1SUQAIADwRf8AKADQASAQvQUhSQdCGBNJELUBI5sESUQAIALw4foAKADQASAQvQUhE0ZJB0IYC0kQtUlEACAA8Mn+ACgA0AEgEL0AAAcwI8AAgAtAAAANQCDFKNkAwAtA//8AABAAAAD4taRJokhJRAhgpE6iSDBgMGgAKPzaMGsBIQkDiEMwYzBrACj82p5IAmieSQMjCkDbAtIYnEsaQwJgAyAAAzBhMGkAKPzaMGkBJz8EuEMwYZNKQDoQawhAIyEJAkAYk0kIQxBjkkwBICBhk0mRSElECGABJQCQAOBtHClGAJgD8Nn6jkmIQvfYYGmNSQhAaR5JB0kLCEMpAv85ATmJBYkNCENgYWBqwAnAAcAcYGKgaQMhiQQIQ6BhoGmCSQhABSGJBkAYoGHgaX9JCEADIUkHQBh+SQhD4GHgaQMhCQQIQ+BhYGrnIckCiEMhIckCQBhgYjBouEMwYDBruEMwYzBpuEMwYfi9akiAMAFoAyKSAhFDAWBwR2ZIgDABaAMikgKRQwFgcEf3tQxGaUmKsBVGFCJ5RGhG//e9/mVJFCJ5RAgxBaj/97b+AC0B0AEtNtFTTkA+MGuHCVVIvwHCaQcgwAWCQwAtLNAFqAAsJ9AJLADZASRhAENcCBhAeAchwAXJBZsGQBibDoQBUk07Q6QJKGgUQwInOEMoYAqY//e7/zBrmEIA0DNjQUjBaaFCANDEYQqY//en/yhouEMoYA2w8L1oRtHncLUWRjtKACBKRBJoBEYAKQjQNU0BKQfQAikK0AQkMGAgRnC9EEb652hpgAWBDxBGDeDoaSlIQDgAa4EGiQ40SAPwFfoSIUhD6WmJAUkPSRwD8A364+cDRgQgACsE0QApAtAsSAhgACBwRyFISEQAaHBHELUdSEBpgAWBDx1ISRxIRABoA/Dz+RC9+LUERhhIDUZIRABoIEkD8On5BkYJ4AMhMEYD8OP5AJAA4AC/QB4AkPvSACJkHihG0kNQQQVG4UPoQwFD69H4vQA2bgEEAAAAWCABAACADUAAgQ1AwMDAwBgYExgjIxoPAMAPQACkeB8MAAAAAESVCP/g+P/P///jgP9/nAEAgAM+NwAAAIAqQAA4nByA9eQJQEIPAPi1Wk1aSC5GAJAMRjdGCEYC8I/6ACgE0CZu4G4AkGdupW4gbQAoYG0n0AAoBNBRSQYgyGNQSMZiIG0AKAbQTUkBIEAxyGJMSEAwxmFJSREjQDELY0hIQDAHYgEiSmNFYopjhWLKY8ViQkmAMQpgBWNFIABdCCgD0A/gACjX0STgPEkBIEAxCGI7SkAyFWHIYdVgiGGVYEhhVWAgewMoAdABKAbRM0hAMINiM0kAmEAxiGEgRgLwRPoAKAbQLUgBIUAwQWIsSEAwR2GgbQAo4G0q0AAoBdAnSQYgQDEIYCZIBmOgbQAoBdAiSAQhQDBBYiFIxmMfSBEhQDBBYh5JQDFPYQEiAmINYcJhzWCCYY1gQmFNYCJ7AyoB0AEqA9EUIgJhAJgIYPi9ACjU0fi9BCEAKA/QAXsDKQvRAWxgMEkGACkB2g8hA+BBfgApAdEeIQF2ACEIRnBHCEmIYgAgcEcGSYlqAWAAIHBHAADxEAAA8TABAICBH0CAgx9AAIAPQPC1/EmFsHlEHsltRh7F+k75T/lNaUb4TEA2gDfANQMAA/Do+QkGDSIrWIGDiYuRAADwQvshaEkGSQ5IQ0jgAPA7+zdqBUYxaQPwvPk6RgAjAvDm/yFryQcB0BYhAOAUIU1DKBgFsPC9APAm+yFpZ+AWIQDgFCFIQ/TnAPAd+wRGMGtFBjhGP2ltDgFoIEYD8Jn5OkYAIwLww/9sQzFrIBgDItIEEUAR0AEi0gSRQgDRQAjSSQlr0koRQAEi0gOJGgbQEgKRQs3RgAjL54AI8OdACMfnAPDw+gRGOGotaEYGdg45ayBGA/Bt+SpGACMC8Jf/dEM5aiAYAyLSBBFAENABItIEkUIA0UAIvEkJawEiiQ+JB5IHiRjW0FIA0UKh0dbngAjx5yhqAeAoaoAIgAcADwhYluezSJTnAPC9+iFqiQeX0JTnACCM5xC1BEYBIP/3Vv+pSUA5ACwJ0AEsCdACLA7QAywP0AAgEiFIQxC9CWgB4AloCQqJBokOA/Ao+PPnCWgJDPfnCWgJDvTnELWdTGBpgAGgaRLVAyEJAwhABdABIQkDiEIF0AAgBeACIP/3Jv8B4ADwf/phackOD+ADIYkECEAT0AEhiQRAGhPQQBoS0IhCCdEAIP/3Ef8haUkHSQ9JHALw8/8QvQAgEL0BIP/3Bf8QvQIg//em/xC9ELUAKAHQAvCM/wEhe0iJB4FhfkkKa9ID/NUBIhIEQmEBaQkE/NWCYRC9ASBzSYAHSGFwRxAidUkAKAHQimNwR0pjcEdxSAFrASIRQwFjcEduSAFrSQhJAAFjcEcQtQRGAiD/983+ZUmAOQAsCdABLAnQAiwO0AMsD9AAIBIhSEMQvQlrAeAJawkKiQaJDgLwn//z5wlrCQz35wlrCQ705xC1WUwDAAPwpfgXDQ0SKjY5PD5AQkRGSkxOUFJUWFpcXmBkAP/3Y/9haYkKEeBgaUAGCtVgaQAGA9UBIP/3vv8F4AIg//cx/wHg//dQ/2FpCQxJB0kPSRwC8Gr/EL3/90b/YWnJBEkPSRwC8GH/YWmJBYkP7+cA8M/5EL0BIMADEL0AICLgAiAg4AAgBOABIALgAiAA4AMg//eQ/xC9CCAU4AEgEuAAIATgASAC4AIgAOADIP/3+f4QvQUgBuAGIATgByAC4AMgAOAEIP/3SP4QvQAgEL0AeAEhQAZADkkDQRgdSAFgAWgAKfzacEcBIBlJAAMIYHBHAHgBIcAHwA9JA0EYFEgBYwFrACn82nBHASARSQADCGNwRwB4wSGAB4APiQFBGAxIAWEBaQAp/NpwRwlJACAIYXBHAHjBIYAHgA+JAUEYBEgBYgFqACn82nBHAAAuNAAAAIANQECBDUAAgIAAQHh9AQDAD0BAgg1ArkkAIAhi6+cwtUFoACKLAKpJmwiAMQtgg2ibAJsIC2EBeAEjSQZbA0kOQHjJGJ0BAigc0KJLbAAEKBbQCCgS0BAoDtAhQ59LGGudTORDIEAQQxhjmUhAMAFjAWsAKfzaML0aRu/nKUP75yFD+ecpQ+nnASCRSQADQDEIY7DncLVBaI5LiQAAIokIgDMZY4FojEyJAIkIgDwhYAF4ASRJBmQDSQ5AeAkZpQECKBrQAySkB24ABCgT0AgoD9AQKAvQMUOASARrpACkCBRDBGMZYhhqACj82nC9Ikby5ylD++cxQ/nnKUPs5wEgdEkAA4AxCGJ15wF5wniJB5IHCQ+SDxFDAngAKgLQASJSAxFDQngAKgLQASISBRFDgHgAKALQASBABQFDZ0iAOAFiAWoAKfzaVecBIGNJAAOAOQhiT+dgSxC1QDsaaMAAvySEQKJDgCSEQBRDHGCJBokOgUARQxlgEL1XSUA5CmjDAIAgmEACQwpgNOdTSxC1gDsaa8AAvySEQKJDgCSEQBRDHGOJBokOgUARQxljEL1KSYA5CmvDAIAgmEACQwpjGecItUZIAWgDIhFDAWBESAFoAiIRQwFgACAAkEJIAL8AmUkcAJGBQvnTO0lAOQhqHyISApBDPEoQQwhiASAIvQi1NkgBaAMiEUMBYDhIAWgCIhFDAWAAIACQMkgAvwCZSRwAkYFC+dMsSUA5CGofIhICkEMtShBDCGIBIAi9CLUAImhGAJL/97v+KUgBa0kASQgBYwFrgwSZQwFjAmABa2MikgMRQwFjASAIvQi1ACJoRgCS//e0/h9IAWtJAEkIAWMBa0MEmUMBYwJgAWtjIpIDEUMBYwEgCL0NSQAgCGEUSAFrggQRQwFjpOYJSQAgCGIQSAFrQgQRQwFjm+YOSABrwAYB1Q1IleYNSEhEAGiR5gCADUAAgIAAQIENQIDAD0BAAS5AgBoGAAEXAABAAy5AAJANQACgDUBAgg1AADZuAQQAAABwtQxGBkYC8DX6BQAL0SJGASOAMgAhMEYC8Ob4YHwBKAHRACAgdChGcL1wtYqwBUYAIG5GMHAPIAEkApADlDJ0Ckb/MgGTcTIjRiFGKEYC8Mv4aUYoRgKUAfDV/wqwcL3/tQQgg7ANRgApKdAuRv82wTZwewAoBtAGmwWaA5j/99T/ACgc0TB7LEaANAIoCtEgRjAwh8hrRgfDIEZAMA/IMDQPxEA8KUYGmwWaA5gC8Mv4MXsCKQPRbUYOzTA0jsQHsPC9/7WJsB1GFkYMRgmY//fG/wAoFNFpRghwAScOIAOXApAOdCJG/zJhMjtGOUYBlQmYAvB4+GlGApcJmAHwgv8NsPC9/7UEIIOwnEaWRgAp1dANRv81wTUoewxGgDQCKAvRIEYQMInIakbmaYnCIEYgMI3IEDSNxCA8Y0ZyRgOYAvCu+Cl7Aim50W1GDs0QNE7EtOf3tYKwFkYNAFHQAS5P2CxG/zTBNCB6ACgA0AEgAChG0ChsQAbHDwKYAvBi+gAuK9AgegAoCdBGIEFdOkYCmP/3FfopRgKYAfCq/aB7ACgD0AAhApgC8F76akYCIQKY//dV+gAvAtAAmEAIAJABqgAhApj/90v6AJkBmALwfvwKIUAcSEOACBDgIXoAKQfQOkYCmP/36/kpRgKYAfCA/aB7ACjZ0AEh1OcAv0Ae/NIFsPC9/7WJsBdGDUYIRgHwR/0GRgAiKUYJmP/3mv87RjJGKUYJmP/3Gf8EAD/RAiBpRghwCSABJAKQA5RHIEFdKEb/MIEwACkG0AF8ACkD0EF8ApEBfAORaUYBlw50DJkFkQBsBpACmAEhAAFCGYAyA5sJmAHwtv9pRgKUCZgB8MD+BAAT0TtGMkYpRgmY//c4/wQAC9H/INAwQF0AKAbQO0YyRilGCZj/9wr/BEYJmALw0fkBIilGCZj/90r/IEYd5/O1i7AAJmlGDJ0OcAEhA5ELIQKRaUYOdEcgQF03RjRGACgJ0ChG/zCBMAF9ACkD0EF9ApEAfQOQACIMmQuY//cn/1A1CpUBzQmQACga0DNGACIMmQuY//eg/gQAPtECmAGWAQEMmAObChgBIYAyC5gB8Ff/ASACkGlGC5gB8GD+BAAr0QmYfxw2GAQv29MALCTRACAJkAZGDJgKnf8wwTAKkIDNAC8T0AAiCZsMmQuY//fG/gQAEdEKmMB7ACgH0AAiCZsMmQuY//eZ/gQABdEJmHYcwBkJkAQu4tMLmALwWfkBIgyZC5j/99L+IEal5ve1irAXRg1GCEYB8HD8BkYAIilGCpj/98P+O0YyRilGCpj/90L+BAA50WlGAZcIcAUgASQCkAOUDnRHIEBdACgJ0ChG/zCBMAF7ACkD0EF7ApEAewOQApgBIQABQhmAMgObCpgB8OX+aUYClAqYAfDv/QQAE9E7RjJGKUYKmP/3Z/4EAAvR/yDQMEBdACgG0DtGMkYpRgqY//c5/gRGCpgC8AD5ASIpRgqY//d5/iBGTOb3tYqwF0YNRghGAfAX/AZGACIpRgqY//dq/jtGMkYpRgqY//fp/QQAOdFpRgGXCHAIIAEkApADlA50RyBAXQAoCdAoRv8wgTABfwApA9BBfwKRAH8DkAKYASEAAUIZgDIDmwqYAfCM/mlGApQKmAHwlv0EABPRO0YyRilGCpj/9w7+BAAL0f8g0DBAXQAoBtA7RjJGKUYKmP/34P0ERgqYAvCn+AEiKUYKmP/3IP4gRvPl8LUHRgQgibAdRhRGDkYAKg/QJCFoRgLwzPoDIGlGCHABIAKQCJUDkAGWB5Q4RgHwXf0JsPC9/7WPsAAgDEYKkAuQDJANkBFoASUeRgUpAtJRaEApFdMldBFsSQJJDwsAAvC7+wcNBQkLBQUHDQACJwvgBCcJ4AEnB+ADJwXgIHQ/4DGICQUPDzvQACAAkGlGApAIdQMgCHEJlQOVBJUIkQEvB9ACLwPQAy8t0AQvBNH9SAHg/EgwOAqQASMKqhlGD5gB8AT+AakPmAHwD/0AKBjRMGgAAQAPBdCwiAAEAQ4B0AAOAJAAISBGgDAhdAEvDdACIgIvE9ADLynQBC8f0CF0ACATsPC950gKMNTnAJlKBvbU5UoCZMMgAUBAIB7gAJmLB+3U4UsRQwNkCAIAkCV0JXUEIGB1AJigYWV04OcAmYsH3dTYSzAzEUMDZAfgAJkKBtXU1Uo9MgJkgCABQwCR5ef3tQEgQAKYsAAnAZBoRgd0ASQNRgKXA5QAKXLQzEh4RE3IDalNwQMgakYQcAmoB5AQIAiQKkaAMgEhA5sYmAHwlP1pRgKUGJgB8J78AChY0QmYQBwI0QqYQBwF0QuYQBwC0QyYQBwH0BAiCakNqALwo/kAKEXRNOAAIxpGKUYYmP/3r/wAKHvRCSACkAIgaUYIcA2oKkYQJgWQ/zIGlhEyASEDmxiYAfBg/WlGApQYmAHwavwAKGPRACMaRilGGJgB8LD9AChb0QKQAyBpRghwCagHkAiWGJgB8Fb8AChP0cLnMiAWkAAgFZAobEAhCEMoZEYgQV0CJgEiGJj+9yL/OOA94AAkEZQSlBOUFJQBIShtCQaIQgHZjkgA4I5IEZCOSfCyQBiNSQEjCEMSkBGqACEYmAHwGf0DIGlGApQIcAmoB5AQIAiQGJgB8B38BAAG0AAvFNAamAAvBmAQ0BDgECIJqQ2oAvAn+QAoDNB2HAAv8NEVmBaZQBwVkIhCwdN4TCBGG7DwvQEn5Of/tQhGgrBcMACQC0bIaAgzAScAKAPaOkbAHoJAAeBAHMIIApj/JAJlAp4Bkkho/zYBNIE2QCgB0jRkCuAYjQAGAg84RpBAASLSA5BCANEgRjBkYU0AJCBGQgDSGBd/AC8N0AEiukCqQgHSFUaERqJCBdkBJz8FukIB0hRGhkZAHAQo6dN1ZDRlApj/MMEwpUIB0QEiAOAAIkJyASIBmBIGkEIt2UAxCH4AKAjQAJhgRAF5BJgBYACYcEQBeRjgYEZAAMAYQH8hIdwiICgC0NgoBdEC4ASYAWAB4ASYAmBwRkAAwBhAfyAoAtDYKAXRAuAFmAFgAeAFmAJgACAGsPC9YEZAAMAYQX8EmAFgcEZAAMAYQX/s5/+1jbAEIAWQD5gPRggwA5APmFwwCZAAIASQEJgAaAACAA8BKAXRA5gAaAADwA8EkHHQACA4cxCZBkYJeAurCgcSD0YhylUAkBggBpAAIAeQCqo4Rg+Z//dI/wEhOG0JBohCAdkgIAaQEJgAiAAEAA9R0TlGEJsPmg2Y//fZ/QWQACj10QOYAGiBAh3VAiAHkAOYAHoBBk4PwAbADhzgAAA1BAEkAQQBIAEEAiCoJgAA7gQgiu0EGIoAAgQAALAEpipOAAD///8AQAIG1QOYgGgBAk4PwALADgCQD5gGmkAw/B38Sfk0CJAgKgLQ+kggYRLgAH75SwAoO9AJmPhKAGjFBQHV90gD4AAGMtXzSCIwYmEgYQHgqeBhYQEgOHM9RvFIgDUoY/FIKGEKmPBKwbIGmAAEAUMRQwGQKWULmcmyAUMRQyMgQAEhYCBjEJgAaAABAQ8P0BCZSWgKBhIOCtDIsgSZACYAkAApIdBAAACQHuAjYdDnBJkAKRnQAA8X0QaYICgE0dVIQBwoYNlIaGA5Rg2Y//ek+gWQAChm0WpGOUYNmP/32/0FkAAo9tEAJgaYGCgG0AIgB5AEmAAoINDuIAPgBJgAKArQ7SA5bEAiEUM5ZAGZAUPHSAFDKWA34AOYAGiBAgPVA5gAiQAEA+BAAgTVA5iAaAAOApAf4AMgGeAImAB+ACgK0AmYAGiBBgrUwAYT1WwgApAAIAeQDuADmABogQIB1ewg5udAAgHVbCDi5xMgApAAIAZGAJACmQGYCEMHmQkGCEOpSQhDKGAQmTpGCXj/MgkGwTIAIAsPAZIAKwPQCQ8BKQTQa+AAmIAZAJBJ4A+ZSWhAKffTA5mJa4oF89UJAwkPBSIRQgHQpSAL4IkHCdU5RhCbD5oNmADwof8FkAAoTdEBIAOZCiIJjwkEiQ4RQgfQkEkhZ2FnBpkgKQnRjkkG4BEiEUI60IxJIWdhZ4xJoWcBIQGaAC5RcxHQBJkAKTPQAS4u0CchiQIIQwCZCQYJCghDg0kIQ2hgg0ioYBfgAJgAKA/QBJqASQAqBdDAskAYf0kIQ2hgCuDAskAYfUkIQ2hgC+B8SGhgBJgAKAbQAZkBIIhzOGxAIQhDOGQFmBGw8L0mIQAJzucBLgzQByGJAghDAJkJBgkKCENvSQhDaGBvSKhg6ucGIQAJ8Of3tWxOmLANAAjQCCNqRgAhGJj/9zf8BABk0QHgBCRh4GZJAJiIQgHQNEZb4GhGAHkoYGhGgHlAHAooANkKIBaQGpgIIQAoANAJAhaYAqrDABiY//cX/AQARNFkIShGAfDq/gAmO+DwAAKqEVyDGNh5AAIKGP8gAAKCQgLQUEiCQizRACECIA8CGRgJeTlDQB751dh4hwAamAAoANAJAv8gAAKCQgzRUC8A2VAnKkY7RggyGJj/9+b7BAAT0W9gDeA/SIJCCtEqRjtGXDIYmP/32fsEAAbRASFYIEFVdhwWmIZCwNMgRkHl97UNRoiwAyEoRulzCCNAMENxWCMrZAEkKXMAKgHQWSEpZMRxDyGBh8SHLkYBIP82QAKBNjBkQAJwZDBlMEZAMAeQRHIpRgiY//cb+QAoctEiSAAnAJAhSAOXASMBkAKXakYZRgiYAfAA+gKXA5caTxxIgDc34AQgAAACBBgIEgQgCAQiAAA+BCAKBgQAAAUEBCQABAAIBCQBAAAEAIr/Bv8G/wYAAAAGAAYAHhAyAAIAsgSmAXwAAgQAALAEpgAwBCYEJAAAAAIAMgQmAXwnTgAAU0ZEUIT/AAAghxiLEI8CoxCPBKcBkAEjakYAIQCXCJgB8Lr5EyDAAgaQAiMGqv5JCJgA8Pz+ACgU0QgjBKoQIQiYAPDg/gAoDNEFmPdJgLIFkASYiEIE0VkhBZgJAohCAtDzSAuw8L0IIwSqJyEImADwyf4AKPXRBJgABAAOBJAXOAko7dgEmQEgiEAoZQ8gAAMGkAIjBqoAIQiYAPDH/gAo39EsRuNJgDQhYOJJYWDiSaFg4knjSuNL5E8QNI7E3E8nYOJPZ2DcT6dgEDQOxOBPp2AiYGFg30/nYN1PJ2H/Nd5PETWOxdJPFDSgPy9g209vYNtPjsQOxNZPp2AiYGFg1U/nYNNPJ2HKTCA9oDwsYNVMbGDVTKxgL0bRTDA3HscOx8tMbGXqZCllykysZchMFDfsZQ7HzUnpZgIhMXIDInJyMXEBInJxMXQJIXF0BCExcwUjc3MxdQshcXUHmQpzf+f3tQQlkrAXRgxGACoE0Hh4OXiIQgHRACWH4CBGQDAIIRGQQXF4eAMlASZCKAHQQSgD0QIlEZgEIUFxeHiCKAHQQigA0SEmACBpRgGQCHQIcAEgApAgIQmoAfBe/fl4AiBCAgYpC9AHKRLQCCkB0AEgK+ApAosdE0P/MQmTBeApAgtGZjMTQ5kxCZMRQw2RHOApAg9GsgJmNysGF0O1Bh9DrEYvQ5klmTEtBBFDL0MZQ2VGMyIpQ1IEEUMJlw2RIS4D0SFsQCIRQyFkA5ARmQEgiHEBBiFljkkhYI5JYWADIWFzoXP/IckxCFUKIGBnIUYSmP73q/8FABfRCaoBIQObEpgB8Jf4aUYSmADwov8FRoFIfSFIRMkAAGgB8P/8AeAAv0AeEZAAKPrRKEYVsPC997WcsB6YDEYFaCgCAA8FKBHQACd1STAieUQNqP73JvkoBAAPCpAoAwUPCpgAKATQAygT0QHgASfs5wAtENADLQzRACgK0AMgIHMQICBkHpgAaAACAA8EKBjQGeAEJpXhaEb+98v7BkYAIP73w/sALgbRakYhRhyY//cq/wYA7tEAICBzECAgZAMgAuBQICBkBiAJkAqYKEMA0QEnIEYKmUAwAykI0AEhQXEhRhyY/vc1/wYA09EB4Agh9ecAIAAtBNAALwHQASAA4AIgAAENqUIYASMZRhyYAfAU+AAgaUYCkAh1AyAIcQEgA5AEkAuoCJABqRyYAPAU/wYAr9EIqAB7wiir0QEhCQQALQioHdBAfApGMDiCQCJlIEYBIv8wEgOBMEJkEhECZAFlAyAgcxAgIGQBIEdAIEYpRv8wwTAlRoA1GZAAKQLQeOCAe+DnCpgDKHPRASEhdAIgYHRhggYiYnUhdQAjaUYHIgtwynAAL0rQgiFqRlFwoGEcSChmG0hyOGhmG0ioZh6YAHgABgAPMeBVBQAAAFEAUilOAACghxiLEI8GswSnAAAAhwCHAIeqhwCHBYcAh3CHEI8LtwCHVYcAhwKHAIeghxCPgKMAh4CHEI8AhzCHAAAAhxCHRkNGQgAEAVYMAAAAiBwAAHIEAAQABAEgAygC0BmZi3Ia4BmZASCIchbggSFrRllwoGH+S/5IK2ZoZv5IqGYBISBGIXcgMEJwAXD4SCFjcjgrZ2hn90ioZwCY/vfb+vZIKGP2SChh4B0KmfkwACkD0AAvFtAhIxXgASEhc/BJKWDwSWlg7kmJHQFh70lBYexJFTEpZepJ0DEBYCMhSQEBY4TgASMALwHQIiEA4AIhjkYALwHQLCEA4AwhGpEALwHQKSEA4AkhCpEALwHQKCEA4AghAJGZAthKmwYYOooYnEYaQ9pLGkMqYHJGGSOSAlsB0hgam5ZGmwYaQ9VLE0NrYAqbmgLBI5sA0hgKkqpgmhyKGGNGGkPPSxNDz0orZIoYY0YaQ81LE0MDIhICK2KKGGNGGkMDIxsGGkNqYqpixkoKmw0y62KKGGNGGkPESxNDA2EAm3JGmwYaQ8EjmwQTQ71KQ2EcMooYY0YaQ71LE0MrZXJGamX3IpIAjRhjRh1DuUtyRh1DBWBCYBsiUgGJGGNGtkoZQxFDAWMALwPQIGxAIQhDIGQZmQIgCHMwRh+w8L33tQxGrkmmsBdGICJ5RB2o/fdj/zhoAAIADwcoCdAAIACQOGgAAwAPBdADICBzUCAU4AEg9OcBqP73F/oFRgAg/vcP+gAtBtEBqiFGJpj/93b9BgAU0QAgIHMQICVGCCFANSBkaXEhRiaY/veO/QYA8NE4aAADAQ8D0AAPAygD0J7gASMdqgHgASMhqgEhJpgA8G/+CCBocQAiBKkmmP/3v/sGACLRA6sCqgSpIEb/93H5AJgAKAPRUCAgZAMgIHMlRnBIgDUoY3BIKGE5aAgDAg8gRv8wwTABkMA4AyoG0AkECg8DKgLQCQ8b0GjgdEkpYnRJKWB0SWlgdEkpZHFJ3DkpZXBJITkBYDshSQEBY21J6zkBYW5JQWE4aAADAA8v0ErgASIhbRIGkUIC0yAijiEB4BgiwiECmxIE27JlTBNDI0MrZQObEUPbshNDYkojQxFDA2ABYUchyQFBYQCZACkK0F5JKWBeSWlgIyFJAQFjAZkBIIhzIuBaSSlgUknz5wAgaUYIcAYnz3CCIEhwAJj+92b5ASAgdAIhYXTnIaFhZ3UgdWCCNEgPMChmMkhyOGhmOEjAHqhmAZkCIAhzMEYpsPC997W0sEdIAJAQaBVGAAIADwxGCSgb0AAmQ0lQInlEHqj993j+ACACkCBGQDAEIQGQQXEoaAEDAAQFDxAgDw8gZAAvBtACLxvQAy8f0GnhASbi5wSo/vcm+QCQACD+9x75AJgAKAfRBKohRjSY//eE/ACQACjq0QGZASBIcQAgA+ABmQQgSHEDICBzCOADICBzCCABmQAuSHEB0QEgApAALQPQAi0B0AMt0NE4RihDANEBJjvgcgQABAAEAgQABAEgBgQAAAUEBCQMBCAICDMEJAQgAAAAABEDAAAGAwAA+QMFAwAAAAD6AwAA7QMAAN4DAAAjAwAAnwMyGQAABQcEp/0HIIsGswSnBgcAAASjAAAABAAIAAQAC/wEIAsGMwQn/QQgiylOAAB8FwAAAi0C0AMtAtAE4AQgAOAIIAGZSHFAICFsAC4B0IFDAOABQyFkIUY0mP73NvwAkAAoitEALgjQAi8C0AMvDNEB4AEgCeACIAfgAi8C0AMvA9EB4AMgAOAEIAABHqlCGAEjGUY0mADwDP0FqQKaNJj/9176AJAAKH3RM6syqgWpIEb/9w/4AyAgcyBGgDD9SQFj/UkBYQAuAdACIwDgIiMALgHQDCEA4CwhjkYALgHQCSEA4CkhApEALgHQCCIA4CgiqQePDQSSOUYBl6oHkgkLN5sGF0OcRh9D7EsfQwdgc0YPHZsCH0MCmxdDmwYfQwKTASObBB9DR2APRiA3F0NjRh9D4kuWRh9DB2UPRtg3F0NjRh9D3UsfQ+Md+TMfYI8cF0NiRhdD2UoXQx9hD0YEmoA3kgIXQwEikgJgMV9hEUMCJxljAi0B0AMtD9EBmXNGSR0ZQwKbGUPNSxlDAWIBmYkdEUP/Is0yAWQXVQAhoWECLQDgP+AC0AMtA9AF4AEikgQB4AEi0gSiYQAuENAibIAjGkMiZAEieSMaVb1KAma9SkJmASAgdAAtB9BndAbgASOiadsFGkOiYe/nYXQGImJ1IHVggmhGAXMALgjQAi0C0AMtAtAH4EEgEuCBIBDgAi0L0AMtC9BBcwggaUbIcwOY/fe9/wCYN7DwvUIgAOCCIGlGSHPw5/e1BCcWRgxGAClN0AAuS9D5ASBGAfCi+AEhJUZANalxCAYgZZtIIGCbSGBgAyBgc6Bz/yDJMAFVMGgAAgAPAwAB8KD5CgYGDBEXFx0dIyMwMkYhRgCYAPDW+AHgASID4AcAGNAe4AAiIUYAmP/3z/n25zJGIUYAmP/3fPvw5zJGIUYAmP/3P/3q5zJGIUYAmP/3HP7k5yBG/fdR/zB4AAcAD6hxASAocThG/r3/tQQggbAPRgApHtA9Rv81gTVpbElCDEYUQNIYUkIKQP8hyjHJXVZCACkM0SltACkJ0CrgIkY5RgGY/veu/AAoA9FpbAwZtEL00wWw8L0pbSBGiEMO0AAgMhsAKAzQkUIK2CJGOUYBmP738PwAKOzRKW0J4AEg7+ciRjlGAZj+94z8ACjh0WlsDBm0Qt/T3Of/tYmwBCASnB9GFkYAKSLQAC4g0AAsHtAIRgDw7fgDIWpGEXABIQORACECkRB0TE2sQgDYJUZpRgGXB5YIlQmYAPCL+gAoBtGpCIkAZBt/GY4ZACzr0Q2w8L1wtY6wDEYAIQyRAJELkQ2RakYCkQZGEXUDIBBxASUDlTpICZUIkgqQK0YElQqqKUYwRgDwVvsBqTBGAPBh+gAoFNEAmfciEUArSwoEEDPTGACR/yIldGEyE1EldQ4iYnWhYQQhYXT/NME05XMOsHC98LUHRgAgqbANRhZGBCQjSSWQJpAnkDAieUQokBmo/ffc+zBoAAMAD1jRBCFFIEFVKEYbSYAwAWAbSUFgKUY4Rv73I/oEAEnRMHgABgAPASgO0egdFUn5MAFnQWcJFIFnACMaRilGOEb+9yT6BAA10TBoAAMb4AYEAAAFBAQkAAQgAAAEBABxBAAEAyAAAEZDRkIABAFW//8AAIUEASTGEQAAAwQYCAQkAQD/Bv8GAA8AARmpQhgBIxlGOEYA8Nn6ACJpRjhG//cr+AQABtEzRmpGKUY4Rv73aP4ERiBG8OQwtYmwAyRtRixwASVJAAAkA5UBkQKUbUYsdGlGCJMHkgDwxvkJsDC9MLWJsAIkbUYscAEkSQABkQKUA5QAISl0aUYGkwWSAPCz+evnAAAAbEAHAdUBIHBHACBwRwBsgAYB1QEgcEcAIHBHAGzABwDQASBwRwBsAAcB1QEgcEcAIHBHAGyABwHVASBwRwAgcEcAbEAGAdUBIHBHACBwR/O1hbAORgQkBZgA8M78BQB+0AAufNAwewMoedgAKArQASgI0AIoBtADKATRMEb/99n/ACgC0P8gATAM4AOqAiEFmP33lPz+SQOYiEIG0zBsAAYD1HkgAJABkCHgACRgAIEZYDFIfg9+ACgL0WQgR0Md0EshOEYA8LH+SyFBQ7lCANJAHD8hPygA2QhGgAZADKIA/zABMGlGZByIUAIs3tMoaAIigAcAKBzaACAe4DBG//ef/wdGAkYCqQWY/feC/OBIApkALwnQAPCI/oAIfSHJAEhDSyEA8IH+0ucA8H7+QAj05yloASARQylgMW0AKQLRcW0AKQLQwCEAm0tRsW0AKQLR8W0AKQTQxCEBmwDgBuBLUQAoAtAoaJBDKGAAJCBGB7Dwvfi1B0YEIBxGDkYALxbQACoU0AAsEtARRsFIAPBM/gFGBUZhQzBGAPBG/gDgQBwBRmlDYUOxQvnTOGAAIPi98LWFsLdNDkYHRgCVAZUA8Br8BAAr0AAuKdACqgIhOEb99/P7A6oBIThG/ffu+wEmrU+2AjNGOUZoRgKa//fB/zNGOUYBqAOa//e7/wCYqEIA2QCVAZioQgDZAZUAmAGZAASJsghDYGAAIAWw8L0EIPvn87WHsAAgAJAMRgQlB5gA8OH7A5AAKFTQACxS0CBGQDAnRgWQUDcAJv8wQTACkDhosgCBCgOYEBgBkAFmoHs/HcUGYHvtDsAGgA0FQ+B7AAdADAVDIEb/99P+ACgC0AEggAIFQ2BvACgN0ASqAiEHmP33kvsBI2FvaEYEmv/3aP8AmAAEBUMBmAVnBZjAeQAoDtACmAB8QQcK0AKZByJJfEADCQcJDVIDgBiAsghDAeAJIAACAZmAMQhgdhwELrbTACUoRgmw8L0CRhC1BCAAKiHQACkf0EQgQFwBKAzR0GhDCFsAQCADQwhG//d2/gAoAdABIAND02DQaCAhCEPQYF5LACCBAIkYDGocQAxiQBwDKPfTACAQvRC1APBb+wAoC9AAIQEj2weKABIYgDIUaBxDFGBJHAQp9tMQvf61BUYEIACQDkYoRgDwRPsEAH7QAC780DB4Ayh52DB8AZAAJyBGAPA/+yhG//fW/2BpHiEIQ2BhJUaANXBoKGIweAIoAtADKALQA+AwiwDgMIyHsjF7MHpJHgAHSQcAC0kJCEMBmckHCEM4Q2hiMHgDKEvR8GkyaoMHStFAIxwhnkapY6trASELQ6tjq2vbB/zRK2sLQytjNuDhHfkxc0ZyRQ/TZ2mbCL8GAtQp4IDJgMBbHvvScUZSGmFpICMZQ2FhHuArbxsGWw2TQgPSGOAIyRIfCMAEKvrSACoQ0AloAZEBqYxGAUYAIwfgZ0Y/eA9wZ0Z/HEkcvEZbHJNC9dMAImFpCQcB1AAqxtEweAIoAOBi4AHQAShI0XFpsmmIB1vRQCCERhwg6GPoawngAOH1BQDKmjv//wAAAGXNHQD/8PwBIxhD6GPoa8AH/NGGRirgIEb/MGNpgTBbBiHVY0abCGJFAtIO4IDJgMBbHvvSYEYSGgngACoD3YDJgMASHwHgACeAwFse9dJwRgAoBNEoawEjGEMoY55GYGlAIxhDYGFgaQAHAdQAKtLcMHgAKAPRKGsBIQhDKGMgRgDwdPpgaQAHC9VobgABAA8OKAHQ/kgB4P1IQB4AkACY/r0AIPrn+LUORgQhH0YVRgCRAPBT+gQAI9AALSHQACHyGUlBECMAIJoaiEEZ0yBGAPBM+u9KomECIOBh8RmwAIsAgQAJGf8x/zECMQLgQM1AwUAcmEL606JhASDgYQAgAJAAmPi9cLUERgQgirAAKSTQACBuRjBwAyABJQKQA5UydEcgAZNAXAAoCdAIRv8wgTACegAqA9BCegKSAHoDkAKYA5sAAUIYASEgRoAy//eq/2lGIEYClf/3tP4KsHC9/7UEIJGwDUYOkAApedAoRkAwgo8BIQxGlEDCjwKTAJIDImtGGnEEkQORDKkIkROZACkB0AghAOAEIQmRE5kZdcB5ACgJ0ChG/zCBMAF5ACkD0EF5A5EAeQSQA5gEmwABQhmAMgOZEZj/923/LW8ALQHQASAA4AAgACYPkAGpEZj/93D+DpAAKDvRE5gAKBnQCqkLqAyrCCIfeA9wX3gHcEAcSRySHpscACr10QCYC5kAKAqYBNAIQCFGgUMK0Q7gCEMK4ACYACgG0AyZIEaIQwAoBNABJwPgDJggQPjnACcPmAdCC9AoRjBDDdB9IMAAACH996r5ACDAQ20eRkEAL7zRDpgVsPC9iUhAHA6Q+Of3tYqwDUYEJgqYAPBv+QcAVNAALVLQASBpRghwDJgBkAAgCHQEIAAkBpCgAEIZEEYgMEF4ACk+0AEjWwLbWZsFmw8D0CsZW38CKzTQApEAeDAyBZIDkAAiKUYMmwqY//ca/wAoK9ECmAEhAAFCGYAyA5sKmP/33/4BIAKQaUYKmP/36P0GABrRaIoAKA7RKRlJfwIpCtADKQjQACIpRgybCpj/9yX/BgAJ0QTgZCFIQwAh/fdC+WQcAyy20zBGDbDwvfO1h7ANRgQmB5gA8A75BAB+0AAt/NAofAAoAtEofwAoCdAobMAGBNQoRv/3IvwAKAHQASAA4AAgA5BKSShoiEJm0QeY/fd7+ClGB5j99175KEZAMAOZApAAKQLQACIBIQXgKEb/9wX8AkYCmIF5B5j99234B5j991r4IGgCJrBDIGAgRgDwyfggaDBDIGAgaDVJCEACmUl5CCkB0YkCCEMySQhDKXuJB4kOAUMhYClGB5j/95f8oGgBIckDiEOgYChG//fD+wAoBNCgaAEhyQQIQ6BgKUYgRv/3If0pRgeY//e5/ClGB5j/98r7IGgCIYhDIGAgRgDwkPgoRil8UDAEkAApHNAHmAWQBCAAIQDgXeAEngCRD0YCzgGRACkK0ClGAJoFmADwkPgAKAbRAZoAmYkYAJF/HAQv7dMGAEbRKH8AKCfQB5gFkAQgAC0g0AAhBJ4AkQ9GAs4J4FkbAADwWvBaRkNGQg/fAAAAAP//AZEAKQrQKUYAmgWY//ff/gAoBtEBmgCZiRgAkX8cBC/i0wYAG9EDmAAoF9AgaAImMEMgYChG//dk+wJGApiBeQeY/PfM/ylGB5j/9xP8KUYHmP/3XfsgaLBDIGAAJjBGo+QQtQDwKfgAKAPQgDABbokH/NUQvRC1APAf+AAoAdAA8BP4EL1wtQ1GAPAW+AQACtAA8Br4ASDAAiFoAC0B0AFDAOCBQyFgcL0BaAEiEUMBYAFoyQf80XBHAUYAIAApAtEwSHhEAGhwR4AwAW7JB/zQAW6JB/zVcEfwtYmwFkYMRgdGBCX/9+j/AChI0AAsRtD/MP8wAjAAaIAFgA8C0GB8Aigl0AElaUYNcAGWYH0CkCB9A5AAIAh0IEYYMAWQBCAGkDNGACIhRjhG//ea/QKYASEAAQIZOEaAMgOb//dh/WlGOEYClf/3a/wFABfRAeAAJRTgYYoAKQzRYHwCKAnQAygH0DNGACIhRjhG//em/QVGBOBkIEhDACH898T/KEYS5HwHAABwtV5IAYhKBwQhACoC2gKIikMCgFpIAohSBwLVAoiKQwKAWUhXSUFgWEmBYAFogCKRQyAiEUMBYFVIAWnJBwPQAWlJCEkAAWG/80+Pv/Nvj1BNACEpYb/zT4+/82+PTkxgaQEiUgQQQ2Bhv/NPj7/zb49JSIAwQWC/80+PAGgBAUkMwASDDcoFGEaWDIIHMkMqYkAe+tJJHvXSv/NPj2BpASEJBAhDYGG/80+Pv/Nvj3C9+LU5TGBpOUo6SYABGNWgaQMjGwMYQAXQASISA5BCCtAAIAngEGmABwHQFiAA4BQgMElIQwDgCEZhaYkASQ8p4BBoK0tABkAOWENHCBBrwAcB0BYlAOAUJSZIRUMkSEAwBmoAaQDwH/oyRgAjAPBJ+KFpQBkgShFAEdABIpIEHkuJGhbQiRoX0JFCB9EgaUEHSQ84RkkcAPAM+QDgACBhackESQ9JHADwBPkUSUlECGD4vRloCQwA4BloiQaJDgDw+PgSIUhD6ucAAACAC0AAAA1AIMUo2QDAC0D//wAAAOAA4EDvAOAA7QDgAMAPQACADUAANm4BAAAMAACBDUAMAAAA/rUFRhBGDEYYQ3PQrkaMRgAgrRoBRpxBZ9NmRgAnASQ9RrYanUEC0xNGOkYhJGVGdkYvBDYMPkMtDLYanUEE0xUMGwQrQxIEEDRlRnZGLwY2Cj5DLQq2Gp1BBNMVDhsCK0MSAgg0ZUZ2Ri8HNgk+Qy0JthqdQQTTFQ8bAStDEgEkHWVGdkavB7YIPkOtCLYanUEE05UPmwArQ5IApBxlRnZG7wd2CD5DbQi2Gp1BGtOSGFtBZBwW4AAYdkZlRklBtxqdQQGRAJAJ02BGsRqYQY5GhEYAmAGZACVAHGlB3QdSCCpDWwhkHubVckZjRgOw8L3/5wAgAUbARsBGKkYjRvXnELUAIADwB/nARsBGASAA8Pz4EL0DRhC1C0ObBw/RBCoN0wjIEMkSH6NC+NAYuiG6iEIB2QEgEL0AIMBDEL0AKgPQ0wcD0FIcB+AAIBC9A3gMeEAcSRwbGwfRA3gMeEAcSRwbGwHRkh7x0RhGEL0B4ATACR8EKfvSiwcB1QKAgBzJBwDQAnBwRwApC9DDBwLQAnBAHEkeAikE04MHAtUCgIAciR7j5wAi7ucAIt/nACIDCYtCLNMDCotCEdMAI5xGTuADRgtDPNQAIkMIi0Ix0wMJi0Ic0wMKi0IB05RGP+DDCYtCAdPLAcAaUkGDCYtCAdOLAcAaUkFDCYtCAdNLAcAaUkEDCYtCAdMLAcAaUkHDCItCAdPLAMAaUkGDCItCAdOLAMAaUkFDCItCAdNLAMAaUkFBGgDSAUZSQRBGcEdd4MoPANBJQgMQANNAQlNAACKcRgMJi0It0wMKi0IS0/wiiQESugMKi0IM04kBkhGLQgjTiQGSEYtCBNOJATrQkhEA4IkJwwmLQgHTywHAGlJBgwmLQgHTiwHAGlJBQwmLQgHTSwHAGlJBAwmLQgHTCwHAGlJBwwiLQgHTywDAGlJBgwiLQgHTiwDAGlJB2dJDCItCAdNLAMAaUkFBGgDSAUZjRlJBWxAQRgHTQEIAKwDVSUJwR2NGWxAA00BCAbUAIMBGwEYCvQAAAUkYIKu+/ucmAAIAELUA8Av4APAC+BC9cEcQtQAoAdD/9+7/EL0AABC1ACECoADwE/gBIBC9AABTSUdBQlJUOiBBYm5vcm1hbCB0ZXJtaW5hdGlvbgAAAHC1BUYMRgogAOBtHADwEvgALQbQKHgAKPfRAuBkHADwCfgALALQIHgAKPfRCiAA8AH4cL0ItWlGCHADIKu+CL34tQQMi7ImRoKyXkMNDBBGNwxYQzYEgBkAIXlBFkZuQzcMNgSAGXlBJkZuQ4kZ+L0wtHRGZB4leGQcq0IA0h1GY11bAOMYMLwYRwAAAAAiCBYIGAYeBBIGDgYRBAwGFgIAABgGFgQMBh4CEgMWAiEBGgEWAUB4fQGA8PoCAOH1BUBZcwcAESIzRFVmd4iZqrvM3e7/WgQYCAgw/yQAAAAAAAAAAFoFGAkIMf8lAAAAAAAAAABaBhgKCDL/JgAAAAAAAAAAnwQDJAAAAAAAAAAAAAAAAJ8HYAcgCwQnAAAAAAAAAACfh2CHIIsEpwAAAAAAAAAAWgQYCAgw/yQAAAAAAAAAAFoHIIv/pwAAAAAAAAAAAABaBBgICDD/JAAAAAAAAAAAWgYYCv8mAAAAAAAAAAAAAFoHGAv/JwAAAAAAAAAAAABaBhiK/6YAAAAAAAAAAAAAWgcgi/+nAAAAAAAAAAAAAACAKkAAAAAAAAAAAAAAAAAApHgfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
   load_address: 0x20209000
+  stack_size: 4096
   pc_init: 0x71
   pc_uninit: 0xdd
   pc_program_page: 0x113
diff --git a/probe-rs/targets/MIMXRT1170.yaml b/probe-rs/targets/MIMXRT1170.yaml
index 3f9b914b..388bb126 100644
--- a/probe-rs/targets/MIMXRT1170.yaml
+++ b/probe-rs/targets/MIMXRT1170.yaml
@@ -34,6 +34,7 @@ flash_algorithms:
   default: true
   instructions: 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cEdwtQxMbUYBJkxENgMjaK0bmhiqQg7YrRqQGe4PdRltEKoYkEIA2RBGwB0LYMII0gDQGiJgcL0QAAAAcLUFRgxGCiAA4G0cAPA6+AAtBtAoeAAo99EC4GQcAPAx+AAsAtAgeAAo99EKIADwKfhwvRC1ASgF0AAhA6D/99//ASAQvQmh+OcAAFNJR1JUTUVNOiBPdXQgb2YgaGVhcCBtZW1vcnkAAAAAOiBIZWFwIG1lbW9yeSBjb3JydXB0ZWQACLVpRghwAyCrvgi9+LUEDIuyJkaCsl5DDQwQRjcMWEM2BIAZACF5QRZGbkM3DDYEgBl5QSZGbkOJGfi9MLR0RmQeJXhkHKtCANIdRmNdWwDjGDC8GEcAAAMAAAD/AAAAAQAAAAAAAAAWAAAAAAAAAAAAAAACBQMABxYPHAIFAwAUDwkYAgUDAA8YCQ0CBQMAFA8JGAIFAwAYCQsRAgUDABAYCQ0CBQMAEBgLCQIFAwAUDwoYAgUDAAkQGAoCBQMAEBgJDQIFAwAQGAkNAgUDAA8YGg0CBQMAEBgJDQIFAwAQGAkNAgUDABAYExQCBQMAEBgaHAIFAwAQGBocAgUDABAYExQCBQMAEBgTFAIFAwAQGBMUAgUDABEJDA8CBQMAEQkMDwIFAwAQGAkNAgUDABAYCQ0CBQMAFA8NGAIFAwAQGAkNAgUDABAYCQ0CBQMAEBgJDQIFAwAQGAkNAgUDABAYCQ0CBQMAEBgJDQIFAwAQGAkNAgUDABAYCQ0CBQMAEBgJDQIFAwAQGAkNAgUDABQPDRgCBQMAFA8NGAIFAwAQGAkNAgUDABAYCQ0CBQMAEBgJDQIFAwAQGAkNAgUDABQPDRgCBQMAFA8NGAIFAwATGAkNAgUDABMYCQ0CBQMAExgJDQIFAwATGAkNAgUDABQPExgCBQMAFA8TGAIFAwAQGAkNAgUDABAYCQ0CBQMAFxoYCwIFAwAXGhgLAgUDABcaGAsCBQMAFxoYCwIFAwAXGhgLAgUDABcaGAsCBQMAFxoYCwIFAwAMChgHAgUDAAwKGAcCBQMAGBAaDQIFAwAYEBoNAgUDABQPGhgCBQMAGg8TDQIFAwAaExgNAgUDABoTGA0CBQMAGhMYDQIFAwAUDxoYAgUDAAkLDxwCBQMACQwRHAIFAwAJDBEcAgUDAAkKERwCBQMACQoRHAIFAwAMDwocAgUDAAwPChwCBQMADA8KHAIFAwAMDxIcAgUDAAwJEhgCBQMADQESGoCAf359fHt6eXh3dnZ1dHNycXFwb25ubWxsa2pqaWhoZ2ZmZWRkY2NiYWFgYF9fXl5dXVxcW1taWllZWFhXV1ZWVVVVVFRTU1JSUlFRUFBQT09PTk5NTU1MTExLS0tKSkpJSUlISEhHR0dHRkZGRUVFRERERENDQ0NCQkJCQUFBAAAAAAAAIyAAAAAAAAAAAAAAAAAAAAAA
   load_address: 0x20250000
+  stack_size: 4096
   pc_init: 0x73
   pc_uninit: 0x153
   pc_program_page: 0x191
diff --git a/probe-rs/targets/MIMXRT500.yaml b/probe-rs/targets/MIMXRT500.yaml
index 94c15f8b..22b80b34 100644
--- a/probe-rs/targets/MIMXRT500.yaml
+++ b/probe-rs/targets/MIMXRT500.yaml
@@ -323,6 +323,7 @@ flash_algorithms:
   # on the official evaluation kit boards.
   instructions: cLVA8gwEwPIABEXyBAYJ6wQAT/QAccTyEwYA8F75QPIEBUPyBADA8gAFzPJAAEn4BQBD9gAAxPIDAAAhAWBD8hwAxPIDAAFgQPIBEPBiQvIwYMTyAABP9IAxAWAMIUFgT/D/MYFgwWCwaEDwAQCwYDBowAcJ0DBowAccvzBoX+rAcALQMGjAB/LRQfIQEMTyAAAfIQFgAyHA+CATACHA+CQTAyAA8Jj4cCPE8gADT/SANsP40G8J6wQBCesFAgEgHmC96HBAAPCXuAC/ACBwR0DyDADA8gAACesAAQEgAPBFuAC/APF4QkDyDADA8gAACesAAdH4xDEBIADwR7gAvwApBL8AIHBHLenwRYGwQPIMChRGiEYGRgAlwPIACgC/CesKBwbxeEIBIDlGI0YA8BP41/jAEQ1EDERFRQ5E79MBsL3o8IUAAE/yHALB8gIyEmhSaBBHAL9P8hwMwfICPNz4AMDc+AjAYEcAv0/yHALB8gIyEmjSaBBHAL9P8hwDwfICMxto22kYRwC/T/IcDMHyAjzc+ADA3PgQwGBHAL9P8hwMwfICPNz4AMDc+CDAYEcAv0/yHAzB8gI83PgAwNz4KMBgRwC/T/IcAsHyAjISaFJqEEcAv0/yHAHB8gIxCWjJaghHAL9P8hwDwfICMxtoG2sYRwC/cLWCsAxGBUZC8hBwAZAAvwGYQR4BkWCxAZhBHgGRQLEBmEEeAZEgsQGYQR4AKAGR7tFP8hwGwfICNjBoIUbDaShGmEcIsQKwcL0waCFGQmgoRpBHArBwvU/yIAHB8gIxCWgJaAhHAL9P8iAAwfICMABoQGgARwC/T/IgAsHyAjISaJJoEEcAv0/yIAPB8gIzG2jbaBhHAL9P8iAAwfICMABoQGkARwC/T/IgA8HyAjMbaJtpGEcAv0/yIAPB8gIzG2gbaRhHAL9P8gABwfICMQloCEfSsgHgAPgBK0ke+9JwRwAi9ucQtRNGCkYERhlG//fw/yBGEL0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
   load_address: 0x1001c000
+  stack_size: 4096
   pc_init: 0x1
   pc_uninit: 0xcd
   pc_program_page: 0x101
@@ -349,6 +350,7 @@ flash_algorithms:
   # on the official evaluation kit boards.
   instructions: cLVA8gwEwPIABEXyBAYJ6wQAT/QAccTyEwYA8F75QPIEBUPyBADA8gAFzPJAAEn4BQBD9gAAxPIDAAAhAWBD8hwAxPIDAAFgQPIBEPBiQvIwYMTyAABP9IAxAWAMIUFgT/D/MYFgwWCwaEDwAQCwYDBowAcJ0DBowAccvzBoX+rAcALQMGjAB/LRQfIQEMTyAAAfIQFgAyHA+CATACHA+CQTAyAA8Jj4cCPE8gADT/SANsP40G8J6wQBCesFAgEgHmC96HBAAPCXuAC/ACBwR0DyDADA8gAACesAAQEgAPBFuAC/APFoQkDyDADA8gAACesAAdH4xDEBIADwR7gAvwApBL8AIHBHLenwRYGwQPIMChRGiEYGRgAlwPIACgC/CesKBwbxaEIBIDlGI0YA8BP41/jAEQ1EDERFRQ5E79MBsL3o8IUAAE/yHALB8gIyEmhSaBBHAL9P8hwMwfICPNz4AMDc+AjAYEcAv0/yHALB8gIyEmjSaBBHAL9P8hwDwfICMxto22kYRwC/T/IcDMHyAjzc+ADA3PgQwGBHAL9P8hwMwfICPNz4AMDc+CDAYEcAv0/yHAzB8gI83PgAwNz4KMBgRwC/T/IcAsHyAjISaFJqEEcAv0/yHAHB8gIxCWjJaghHAL9P8hwDwfICMxtoG2sYRwC/cLWCsAxGBUZC8hBwAZAAvwGYQR4BkWCxAZhBHgGRQLEBmEEeAZEgsQGYQR4AKAGR7tFP8hwGwfICNjBoIUbDaShGmEcIsQKwcL0waCFGQmgoRpBHArBwvU/yIAHB8gIxCWgJaAhHAL9P8iAAwfICMABoQGgARwC/T/IgAsHyAjISaJJoEEcAv0/yIAPB8gIzG2jbaBhHAL9P8iAAwfICMABoQGkARwC/T/IgA8HyAjMbaJtpGEcAv0/yIAPB8gIzG2gbaRhHAL9P8gABwfICMQloCEfSsgHgAPgBK0ke+9JwRwAi9ucQtRNGCkYERhlG//fw/yBGEL0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
   load_address: 0x1001c000
+  stack_size: 4096
   pc_init: 0x1
   pc_uninit: 0xcd
   pc_program_page: 0x101
diff --git a/probe-rs/targets/SAMD21.yaml b/probe-rs/targets/SAMD21.yaml
index db253f21..29b413ac 100644
--- a/probe-rs/targets/SAMD21.yaml
+++ b/probe-rs/targets/SAMD21.yaml
@@ -2,6 +2,45 @@ name: SAMD21
 manufacturer:
   id: 0x1f
   cc: 0x0
+chip_detection:
+ - !AtsamDsu
+    processor: 1
+    family: 0
+    series: 1
+    variants:
+      0x00: ATSAMD21J18A
+      0x01: ATSAMD21J17A
+      0x02: ATSAMD21J16A
+      0x03: ATSAMD21J15A
+      0x05: ATSAMD21G18A
+      0x0F: ATSAMD21G18AU
+      0x06: ATSAMD21G17A
+      0x10: ATSAMD21G17AU
+      0x07: ATSAMD21G16A
+      0x08: ATSAMD21G15A
+      0x0A: ATSAMD21E18A
+      0x0B: ATSAMD21E17A
+      0x0C: ATSAMD21E16A
+      0x0D: ATSAMD21E15A
+      0x20: ATSAMD21J16B
+      0x21: ATSAMD21J15B
+      0x23: ATSAMD21G16B
+      0x24: ATSAMD21G15B
+      0x26: ATSAMD21E16B
+      0x55: ATSAMD21E16BU
+      0x27: ATSAMD21E15B
+      0x56: ATSAMD21E15BU
+      0x57: ATSAMD21G16L
+      0x3E: ATSAMD21E16L
+      0x3F: ATSAMD21E15L
+      0x62: ATSAMD21E16CU
+      0x63: ATSAMD21E15CU
+      0x94: ATSAMD21E17D
+      0x95: ATSAMD21E17DU
+      0x97: ATSAMD21E17L
+      0x93: ATSAMD21G17D
+      0x96: ATSAMD21G17L
+      0x92: ATSAMD21J17D
 variants:
 - name: ATSAMD21E15A
   cores:
diff --git a/probe-rs/targets/SAMD51.yaml b/probe-rs/targets/SAMD51.yaml
index 9ea1f9f0..df707b4d 100644
--- a/probe-rs/targets/SAMD51.yaml
+++ b/probe-rs/targets/SAMD51.yaml
@@ -2,6 +2,21 @@ name: SAMD51
 manufacturer:
   id: 0x1f
   cc: 0x0
+chip_detection:
+ - !AtsamDsu
+    processor: 6
+    family: 0
+    series: 6
+    variants:
+      0x00: ATSAMD51P20A
+      0x01: ATSAMD51P19A
+      0x02: ATSAMD51N20A
+      0x03: ATSAMD51N19A
+      0x04: ATSAMD51J20A
+      0x05: ATSAMD51J19A
+      0x06: ATSAMD51J18A
+      0x07: ATSAMD51G19A
+      0x08: ATSAMD51G18A
 variants:
 - name: ATSAMD51G18A
   cores:
diff --git a/probe-rs/targets/SAMDA1.yaml b/probe-rs/targets/SAMDA1.yaml
index ead1e4b7..1c9e67c1 100644
--- a/probe-rs/targets/SAMDA1.yaml
+++ b/probe-rs/targets/SAMDA1.yaml
@@ -2,6 +2,30 @@ name: SAMDA1
 manufacturer:
   id: 0x1f
   cc: 0x0
+chip_detection:
+ - !AtsamDsu
+    processor: 1
+    family: 0
+    series: 1
+    variants:
+      0x31: ATSAMDA1E14A
+      0x30: ATSAMDA1E15A
+      0x2F: ATSAMDA1E16A
+      0x2E: ATSAMDA1G14A
+      0x2D: ATSAMDA1G15A
+      0x2C: ATSAMDA1G16A
+      0x2B: ATSAMDA1J14A
+      0x2A: ATSAMDA1J15A
+      0x29: ATSAMDA1J16A
+      0x6C: ATSAMDA1E14B
+      0x6B: ATSAMDA1E15B
+      0x6A: ATSAMDA1E16B
+      0x69: ATSAMDA1G14B
+      0x68: ATSAMDA1G15B
+      0x67: ATSAMDA1G16B
+      0x66: ATSAMDA1J14B
+      0x65: ATSAMDA1J15B
+      0x64: ATSAMDA1J16B
 variants:
 - name: ATSAMDA1E14B
   cores:
diff --git a/probe-rs/targets/SAME51.yaml b/probe-rs/targets/SAME51.yaml
index 682921e9..002361a1 100644
--- a/probe-rs/targets/SAME51.yaml
+++ b/probe-rs/targets/SAME51.yaml
@@ -2,6 +2,18 @@ name: SAME51
 manufacturer:
   id: 0x1f
   cc: 0x0
+chip_detection:
+ - !AtsamDsu
+    processor: 6
+    family: 3
+    series: 1
+    variants:
+      0x00: ATSAME51N20A
+      0x01: ATSAME51N19A
+      0x02: ATSAME51J19A
+      0x03: ATSAME51J18A
+      0x04: ATSAME51J20A
+      0x06: ATSAME51G18A
 variants:
 - name: ATSAME51G18A
   cores:
diff --git a/probe-rs/targets/SAME53.yaml b/probe-rs/targets/SAME53.yaml
index b53333d9..3484b2dd 100644
--- a/probe-rs/targets/SAME53.yaml
+++ b/probe-rs/targets/SAME53.yaml
@@ -2,6 +2,17 @@ name: SAME53
 manufacturer:
   id: 0x1f
   cc: 0x0
+chip_detection:
+ - !AtsamDsu
+    processor: 6
+    family: 3
+    series: 3
+    variants:
+      0x02: ATSAME53N20A
+      0x03: ATSAME53N19A
+      0x04: ATSAME53J20A
+      0x05: ATSAME53J19A
+      0x06: ATSAME53J18A
 variants:
 - name: ATSAME53J18A
   cores:
diff --git a/probe-rs/targets/SAME54.yaml b/probe-rs/targets/SAME54.yaml
index 68124e7a..68904a9e 100644
--- a/probe-rs/targets/SAME54.yaml
+++ b/probe-rs/targets/SAME54.yaml
@@ -2,6 +2,16 @@ name: SAME54
 manufacturer:
   id: 0x1f
   cc: 0x0
+chip_detection:
+ - !AtsamDsu
+    processor: 6
+    family: 3
+    series: 4
+    variants:
+      0x00: ATSAME54P20A
+      0x01: ATSAME54P19A
+      0x02: ATSAME54N20A
+      0x03: ATSAME54N19A
 variants:
 - name: ATSAME54N19A
   cores:
diff --git a/probe-rs/targets/STM32F0_Series.yaml b/probe-rs/targets/STM32F0_Series.yaml
index fc4d6169..4b65aef5 100644
--- a/probe-rs/targets/STM32F0_Series.yaml
+++ b/probe-rs/targets/STM32F0_Series.yaml
@@ -2,6 +2,8 @@ name: STM32F0 Series
 manufacturer:
   id: 0x20
   cc: 0x0
+generated_from_pack: true
+pack_file_release: 2.1.1
 variants:
 - name: STM32F030C6Tx
   cores:
@@ -12,12 +14,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -25,7 +29,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F030C8Tx
   cores:
@@ -36,12 +40,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -49,7 +55,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F030CCTx
   cores:
@@ -60,12 +66,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -73,7 +81,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_256
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F030F4Px
   cores:
@@ -84,12 +92,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -97,7 +107,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F030K6Tx
   cores:
@@ -108,12 +118,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -121,7 +133,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F030R8Tx
   cores:
@@ -132,12 +144,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -145,7 +159,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F030RCTx
   cores:
@@ -156,12 +170,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -169,7 +185,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_256
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F031C4Tx
   cores:
@@ -180,12 +196,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -193,7 +211,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F031C6Tx
   cores:
@@ -204,12 +222,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -217,7 +237,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F031E6Yx
   cores:
@@ -228,12 +248,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -241,7 +263,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F031F4Px
   cores:
@@ -252,12 +274,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -265,7 +289,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F031F6Px
   cores:
@@ -276,12 +300,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -289,7 +315,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F031G4Ux
   cores:
@@ -300,12 +326,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -313,7 +341,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F031G6Ux
   cores:
@@ -324,12 +352,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -337,7 +367,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F031K4Ux
   cores:
@@ -348,12 +378,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -361,7 +393,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F031K6Tx
   cores:
@@ -372,12 +404,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -385,7 +419,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F031K6Ux
   cores:
@@ -396,12 +430,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -409,7 +445,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F038C6Tx
   cores:
@@ -420,12 +456,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -433,7 +471,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F038E6Yx
   cores:
@@ -444,12 +482,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -457,7 +497,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F038F6Px
   cores:
@@ -468,12 +508,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -481,7 +523,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F038G6Ux
   cores:
@@ -492,12 +534,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -505,7 +549,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F038K6Ux
   cores:
@@ -516,12 +560,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -529,7 +575,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F042C4Tx
   cores:
@@ -540,12 +586,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -553,7 +601,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F042C4Ux
   cores:
@@ -564,12 +612,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -577,7 +627,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F042C6Tx
   cores:
@@ -588,12 +638,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -601,7 +653,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F042C6Ux
   cores:
@@ -612,12 +664,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -625,7 +679,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F042F4Px
   cores:
@@ -636,12 +690,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -649,7 +705,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F042F6Px
   cores:
@@ -660,12 +716,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -673,7 +731,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F042G4Ux
   cores:
@@ -684,12 +742,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -697,7 +757,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F042G6Ux
   cores:
@@ -708,12 +768,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -721,7 +783,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F042K4Tx
   cores:
@@ -732,12 +794,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -745,7 +809,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F042K4Ux
   cores:
@@ -756,12 +820,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -769,7 +835,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F042K6Tx
   cores:
@@ -780,12 +846,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -793,7 +861,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F042K6Ux
   cores:
@@ -804,12 +872,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -817,7 +887,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F042T6Yx
   cores:
@@ -828,12 +898,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -841,7 +913,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F048C6Ux
   cores:
@@ -852,12 +924,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -865,7 +939,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F048G6Ux
   cores:
@@ -876,12 +950,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -889,7 +965,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F048T6Yx
   cores:
@@ -900,12 +976,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -913,7 +991,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F051C4Tx
   cores:
@@ -924,12 +1002,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -937,7 +1017,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F051C4Ux
   cores:
@@ -948,12 +1028,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -961,7 +1043,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F051C6Tx
   cores:
@@ -972,12 +1054,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -985,7 +1069,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F051C6Ux
   cores:
@@ -996,12 +1080,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -1009,7 +1095,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F051C8Tx
   cores:
@@ -1020,12 +1106,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1033,7 +1121,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F051C8Ux
   cores:
@@ -1044,12 +1132,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1057,7 +1147,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F051K4Tx
   cores:
@@ -1068,12 +1158,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -1081,7 +1173,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F051K4Ux
   cores:
@@ -1092,12 +1184,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -1105,7 +1199,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F051K6Tx
   cores:
@@ -1116,12 +1210,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -1129,7 +1225,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F051K6Ux
   cores:
@@ -1140,12 +1236,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -1153,7 +1251,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F051K8Tx
   cores:
@@ -1164,12 +1262,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1177,7 +1277,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F051K8Ux
   cores:
@@ -1188,12 +1288,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1201,7 +1303,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F051R4Tx
   cores:
@@ -1212,12 +1314,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -1225,7 +1329,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F051R6Tx
   cores:
@@ -1236,12 +1340,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -1249,7 +1355,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F051R8Hx
   cores:
@@ -1260,12 +1366,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1273,7 +1381,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F051R8Tx
   cores:
@@ -1284,12 +1392,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1297,7 +1407,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F051T8Yx
   cores:
@@ -1308,12 +1418,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1321,7 +1433,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F058C8Ux
   cores:
@@ -1332,12 +1444,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1345,7 +1459,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F058R8Hx
   cores:
@@ -1356,12 +1470,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1369,7 +1485,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F058R8Tx
   cores:
@@ -1380,12 +1496,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1393,7 +1511,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F058T8Yx
   cores:
@@ -1404,12 +1522,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1417,7 +1537,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F070C6Tx
   cores:
@@ -1428,12 +1548,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -1441,7 +1563,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F070CBTx
   cores:
@@ -1452,12 +1574,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1465,7 +1589,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F070F6Px
   cores:
@@ -1476,12 +1600,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -1489,7 +1615,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_64
   - stm32f0xx_opt
 - name: STM32F070RBTx
   cores:
@@ -1500,12 +1626,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1513,7 +1641,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F071C8Tx
   cores:
@@ -1524,12 +1652,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1537,7 +1667,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F071C8Ux
   cores:
@@ -1548,12 +1678,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1561,7 +1693,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F071CBTx
   cores:
@@ -1572,12 +1704,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1585,7 +1719,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F071CBUx
   cores:
@@ -1596,12 +1730,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1609,7 +1745,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F071CBYx
   cores:
@@ -1620,12 +1756,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1633,7 +1771,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F071RBTx
   cores:
@@ -1644,12 +1782,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1657,7 +1797,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F071V8Hx
   cores:
@@ -1668,12 +1808,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1681,7 +1823,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F071V8Tx
   cores:
@@ -1692,12 +1834,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1705,7 +1849,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F071VBHx
   cores:
@@ -1716,12 +1860,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1729,7 +1875,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F071VBTx
   cores:
@@ -1740,12 +1886,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1753,7 +1901,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F072C8Tx
   cores:
@@ -1764,12 +1912,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1777,7 +1927,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F072C8Ux
   cores:
@@ -1788,12 +1938,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1801,7 +1953,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F072CBTx
   cores:
@@ -1812,12 +1964,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1825,7 +1979,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F072CBUx
   cores:
@@ -1836,12 +1990,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1849,7 +2005,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F072CBYx
   cores:
@@ -1860,12 +2016,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1873,7 +2031,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F072R8Tx
   cores:
@@ -1884,12 +2042,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1897,7 +2057,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F072RBHx
   cores:
@@ -1908,12 +2068,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1921,7 +2083,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F072RBIx
   cores:
@@ -1932,12 +2094,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1945,7 +2109,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F072RBTx
   cores:
@@ -1956,12 +2120,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1969,7 +2135,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F072V8Hx
   cores:
@@ -1980,12 +2146,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1993,7 +2161,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F072V8Tx
   cores:
@@ -2004,12 +2172,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -2017,7 +2187,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F072VBHx
   cores:
@@ -2028,12 +2198,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -2041,7 +2213,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F072VBTx
   cores:
@@ -2052,12 +2224,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -2065,7 +2239,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F078CBTx
   cores:
@@ -2076,12 +2250,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -2089,7 +2265,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F078CBUx
   cores:
@@ -2100,12 +2276,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -2113,7 +2291,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F078CBYx
   cores:
@@ -2124,12 +2302,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -2137,7 +2317,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F078RBHx
   cores:
@@ -2148,12 +2328,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -2161,7 +2343,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F078RBTx
   cores:
@@ -2172,12 +2354,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -2185,7 +2369,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F078VBHx
   cores:
@@ -2196,12 +2380,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -2209,7 +2395,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F078VBTx
   cores:
@@ -2220,12 +2406,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -2233,7 +2421,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F091CBTx
   cores:
@@ -2244,12 +2432,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -2257,7 +2447,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F091CBUx
   cores:
@@ -2268,12 +2458,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -2281,7 +2473,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F091CCTx
   cores:
@@ -2292,12 +2484,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -2305,7 +2499,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_256
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F091CCUx
   cores:
@@ -2316,12 +2510,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -2329,7 +2525,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_256
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F091RBTx
   cores:
@@ -2340,12 +2536,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -2353,7 +2551,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F091RCHx
   cores:
@@ -2364,12 +2562,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -2377,7 +2577,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_256
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F091RCTx
   cores:
@@ -2388,12 +2588,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -2401,7 +2603,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_256
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F091RCYx
   cores:
@@ -2412,12 +2614,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -2425,7 +2629,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_256
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F091VBTx
   cores:
@@ -2436,12 +2640,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -2449,7 +2655,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_128
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F091VCHx
   cores:
@@ -2460,12 +2666,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -2473,7 +2681,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_256
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F091VCTx
   cores:
@@ -2484,12 +2692,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -2497,7 +2707,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_256
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F098CCTx
   cores:
@@ -2508,12 +2718,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -2521,7 +2733,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_256
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F098CCUx
   cores:
@@ -2532,12 +2744,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -2545,7 +2759,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_256
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F098RCHx
   cores:
@@ -2556,12 +2770,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -2569,7 +2785,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_256
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F098RCTx
   cores:
@@ -2580,12 +2796,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -2593,7 +2811,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_256
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F098RCYx
   cores:
@@ -2604,12 +2822,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -2617,7 +2837,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_256
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F098VCHx
   cores:
@@ -2628,12 +2848,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -2641,7 +2863,7 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_256
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 - name: STM32F098VCTx
   cores:
@@ -2652,12 +2874,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -2665,13 +2889,13 @@ variants:
     cores:
     - main
   flash_algorithms:
-  - stm32f0xx_256
+  - stm32f0xx_256_2k
   - stm32f0xx_opt
 flash_algorithms:
-- name: stm32f0xx_256
-  description: STM32F0xx 256kB Flash
+- name: stm32f0xx_64
+  description: STM32F0xx 64kB Flash
   default: true
-  instructions: RkhFSUFgRklBYAAhAWDBaBQiEUPBYMBpQAcG1EJIQUkBYAYhQWBBSYFgACBwRztIAWmAIhFDAWEAIHBHMLU3SMFoFCQhQ8FgAWkEJSlDAWEBaUAiEUMBYTVJM0oA4BFgw2jbB/vRAWmpQwFhwWghQgTQwWghQ8FgASAwvQAgML0wtSZJymgUIxpDymAKaQIkIkMKYUhhCGlAIhBDCGEkSCFKAOAQYM1o7Qf70QhpoEMIYchoGEAD0MhoGEPIYAEgML3wtRVNSRxJCOtoSQAEJCND62AUJxZMGuAraQEmM0MrYROIA4AQSwDgHGDuaPYH+9EraVsIWwArYetoO0IE0OhoOEPoYAEg8L2AHIkekhwAKeLRACDwvSMBZ0UAIAJAq4nvzVVVAAAAMABA/w8AAKqqAAAAAAAA
+  instructions: RkhFSUFgRklBYAAhAWDBaBQiEUPBYMBpQAcG1EJIQUkBYAYhQWBBSYFgACBwRztIAWmAIhFDAWEAIHBHMLU3SMFoFCQhQ8FgAWkEJSlDAWEBaUAiEUMBYTVJM0oA4BFgw2jbB/vRAWmpQwFhwWghQgTQwWghQ8FgASAwvQAgML0wtSZJymgUIxpDymAKaQIkIkMKYUhhCGlAIhBDCGEkSCFKAOAQYM1o7Qf70QhpoEMIYchoGEAD0MhoGEPIYAEgML3wtRVNSRxJCOtoSQAEJCND62AUJxZMGuAraQEmM0MrYROIA4AQSwDgHGDuaPYH+9EraVsIWwArYetoO0IE0OhoOEPoYAEg8L2AHJIciR4AKeLRACDwvSMBZ0UAIAJAq4nvzVVVAAAAMABA/w8AAKqqAAAAAAAA
   pc_init: 0x1
   pc_uninit: 0x2f
   pc_program_page: 0xc3
@@ -2681,7 +2905,7 @@ flash_algorithms:
   flash_properties:
     address_range:
       start: 0x8000000
-      end: 0x8040000
+      end: 0x8010000
     page_size: 0x400
     erased_byte_value: 0xff
     program_page_timeout: 100
@@ -2689,8 +2913,6 @@ flash_algorithms:
     sectors:
     - size: 0x400
       address: 0x0
-  cores:
-  - main
 - name: stm32f0xx_opt
   description: STM32F0xx Flash Options
   instructions: U0hSSkJgU0lBYIJggWAAIQFgwWgUIhFDwWDAaUAHBtROSE1JAWAGIUFgTUmBYAAgcEdHSAFpgCIRQwFhAWmCFZFDAWEAIHBHcLVBSMFoFCMZQ8FgAWkgJCFDAWEBaUAiEUMBYT9JPUoA4BFgxWjtB/vRBWmlQwVhBWkQJCVDBWE1TTlOVTU1gADgEWDFaO0H+9EBaaFDAWHBaBlCBNDBaBlDwWABIHC9ACBwvTC1KEjBaBQkIUPBYAFpICUpQwFhAWlAIhFDAWEmSSRKAOARYMNo2wf70QFpqUMBYcFoIUIE0MFoIUPBYAEgML0AIDC9ASBwR/C1Fk1JHEkI62hJAAQkI0PrYBAmFksa4CxpNEMsYRSIBIARTADgI2DvaP8H+9EsabRDLGHsaBQnPEIF0OhoFCEIQ+hgASDwvYAckhyJHgAp4tEAIPC9AAAjAWdFACACQKuJ781VVQAAADAAQP8PAACqqgAAAPj/HwAAAAA=
@@ -2711,12 +2933,10 @@ flash_algorithms:
     sectors:
     - size: 0x10
       address: 0x0
-  cores:
-  - main
-- name: stm32f0xx_128
-  description: STM32F0xx 128kB Flash
+- name: stm32f0xx_256_2k
+  description: STM32F0xx 256kB Flash (2kB page)
   default: true
-  instructions: RkhFSUFgRklBYAAhAWDBaBQiEUPBYMBpQAcG1EJIQUkBYAYhQWBBSYFgACBwRztIAWmAIhFDAWEAIHBHMLU3SMFoFCQhQ8FgAWkEJSlDAWEBaUAiEUMBYTVJM0oA4BFgw2jbB/vRAWmpQwFhwWghQgTQwWghQ8FgASAwvQAgML0wtSZJymgUIxpDymAKaQIkIkMKYUhhCGlAIhBDCGEkSCFKAOAQYM1o7Qf70QhpoEMIYchoGEAD0MhoGEPIYAEgML3wtRVNSRxJCOtoSQAEJCND62AUJxZMGuAraQEmM0MrYROIA4AQSwDgHGDuaPYH+9EraVsIWwArYetoO0IE0OhoOEPoYAEg8L2AHJIciR4AKeLRACDwvSMBZ0UAIAJAq4nvzVVVAAAAMABA/w8AAKqqAAAAAAAA
+  instructions: RkhFSUFgRklBYAAhAWDBaBQiEUPBYMBpQAcG1EJIQUkBYAYhQWBBSYFgACBwRztIAWmAIhFDAWEAIHBHMLU3SMFoFCQhQ8FgAWkEJSlDAWEBaUAiEUMBYTVJM0oA4BFgw2jbB/vRAWmpQwFhwWghQgTQwWghQ8FgASAwvQAgML0wtSZJymgUIxpDymAKaQIkIkMKYUhhCGlAIhBDCGEkSCFKAOAQYM1o7Qf70QhpoEMIYchoGEAD0MhoGEPIYAEgML3wtRVNSRxJCOtoSQAEJCND62AUJxZMGuAraQEmM0MrYROIA4AQSwDgHGDuaPYH+9EraVsIWwArYetoO0IE0OhoOEPoYAEg8L2AHIkekhwAKeLRACDwvSMBZ0UAIAJAq4nvzVVVAAAAMABA/w8AAKqqAAAAAAAA
   pc_init: 0x1
   pc_uninit: 0x2f
   pc_program_page: 0xc3
@@ -2726,13 +2946,11 @@ flash_algorithms:
   flash_properties:
     address_range:
       start: 0x8000000
-      end: 0x8020000
+      end: 0x8040000
     page_size: 0x400
     erased_byte_value: 0xff
     program_page_timeout: 100
     erase_sector_timeout: 6000
     sectors:
-    - size: 0x400
+    - size: 0x800
       address: 0x0
-  cores:
-  - main
diff --git a/probe-rs/targets/STM32F1_Series.yaml b/probe-rs/targets/STM32F1_Series.yaml
index 61e443f7..65d9c226 100644
--- a/probe-rs/targets/STM32F1_Series.yaml
+++ b/probe-rs/targets/STM32F1_Series.yaml
@@ -2,6 +2,8 @@ name: STM32F1 Series
 manufacturer:
   id: 0x20
   cc: 0x0
+generated_from_pack: true
+pack_file_release: 2.4.1
 variants:
 - name: STM32F100C4
   cores:
@@ -12,12 +14,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -36,12 +40,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -60,12 +66,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -84,12 +92,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -108,12 +118,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -132,12 +144,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -156,12 +170,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -180,12 +196,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -204,12 +222,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20006000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -228,12 +248,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8060000
@@ -252,12 +274,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -276,12 +300,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -300,12 +326,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -324,12 +352,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20006000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -348,12 +378,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8060000
@@ -372,12 +404,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -396,12 +430,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20006000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -420,12 +456,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8060000
@@ -444,12 +482,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -468,12 +508,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -492,12 +534,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -516,12 +560,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -540,12 +586,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -564,12 +612,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -588,12 +638,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -612,12 +664,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -636,12 +690,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -660,12 +716,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -684,12 +742,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x2000c000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8060000
@@ -708,12 +768,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x2000c000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -732,12 +794,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20014000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x80c0000
@@ -756,12 +820,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20014000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -780,12 +846,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -804,12 +872,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -828,12 +898,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -852,12 +924,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -876,12 +950,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -900,12 +976,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -924,12 +1002,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -948,12 +1028,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x2000c000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8060000
@@ -972,12 +1054,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x2000c000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -996,12 +1080,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20014000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x80c0000
@@ -1020,12 +1106,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20014000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -1044,12 +1132,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20008000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -1068,12 +1158,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x2000c000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8060000
@@ -1092,12 +1184,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x2000c000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -1116,12 +1210,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20014000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x80c0000
@@ -1140,12 +1236,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20014000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -1164,12 +1262,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -1188,12 +1288,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -1212,12 +1314,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1236,12 +1340,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1260,12 +1366,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -1284,12 +1392,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -1308,12 +1418,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1332,12 +1444,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20004000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1356,12 +1470,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -1380,12 +1496,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -1404,12 +1522,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20005000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1428,12 +1548,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20005000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1452,12 +1574,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -1476,12 +1600,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -1500,12 +1626,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20005000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1524,12 +1652,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20005000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1548,12 +1678,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x2000c000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -1572,12 +1704,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20010000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8060000
@@ -1596,12 +1730,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20010000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -1620,12 +1756,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20018000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x80c0000
@@ -1644,12 +1782,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20018000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -1668,12 +1808,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20001800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8004000
@@ -1692,12 +1834,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20002800
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8008000
@@ -1716,12 +1860,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20005000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1740,12 +1886,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20005000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1764,12 +1912,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20005000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -1788,12 +1938,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20005000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -1812,12 +1964,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x2000c000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -1836,12 +1990,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20010000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8060000
@@ -1860,12 +2016,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20010000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -1884,12 +2042,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20018000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x80c0000
@@ -1908,12 +2068,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20018000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -1932,12 +2094,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x2000c000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -1956,12 +2120,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20010000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8060000
@@ -1980,12 +2146,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20010000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -2004,12 +2172,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20018000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x80c0000
@@ -2028,12 +2198,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20018000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -2052,12 +2224,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20010000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -2076,12 +2250,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20010000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -2100,12 +2276,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20010000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -2124,12 +2302,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20010000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8010000
@@ -2148,12 +2328,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20010000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -2172,12 +2354,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20010000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -2196,12 +2380,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20010000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -2220,12 +2406,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20010000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -2244,12 +2432,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20010000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -2268,12 +2458,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20010000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -2284,29 +2476,6 @@ variants:
   - stm32f10x_512
   - stm32f10x_opt
 flash_algorithms:
-- name: stm32f10x_512
-  description: STM32F10x High-density Flash
-  default: true
-  instructions: ELUDRgAgREwgYERIYGBESGBgIEbAaRDwBA8I0UXyVVBATCBgBiBgYED2/3CgYAAgEL0BRjhIAGlA8IAANkoQYQAgcEc0SABpQPAEADJJCGEIRgBpQPBAAAhhA+BK9qogMEkIYCxIwGgQ8AEP9tEqSABpIPAEAChJCGEAIHBHAUYlSABpQPACACNKEGEQRkFhAGlA8EAAEGED4Er2qiAhShBgHUjAaBDwAQ/20RpIAGkg8AIAGEoQYQAgcEcQtQNGSBwg8AEBIuATSABpQPABABFMIGEQiBiAAL8PSMBoEPABD/rRDEgAaSDwAQAKTCBhIEbAaBDwFA8G0CBGwGhA8BQA4GABIBC9mxySHIkeACna0QAg9+cAAAAgAkAjAWdFq4nvzQAwAEAAAAAA
-  pc_init: 0x1
-  pc_uninit: 0x33
-  pc_program_page: 0xbd
-  pc_erase_sector: 0x7f
-  pc_erase_all: 0x45
-  data_section_offset: 0x128
-  flash_properties:
-    address_range:
-      start: 0x8000000
-      end: 0x8080000
-    page_size: 0x400
-    erased_byte_value: 0xff
-    program_page_timeout: 100
-    erase_sector_timeout: 500
-    sectors:
-    - size: 0x800
-      address: 0x0
-  cores:
-  - main
 - name: stm32f10x_128
   description: STM32F10x Med-density Flash
   default: true
@@ -2328,8 +2497,6 @@ flash_algorithms:
     sectors:
     - size: 0x400
       address: 0x0
-  cores:
-  - main
 - name: stm32f10x_opt
   description: STM32F10x Flash Options
   instructions: ELUDRgAgXkwgYF5IYGBeSGBgXEigYFxIoGAgRsBpEPAEDwjRRfJVUFhMIGAGIGBgQPb/cKBgACAQvQFGUEgAaSD0gHBOShBhEEYAaUDwgAAQYQAgcEdKSABpQPAgAEhJCGEIRgBpQPBAAAhhA+BK9qogRkkIYEJIwGgQ8AEP9tE/SABpIPAgAD1JCGEIRgBpQPAQAAhhRfalID1JCIAD4Er2qiA5SQhgNUjAaBDwAQ/20TNIAGkg8BAAMUkIYQhGwGgQ8BQPBtAIRsBoQPAUAMhgASBwRwAg/OcBRihIAGlA8CAAJkoQYRBGAGlA8EAAEGED4Er2qiAkShBgIEjAaBDwAQ/20R5IAGkg8CAAHEoQYQAgcEcDRgEgcEcQtQNGSBwg8AEBJuAVSABpQPAQABNMIGEQiBiAA+BK9qogE0wgYA9IwGgQ8AEP9tEMSABpIPAQAApMIGEgRsBoEPAUDwbQIEbAaEDwFADgYAEgEL2bHJIciR4AKdbRACD35wAAACACQCMBZ0Wrie/NADAAQAD4/x8AAAAA
@@ -2350,8 +2517,27 @@ flash_algorithms:
     sectors:
     - size: 0x10
       address: 0x0
-  cores:
-  - main
+- name: stm32f10x_512
+  description: STM32F10x High-density Flash
+  default: true
+  instructions: ELUDRgAgREwgYERIYGBESGBgIEbAaRDwBA8I0UXyVVBATCBgBiBgYED2/3CgYAAgEL0BRjhIAGlA8IAANkoQYQAgcEc0SABpQPAEADJJCGEIRgBpQPBAAAhhA+BK9qogMEkIYCxIwGgQ8AEP9tEqSABpIPAEAChJCGEAIHBHAUYlSABpQPACACNKEGEQRkFhAGlA8EAAEGED4Er2qiAhShBgHUjAaBDwAQ/20RpIAGkg8AIAGEoQYQAgcEcQtQNGSBwg8AEBIuATSABpQPABABFMIGEQiBiAAL8PSMBoEPABD/rRDEgAaSDwAQAKTCBhIEbAaBDwFA8G0CBGwGhA8BQA4GABIBC9mxySHIkeACna0QAg9+cAAAAgAkAjAWdFq4nvzQAwAEAAAAAA
+  pc_init: 0x1
+  pc_uninit: 0x33
+  pc_program_page: 0xbd
+  pc_erase_sector: 0x7f
+  pc_erase_all: 0x45
+  data_section_offset: 0x128
+  flash_properties:
+    address_range:
+      start: 0x8000000
+      end: 0x8080000
+    page_size: 0x400
+    erased_byte_value: 0xff
+    program_page_timeout: 100
+    erase_sector_timeout: 500
+    sectors:
+    - size: 0x800
+      address: 0x0
 - name: stm32f10x_1024
   description: STM32F10x XL-density Flash
   default: true
@@ -2373,5 +2559,3 @@ flash_algorithms:
     sectors:
     - size: 0x800
       address: 0x0
-  cores:
-  - main
diff --git a/probe-rs/targets/STM32F2_Series.yaml b/probe-rs/targets/STM32F2_Series.yaml
index 7db42c36..2891bcd0 100644
--- a/probe-rs/targets/STM32F2_Series.yaml
+++ b/probe-rs/targets/STM32F2_Series.yaml
@@ -2,6 +2,8 @@ name: STM32F2 Series
 manufacturer:
   id: 0x20
   cc: 0x0
+generated_from_pack: true
+pack_file_release: 2.11.0
 variants:
 - name: STM32F205RBTx
   cores:
@@ -12,12 +14,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20010000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -37,12 +41,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20018000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -62,12 +68,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -87,12 +95,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -112,12 +122,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x80c0000
@@ -128,6 +140,33 @@ variants:
   - stm32f2xx_1024
   - stm32f2xx_opt
   - stm32f2xx_otp
+- name: STM32F205RGEx
+  cores:
+  - name: main
+    type: armv7m
+    core_access_options: !Arm
+      ap: 0
+      psel: 0x0
+  memory_map:
+  - !Ram
+    name: IRAM1
+    range:
+      start: 0x20000000
+      end: 0x20020000
+    cores:
+    - main
+  - !Nvm
+    name: IROM1
+    range:
+      start: 0x8000000
+      end: 0x8100000
+    is_boot_memory: true
+    cores:
+    - main
+  flash_algorithms:
+  - stm32f2xx_1024
+  - stm32f2xx_opt
+  - stm32f2xx_otp
 - name: STM32F205RGTx
   cores:
   - name: main
@@ -137,12 +176,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -162,12 +203,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -187,12 +230,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20010000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8020000
@@ -212,12 +257,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20018000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -237,12 +284,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -262,12 +311,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x80c0000
@@ -287,12 +338,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -312,12 +365,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20018000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -337,12 +392,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -362,12 +419,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x80c0000
@@ -387,12 +446,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -412,12 +473,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -437,12 +500,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -462,12 +527,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -487,12 +554,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -512,12 +581,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x80c0000
@@ -537,12 +608,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x80c0000
@@ -562,12 +635,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -587,12 +662,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -612,12 +689,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -637,12 +716,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -662,12 +743,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x80c0000
@@ -687,12 +770,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -712,12 +797,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8040000
@@ -737,12 +824,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -762,12 +851,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x80c0000
@@ -787,12 +878,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -812,12 +905,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -837,12 +932,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -862,12 +959,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -887,12 +986,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -912,12 +1013,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -937,12 +1040,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -962,12 +1067,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -987,12 +1094,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -1012,12 +1121,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -1037,12 +1148,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -1062,12 +1175,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -1087,12 +1202,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -1112,12 +1229,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8080000
@@ -1137,12 +1256,14 @@ variants:
       psel: 0x0
   memory_map:
   - !Ram
+    name: IRAM1
     range:
       start: 0x20000000
       end: 0x20020000
     cores:
     - main
   - !Nvm
+    name: IROM1
     range:
       start: 0x8000000
       end: 0x8100000
@@ -1179,8 +1300,6 @@ flash_algorithms:
       address: 0x10000
     - size: 0x20000
       address: 0x20000
-  cores:
-  - main
 - name: stm32f2xx_opt
   description: STM32F2xx Flash Options
   instructions: AAMADiAoAtNACQAdcEcQKALTAAnAHHBHgAhwRylIKEmBYClJgWDBaPAiEUPBYEBpgAYG1CZIJUkBYAYhQWAlSYFgACBwRx9IQWkBIhFDQWEAIHBHG0jCaPAhCkPCYB5KQmFCaQIjGkNCYcJoEgYSDwTQwmgKQ8JgASBwRwAgcEcAIHBHEYkQiAkFCQmACIAAAUMMSMNo8CITQ8NgAiMZQ0FhwWjJA/zUwWgJBgkPBNDBaBFDwWABIHBHACBwRwAAOyoZCAA8AkB/bl1MVVUAAAAwAED/DwAA7Kr/DwAAAAA=
@@ -1201,8 +1320,6 @@ flash_algorithms:
     sectors:
     - size: 0x10
       address: 0x0
-  cores:
-  - main
 - name: stm32f2xx_otp
   description: STM32F2xx Flash OTP
   instructions: AAMADiAoAtNACQAdcEcQKALTAAnAHHBHgAhwRyVIJElBYCVJQWAAIQFgwWjwIhFDwWBAaYAGBtQhSCBJAWAGIUFgIEmBYAAgcEcaSAFpQgURQwFhACBwRwAgcEdwtRVNyRyJCOtoiQDwJjND62AAIythFUsX4CxpHEMsYRRoBGDsaOQD/NQsaWQIZAAsYexoJAYkDwTQ6GgwQ+hgASBwvQAdEh0JHwAp5dEAIHC9AAAjAWdFADwCQKuJ781VVQAAADAAQP8PAAABAgAAAAAAAA==
@@ -1222,5 +1339,3 @@ flash_algorithms:
     sectors:
     - size: 0x210
       address: 0x0
-  cores:
-  - main
diff --git a/probe-rs/targets/esp32.yaml b/probe-rs/targets/esp32.yaml
index 6b552801..c427e000 100644
--- a/probe-rs/targets/esp32.yaml
+++ b/probe-rs/targets/esp32.yaml
@@ -2,6 +2,7 @@ name: esp32
 manufacturer:
   id: 0x12
   cc: 0xc
+# chip_detection deliberately missing to avoid misdetecting 1.8V variants
 variants:
 - name: esp32-3.3v
   cores:
diff --git a/probe-rs/targets/esp32c2.yaml b/probe-rs/targets/esp32c2.yaml
index 1f4c2c17..19fecf95 100644
--- a/probe-rs/targets/esp32c2.yaml
+++ b/probe-rs/targets/esp32c2.yaml
@@ -2,6 +2,12 @@ name: esp32c2
 manufacturer:
   id: 0x12
   cc: 0xc
+chip_detection:
+  - !Espressif
+    idcode: 0x0000cc25
+    variants:
+      0x6f51306f: esp32c2 # ECO0
+      0x7c41a06f: esp32c2 # ECO1
 variants:
 - name: esp32c2
   cores:
diff --git a/probe-rs/targets/esp32c3.yaml b/probe-rs/targets/esp32c3.yaml
index 47c9e181..dcdc92ba 100644
--- a/probe-rs/targets/esp32c3.yaml
+++ b/probe-rs/targets/esp32c3.yaml
@@ -2,6 +2,14 @@ name: esp32c3
 manufacturer:
   id: 0x12
   cc: 0xc
+chip_detection:
+  - !Espressif
+    idcode: 0x00005c25
+    variants:
+      0x6921506f: esp32c3 # ECO1 + ECO2
+      0x1b31506f: esp32c3 # ECO3
+      0x4881606f: esp32c3 # ECO6
+      0x4361606f: esp32c3 # ECO7
 variants:
 - name: esp32c3
   cores:
diff --git a/probe-rs/targets/esp32c6.yaml b/probe-rs/targets/esp32c6.yaml
index 74d754e1..700516fc 100644
--- a/probe-rs/targets/esp32c6.yaml
+++ b/probe-rs/targets/esp32c6.yaml
@@ -2,6 +2,11 @@ name: esp32c6
 manufacturer:
   id: 0x12
   cc: 0xc
+chip_detection:
+  - !Espressif
+    idcode: 0x0000dc25
+    variants:
+      0x2CE0806F: esp32c6
 variants:
 - name: esp32c6
   cores:
diff --git a/probe-rs/targets/esp32h2.yaml b/probe-rs/targets/esp32h2.yaml
index 849d2763..c4a6646b 100644
--- a/probe-rs/targets/esp32h2.yaml
+++ b/probe-rs/targets/esp32h2.yaml
@@ -2,6 +2,11 @@ name: esp32h2
 manufacturer:
   id: 0x12
   cc: 0xc
+chip_detection:
+  - !Espressif
+    idcode: 0x00010c25
+    variants:
+      0xD7B73E80: esp32h2
 variants:
 - name: esp32h2
   cores:
diff --git a/probe-rs/targets/esp32s2.yaml b/probe-rs/targets/esp32s2.yaml
index 675359c4..9c4dfe10 100644
--- a/probe-rs/targets/esp32s2.yaml
+++ b/probe-rs/targets/esp32s2.yaml
@@ -2,6 +2,11 @@ name: esp32s2
 manufacturer:
   id: 0x12
   cc: 0xc
+chip_detection:
+  - !Espressif
+    idcode: 0x120034e5
+    variants:
+      0x000007c6: esp32s2
 variants:
 - name: esp32s2
   cores:
diff --git a/probe-rs/targets/esp32s3.yaml b/probe-rs/targets/esp32s3.yaml
index 72a90608..a3d2b77d 100644
--- a/probe-rs/targets/esp32s3.yaml
+++ b/probe-rs/targets/esp32s3.yaml
@@ -2,6 +2,11 @@ name: esp32s3
 manufacturer:
   id: 0x12
   cc: 0xc
+chip_detection:
+  - !Espressif
+    idcode: 0x120034e5
+    variants:
+      0x9: esp32s3
 variants:
 - name: esp32s3
   cores:
diff --git a/probe-rs/targets/nRF51_Series.yaml b/probe-rs/targets/nRF51_Series.yaml
index 1b0d4481..cbbfe9ca 100644
--- a/probe-rs/targets/nRF51_Series.yaml
+++ b/probe-rs/targets/nRF51_Series.yaml
@@ -2,6 +2,116 @@ name: nRF51 Series
 manufacturer:
   id: 0x44
   cc: 0x2
+chip_detection:
+ - !NordicConfigId
+    configid_address: 0x1000005C
+    hwid:
+      # list adapted from https://devzone.nordicsemi.com/f/nordic-q-a/36392/hwid-for-nrf51822
+      # 0x15: nRF51x22_xxAA
+      # 0x1C: nRF51x22_xxAA
+      0x1D: nRF51822_xxAA
+      0x1E: nRF51422_xxAA
+      0x20: nRF51822_xxAA
+      0x21: nRF51822_xxAA
+      0x22: nRF51822_xxAA
+      0x23: nRF51822_xxAA
+      0x24: nRF51422_xxAA
+      0x26: nRF51822_xxAB
+      0x27: nRF51822_xxAB
+      0x28: nRF51822_xxAA
+      0x29: nRF51822_xxAA
+      0x2A: nRF51822_xxAA
+      0x2B: nRF51822_xxAA
+      0x2C: nRF51822_xxAA
+      0x2D: nRF51422_xxAA
+      0x2E: nRF51422_xxAA
+      0x2F: nRF51822_xxAA
+      0x30: nRF51822_xxAA
+      0x31: nRF51422_xxAA
+      0x32: nRF51422_xxAA
+      0x33: nRF51922_xxAA
+      0x34: nRF51822_xxAA
+      0x38: nRF51822_xxAA
+      0x39: nRF51822_xxAA
+      0x3A: nRF51822_xxAB
+      0x3B: nRF51822_xxAB
+      0x3C: nRF51822_xxAA
+      0x3D: nRF51822_xxAA
+      0x3E: nRF51822_xxAA
+      0x3F: nRF51922_xxAA
+      0x40: nRF51822_xxAA
+      0x41: nRF51822_xxAA
+      0x42: nRF51822_xxAA
+      0x43: nRF51822_xxAA
+      0x44: nRF51822_xxAA
+      0x45: nRF51822_xxAA
+      0x46: nRF51822_xxAA
+      0x47: nRF51822_xxAA
+      0x48: nRF51822_xxAA
+      0x49: nRF51822_xxAA
+      0x4A: nRF51822_xxAA
+      0x4B: nRF51922_xxAA
+      0x4C: nRF51822_xxAB
+      0x4D: nRF51822_xxAA
+      0x4E: nRF51822_xxAA
+      0x4F: nRF51822_xxAA
+      0x50: nRF51422_xxAA
+      0x54: nRF51822_xxAA
+      0x56: nRF51822_xxAB
+      0x57: nRF51822_xxAA
+      0x58: nRF51822_xxAA
+      0x59: nRF51822_xxAA
+      0x5A: nRF51822_xxAA
+      0x5B: nRF51822_xxAA
+      0x5C: nRF51422_xxAA
+      0x5D: nRF51822_xxAA
+      0x5E: nRF51422_xxAA
+      0x5F: nRF51822_xxAB
+      0x60: nRF51822_xxAB
+      0x61: nRF51422_xxAB
+      0x63: nRF51422_xxAA
+      0x63: nRF51822_xxAB
+      0x64: nRF51822_xxAB
+      0x65: nRF51422_xxAB
+      0x66: nRF51422_xxAB
+      0x67: nRF51822_xxAB
+      0x68: nRF51422_xxAB
+      0x6A: nRF51822_xxAA
+      0x6B: nRF51822_xxAA
+      0x6C: nRF51822_xxAC
+      0x6D: nRF51422_xxAC
+      0x6E: nRF51822_xxAC
+      0x6F: nRF51822_xxAA
+      0x70: nRF51822_xxAA
+      0x71: nRF51422_xxAC
+      0x72: nRF51822_xxAA
+      0x73: nRF51422_xxAA
+      0x74: nRF51822_xxAC
+      0x75: nRF51422_xxAC
+      0x76: nRF51822_xxAB
+      0x77: nRF51822_xxAA
+      0x79: nRF51822_xxAA
+      0x7A: nRF51422_xxAA
+      0x7B: nRF51822_xxAB
+      0x7C: nRF51422_xxAB
+      0x7d: nRF51822_xxAB
+      0x80: nRF51822_xxAA
+      0x82: nRF51822_xxAC
+      0x83: nRF51822_xxAC
+      0x84: nRF51822_xxAC
+      0x85: nRF51422_xxAC
+      0x86: nRF51422_xxAC
+      0x87: nRF51822_xxAC
+      0x88: nRF51422_xxAC
+      0x8A: nRF51802_xxAA
+      0x8B: nRF51832_xxAA
+      0x8C: nRF51822_xx00
+      0x8E: nRF51822_xxAA
+      0x8F: nRF51822_xxAA
+      0x91: nRF51822_xxAC
+      0x92: nRF51822_xxAQ
+      0x93: nRF51822_xx00
+      0x94: nRF51802_xxAA
 variants:
 - name: nRF51422_xxAA
   cores:
diff --git a/probe-rs/targets/nRF52_Series.yaml b/probe-rs/targets/nRF52_Series.yaml
index 2e7d8d57..941bb971 100644
--- a/probe-rs/targets/nRF52_Series.yaml
+++ b/probe-rs/targets/nRF52_Series.yaml
@@ -2,6 +2,93 @@ name: nRF52 Series
 manufacturer:
   id: 0x44
   cc: 0x2
+chip_detection:
+ - !NordicFicrInfo
+    part_address: 0x10000100
+    variant_address: 0x10000104
+    part: 0x52805
+    variants:
+      0x41414141: nRF52805_xxAA
+      0x41414130: nRF52805_xxAA
+      0x41414241: nRF52805_xxAA
+      0x41414242: nRF52805_xxAA
+      0x41414230: nRF52805_xxAA
+      0x41414231: nRF52805_xxAA
+      0x41414341: nRF52805_xxAA
+      0x41414342: nRF52805_xxAA
+      0x41414330: nRF52805_xxAA
+ - !NordicFicrInfo
+    part_address: 0x10000100
+    variant_address: 0x10000104
+    part: 0x52810
+    variants:
+      0x41414141: nRF52810_xxAA
+      0x41414130: nRF52810_xxAA
+      0x41414241: nRF52810_xxAA
+      0x41414242: nRF52810_xxAA
+      0x41414230: nRF52810_xxAA
+      0x41414341: nRF52810_xxAA
+      0x41414342: nRF52810_xxAA
+      0x41414330: nRF52810_xxAA
+      0x41414530: nRF52810_xxAA
+      0x41414531: nRF52810_xxAA
+ - !NordicFicrInfo
+    part_address: 0x10000100
+    variant_address: 0x10000104
+    part: 0x52811
+    variants:
+      0x41414141: nRF52811_xxAA
+      0x41414130: nRF52811_xxAA
+      0x41414241: nRF52811_xxAA
+      0x41414242: nRF52811_xxAA
+      0x41414230: nRF52811_xxAA
+      0x41414341: nRF52811_xxAA
+      0x41414342: nRF52811_xxAA
+      0x41414330: nRF52811_xxAA
+      0x41414530: nRF52811_xxAA
+      0x41414531: nRF52811_xxAA
+ - !NordicFicrInfo
+    part_address: 0x10000100
+    variant_address: 0x10000104
+    part: 0x52832
+    variants:
+      0x41414141: nRF52832_xxAA
+      0x41414143: nRF52832_xxAA
+      0x41414241: nRF52832_xxAA
+      0x41414242: nRF52832_xxAA
+      0x41414230: nRF52832_xxAA
+      0x41424230: nRF52832_xxAB
+      0x41414530: nRF52832_xxAA
+      0x41424530: nRF52832_xxAB
+      0x41414742: nRF52832_xxAA
+      0x41424742: nRF52832_xxAB
+      0x41414730: nRF52832_xxAA
+      0x41424730: nRF52832_xxAB
+ - !NordicFicrInfo
+    part_address: 0x10000100
+    variant_address: 0x10000104
+    part: 0x52833
+    variants:
+      0x41414141: nRF52833_xxAA
+      0x41414142: nRF52833_xxAA
+      0x41414130: nRF52833_xxAA
+      0x41414131: nRF52833_xxAA
+      0x41414230: nRF52833_xxAA
+ - !NordicFicrInfo
+    part_address: 0x10000100
+    variant_address: 0x10000104
+    part: 0x52840
+    variants:
+      0x41414141: nRF52840_xxAA
+      0x41414242: nRF52840_xxAA
+      0x41414341: nRF52840_xxAA
+      0x41414330: nRF52840_xxAA
+      0x41414441: nRF52840_xxAA
+      0x41414430: nRF52840_xxAA
+      0x41414431: nRF52840_xxAA
+      0x41414541: nRF52840_xxAA
+      0x41414530: nRF52840_xxAA
+      0x41414541: nRF52840_xxAA
 variants:
 - name: nRF52805_xxAA
   cores:
diff --git a/probe-rs/targets/nRF53_Series.yaml b/probe-rs/targets/nRF53_Series.yaml
index 79899495..1e3b0485 100644
--- a/probe-rs/targets/nRF53_Series.yaml
+++ b/probe-rs/targets/nRF53_Series.yaml
@@ -2,6 +2,14 @@ name: nRF53 Series
 manufacturer:
   id: 0x44
   cc: 0x2
+chip_detection:
+ - !NordicFicrInfo
+    part_address: 0x00FF020C # through application core
+    variant_address: 0x00FF0210 # through application core
+    part: 0x5340
+    variants:
+      0x514B4141: nRF5340_xxAA
+      0x434C4141: nRF5340_xxAA
 variants:
 - name: nRF5340_xxAA
   cores:
diff --git a/probe-rs/targets/nRF91_Series.yaml b/probe-rs/targets/nRF91_Series.yaml
index 501f2cca..e66bdcec 100644
--- a/probe-rs/targets/nRF91_Series.yaml
+++ b/probe-rs/targets/nRF91_Series.yaml
@@ -2,6 +2,13 @@ name: nRF91 Series
 manufacturer:
   id: 0x44
   cc: 0x2
+chip_detection:
+ - !NordicFicrInfo
+    part_address: 0x00FF0140 # SIPINFO.PARTNO
+    variant_address: 0x00FF021C # INFO.FLASH
+    part: 0x9160
+    variants:
+      0x400: nRF9160_xxAA
 variants:
 - name: nRF9160_xxAA
   cores:
diff --git a/target-gen/src/commands/elf.rs b/target-gen/src/commands/elf.rs
index 8cd9eb7c..32f4bc02 100644
--- a/target-gen/src/commands/elf.rs
+++ b/target-gen/src/commands/elf.rs
@@ -1,7 +1,7 @@
 use anyhow::{bail, Context, Result};
 use probe_rs_target::{
-    ArmCoreAccessOptions, Chip, ChipFamily, Core, CoreAccessOptions, CoreType, MemoryRegion,
-    NvmRegion, RamRegion, RawFlashAlgorithm, TargetDescriptionSource,
+    ArmCoreAccessOptions, Chip, ChipFamily, Core, CoreAccessOptions, CoreType, MemoryAccess,
+    MemoryRegion, NvmRegion, RamRegion, RawFlashAlgorithm, TargetDescriptionSource,
 };
 use std::{
     borrow::Cow,
@@ -77,6 +77,7 @@ pub fn cmd_elf(
             name: "<family name>".to_owned(),
             manufacturer: None,
             generated_from_pack: false,
+            chip_detection: vec![],
             pack_file_release: None,
             variants: vec![Chip {
                 cores: vec![Core {
@@ -95,17 +96,20 @@ pub fn cmd_elf(
                 name: "<chip name>".to_owned(),
                 memory_map: vec![
                     MemoryRegion::Nvm(NvmRegion {
-                        is_boot_memory: false,
+                        access: None,
                         range: 0..0x2000,
                         cores: vec!["main".to_owned()],
                         name: None,
                         is_alias: false,
                     }),
                     MemoryRegion::Ram(RamRegion {
-                        is_boot_memory: true,
                         range: 0x1_0000..0x2_0000,
                         cores: vec!["main".to_owned()],
                         name: None,
+                        access: Some(MemoryAccess {
+                            boot: true,
+                            ..Default::default()
+                        }),
                     }),
                 ],
                 flash_algorithms: vec![algorithm_name],
@@ -253,6 +257,7 @@ mod test {
             name: "Test Family".to_owned(),
             manufacturer: None,
             generated_from_pack: false,
+            chip_detection: vec![],
             pack_file_release: None,
             variants: vec![Chip::generic_arm("Test Chip", CoreType::Armv8m)],
             flash_algorithms: vec![],
diff --git a/target-gen/src/generate.rs b/target-gen/src/generate.rs
index b53af92e..12cec8ff 100644
--- a/target-gen/src/generate.rs
+++ b/target-gen/src/generate.rs
@@ -5,7 +5,7 @@ use futures::StreamExt;
 use probe_rs::flashing::FlashAlgorithm;
 use probe_rs_target::{
     Architecture, ArmCoreAccessOptions, Chip, ChipFamily, Core as ProbeCore, CoreAccessOptions,
-    CoreType, GenericRegion, MemoryRegion, NvmRegion, RamRegion, RawFlashAlgorithm,
+    CoreType, GenericRegion, MemoryAccess, MemoryRegion, NvmRegion, RamRegion, RawFlashAlgorithm,
     RiscvCoreAccessOptions, TargetDescriptionSource, XtensaCoreAccessOptions,
 };
 use std::collections::HashMap;
@@ -105,6 +105,7 @@ where
                 name: device.family.clone(),
                 manufacturer: None,
                 generated_from_pack: true,
+                chip_detection: vec![],
                 pack_file_release: pack_file_release.clone(),
                 variants: Vec::new(),
                 flash_algorithms: Vec::new(),
@@ -444,7 +445,7 @@ where
 }
 
 /// A flag to indicate what type of memory this is.
-#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 enum MemoryType {
     /// A RAM memory.
     Ram,
@@ -457,14 +458,28 @@ enum MemoryType {
 /// A struct to combine essential information from [`cmsis_pack::pdsc::Device::memories`].
 /// This is used to apply the necessary sorting and filtering in creating [`MemoryRegion`]s.
 // The sequence of the fields is important for the sorting by derived natural order.
-#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Debug, Clone, PartialEq, Eq)]
 struct DeviceMemory {
     memory_type: MemoryType,
     p_name: Option<String>,
-    is_boot_memory: bool,
     memory_start: u64,
     memory_end: u64,
     name: String,
+    access: MemoryAccess,
+}
+
+impl DeviceMemory {
+    fn access(&self) -> Option<MemoryAccess> {
+        fn is_default(access: &MemoryAccess) -> bool {
+            access == &MemoryAccess::default()
+        }
+
+        if is_default(&self.access) {
+            None
+        } else {
+            Some(self.access)
+        }
+    }
 }
 
 /// Extracts the memory regions in the package.
@@ -491,12 +506,24 @@ pub(crate) fn get_mem_map(device: &Device, cores: &[probe_rs_target::Core]) -> V
             },
             memory_start: memory.start,
             memory_end: memory.start + memory.size,
-            is_boot_memory: memory.startup,
+            access: MemoryAccess {
+                read: memory.access.read,
+                write: memory.access.write,
+                execute: memory.access.execute,
+                boot: memory.startup,
+            },
         })
         .collect();
 
     // Sort by memory type, then by processor name, then by boot memory, then by start address.
-    device_memories.sort();
+    device_memories.sort_by_key(|memory| {
+        (
+            memory.memory_type,
+            memory.p_name.clone(),
+            memory.access.boot,
+            memory.memory_start,
+        )
+    });
 
     let all_cores: Vec<_> = cores.iter().map(|core| core.name.clone()).collect();
 
@@ -518,30 +545,30 @@ pub(crate) fn get_mem_map(device: &Device, cores: &[probe_rs_target::Core]) -> V
         match region.memory_type {
             MemoryType::Ram => {
                 if let Some(MemoryRegion::Ram(existing_region)) = mem_map.iter_mut().find(|existing_region| {
-                        matches!(existing_region, MemoryRegion::Ram(ram_region) if ram_region.name.as_deref() == Some(&region.name))
+                        matches!(existing_region, MemoryRegion::Ram(ram_region) if ram_region.name.as_deref() == Some(&region.name) && ram_region.access == region.access())
                     })
                 {
                     existing_region.cores.extend_from_slice(&cores);
                 } else {
                     mem_map.push(MemoryRegion::Ram(RamRegion {
+                        access: region.access(),
                         name: Some(region.name),
                         range: region.memory_start..region.memory_end,
-                        is_boot_memory: region.is_boot_memory,
                         cores,
                     }));
                 }
             },
             MemoryType::Nvm => {
                 if let Some(MemoryRegion::Nvm(existing_region)) = mem_map.iter_mut().find(|existing_region| {
-                        matches!(existing_region, MemoryRegion::Nvm(nvm_region) if nvm_region.name.as_deref() == Some(&region.name))
+                        matches!(existing_region, MemoryRegion::Nvm(nvm_region) if nvm_region.name.as_deref() == Some(&region.name) && nvm_region.access == region.access())
                     })
                 {
                     existing_region.cores.extend_from_slice(&cores);
                 } else {
                     mem_map.push(MemoryRegion::Nvm(NvmRegion {
+                        access: region.access(),
                         name: Some(region.name),
                         range: region.memory_start..region.memory_end,
-                        is_boot_memory: region.is_boot_memory,
                         cores,
                         is_alias: false,
                     }));
@@ -549,12 +576,13 @@ pub(crate) fn get_mem_map(device: &Device, cores: &[probe_rs_target::Core]) -> V
             },
             MemoryType::Generic => {
                 if let Some(MemoryRegion::Generic(existing_region)) = mem_map.iter_mut().find(|existing_region| {
-                        matches!(existing_region, MemoryRegion::Generic(generic_region) if generic_region.name.as_deref() == Some(&region.name))
+                        matches!(existing_region, MemoryRegion::Generic(generic_region) if generic_region.name.as_deref() == Some(&region.name) && generic_region.access == region.access())
                     })
                 {
                     existing_region.cores.extend_from_slice(&cores);
                 } else {
                     mem_map.push(MemoryRegion::Generic(GenericRegion {
+                        access: region.access(),
                         name: Some(region.name),
                         range: region.memory_start..region.memory_end,
                         cores,


Test patch:
diff --git a/.github/workflows/smoketest.yml b/.github/workflows/smoketest.yml
index 0f2c6adc..b9ce27e2 100644
--- a/.github/workflows/smoketest.yml
+++ b/.github/workflows/smoketest.yml
@@ -23,7 +23,7 @@ jobs:
         run: rustup target add aarch64-unknown-linux-gnu
 
       - name: Install cross
-        uses: taiki-e/install-action@v2.39.1
+        uses: taiki-e/install-action@v2.41.3
         with:
           tool: cross
 
diff --git a/probe-rs/tests/gpio-hal-blinky/Cargo.lock b/probe-rs/tests/gpio-hal-blinky/Cargo.lock
index 489f4d27..868b2c11 100644
--- a/probe-rs/tests/gpio-hal-blinky/Cargo.lock
+++ b/probe-rs/tests/gpio-hal-blinky/Cargo.lock
@@ -158,18 +158,18 @@ dependencies = [
 
 [[package]]
 name = "microbit"
-version = "0.14.0"
+version = "0.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ea941ae60d022668f789ff6a6439fdb59b5cea202cd2affbb967e9af7425356"
+checksum = "e65a87c29e39e928c536c160bacf679d815e0c00bca26665b34e2c7eac926b93"
 dependencies = [
  "microbit-common",
 ]
 
 [[package]]
 name = "microbit-common"
-version = "0.14.0"
+version = "0.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37409f40befaa165d8a94255955475337422f5fe2fecaeeeedde170562ee114b"
+checksum = "26d84d7858bbe6cdd89c429be9aa62f2820d1a271e66580df22fe9093bb63c51"
 dependencies = [
  "embedded-hal 1.0.0",
  "nrf51-hal",
@@ -193,9 +193,9 @@ checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
 
 [[package]]
 name = "nrf-hal-common"
-version = "0.17.1"
+version = "0.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56fbecd598c7f16e32bd4783447ca023aa7897d4a4c8e70f6b7c5739c81b4ceb"
+checksum = "0c134de1f2f0191aed3fc24d3831da8808d1e636b06edf81a5717103095f625d"
 dependencies = [
  "cast",
  "cfg-if",
@@ -213,9 +213,9 @@ dependencies = [
 
 [[package]]
 name = "nrf51-hal"
-version = "0.17.1"
+version = "0.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5fb186285d15fdfe7329ebb25e64b898f1c619831c43dc96849f11c3ef244b2a"
+checksum = "22ed1244a7c2c8da0ce121b6ef28175a253c1ddb2ef9849b8f15825295253bcd"
 dependencies = [
  "nrf-hal-common",
  "nrf51-pac",
diff --git a/probe-rs/tests/gpio-hal-blinky/Cargo.toml b/probe-rs/tests/gpio-hal-blinky/Cargo.toml
index 47ac193f..f5643dcc 100644
--- a/probe-rs/tests/gpio-hal-blinky/Cargo.toml
+++ b/probe-rs/tests/gpio-hal-blinky/Cargo.toml
@@ -13,4 +13,4 @@ cortex-m = { version = "0.7", features = [
     "inline-asm",
 ] }
 panic-halt = "0.2.0"
-microbit = "0.14.0"
+microbit = "0.15.0"
diff --git a/smoke-tester/src/tests/stepping.rs b/smoke-tester/src/tests/stepping.rs
index 3c34d05c..45f33a4a 100644
--- a/smoke-tester/src/tests/stepping.rs
+++ b/smoke-tester/src/tests/stepping.rs
@@ -15,29 +15,33 @@ const TEST_CODE: &[u8] = include_bytes!("test_arm.bin");
 fn test_stepping(tracker: &TestTracker, core: &mut Core) -> TestResult {
     println!("Testing stepping...");
 
-    if core.architecture() == Architecture::Riscv {
+    if core.architecture() != Architecture::Arm {
         // Not implemented for RISC-V yet
         return Err(TestFailure::UnimplementedForTarget(
             Box::new(tracker.current_target().clone()),
-            "Testing stepping is not implemented for RISC-V yet.".to_string(),
+            format!(
+                "Testing stepping is not implemented for {:?} yet.",
+                core.architecture()
+            ),
         ));
     }
 
-    let ram_region = core.memory_regions().find_map(MemoryRegion::as_ram_region);
+    let ram_region = core
+        .memory_regions()
+        .filter_map(MemoryRegion::as_ram_region)
+        .find(|r| r.is_executable());
 
-    let ram_region = if let Some(ram_region) = ram_region {
-        ram_region.clone()
-    } else {
+    let Some(ram_region) = ram_region else {
         return Err(TestFailure::Skipped(
             "No RAM configured for core, unable to test stepping".to_string(),
         ));
     };
 
+    let code_load_address = ram_region.range.start;
+
     core.reset_and_halt(Duration::from_millis(100))
         .into_diagnostic()?;
 
-    let code_load_address = ram_region.range.start;
-
     core.write_8(code_load_address, TEST_CODE)
         .into_diagnostic()?;