Update pico-sdk and bazelify it

This borrows heavily from work that Austin did to initially get this
stuff working.

Merge commit 'a1fdcd85e25a8a2b1e3ca5bc31e45bedf9e58266' into HEAD

Signed-off-by: Ravago Jones <ravagojones@gmail.com>
Change-Id: Id47d383bd5fb46664083b365890fd7bad5786c1f
diff --git a/third_party/pico-sdk/tools/elf2uf2/BUILD b/third_party/pico-sdk/tools/elf2uf2/BUILD
index 3c8cf78..1a985c8 100644
--- a/third_party/pico-sdk/tools/elf2uf2/BUILD
+++ b/third_party/pico-sdk/tools/elf2uf2/BUILD
@@ -8,6 +8,7 @@
         "-Wno-format-nonliteral",
         "-Wno-reorder",
         "-Wno-unused-parameter",
+        "-Wno-unused-variable",
         "-Wno-unused-function",
         "-Wno-type-limits",
     ],
diff --git a/third_party/pico-sdk/tools/elf2uf2/main.cpp b/third_party/pico-sdk/tools/elf2uf2/main.cpp
index 2c0ddcd..77e67c7 100644
--- a/third_party/pico-sdk/tools/elf2uf2/main.cpp
+++ b/third_party/pico-sdk/tools/elf2uf2/main.cpp
@@ -6,6 +6,7 @@
 
 #include <cstdio>
 #include <map>
+#include <set>
 #include <vector>
 #include <cstring>
 #include <cstdarg>
@@ -21,6 +22,8 @@
 #define ERROR_READ_FAILED -4
 #define ERROR_WRITE_FAILED -5
 
+#define FLASH_SECTOR_ERASE_SIZE 4096u
+
 static char error_msg[512];
 static bool verbose;
 
@@ -59,14 +62,16 @@
 
 typedef std::vector<address_range> address_ranges;
 
-#define MAIN_RAM_START        0x20000000u
-#define MAIN_RAM_END          0x20042000u
-#define FLASH_START           0x10000000u
+#define MAIN_RAM_START        0x20000000u // same as SRAM_BASE in addressmap.h
+#define MAIN_RAM_END          0x20042000u // same as SRAM_END in addressmap.h
+#define FLASH_START           0x10000000u // same as XIP_MAIN_BASE in addressmap.h
 #define FLASH_END             0x15000000u
-#define XIP_SRAM_START        0x15000000u
-#define XIP_SRAM_END          0x15004000u
-#define MAIN_RAM_BANKED_START 0x21000000u
+#define XIP_SRAM_START        0x15000000u // same as XIP_SRAM_BASE in addressmap.h
+#define XIP_SRAM_END          0x15004000u // same as XIP_SRAM_END in addressmap.h
+#define MAIN_RAM_BANKED_START 0x21000000u // same as SRAM0_BASE in addressmap.h
 #define MAIN_RAM_BANKED_END   0x21040000u
+#define ROM_START             0x00000000u // same as ROM_BASE in addressmap.h
+#define ROM_END               0x00004000u
 
 const address_ranges rp2040_address_ranges_flash {
     address_range(FLASH_START, FLASH_END, address_range::type::CONTENTS),
@@ -77,7 +82,7 @@
 const address_ranges rp2040_address_ranges_ram {
     address_range(MAIN_RAM_START, MAIN_RAM_END, address_range::type::CONTENTS),
     address_range(XIP_SRAM_START, XIP_SRAM_END, address_range::type::CONTENTS),
-    address_range(0x00000000u, 0x00004000u, address_range::type::IGNORE) // for now we ignore the bootrom if present
+    address_range(ROM_START, ROM_END, address_range::type::IGNORE) // for now we ignore the bootrom if present
 };
 
 struct page_fragment {
@@ -293,6 +298,28 @@
                         MAIN_RAM_START, sp);
         }
 #endif
+    } else {
+        // Fill in empty dummy uf2 pages to align the binary to flash sectors (except for the last sector which we don't
+        // need to pad, and choose not to to avoid making all SDK UF2s bigger)
+        // That workaround is required because the bootrom uses the block number for erase sector calculations:
+        // https://github.com/raspberrypi/pico-bootrom/blob/c09c7f08550e8a36fc38dc74f8873b9576de99eb/bootrom/virtual_disk.c#L205
+
+        std::set<uint32_t> touched_sectors;
+        for (auto& page_entry : pages) {
+            uint32_t sector = page_entry.first / FLASH_SECTOR_ERASE_SIZE;
+            touched_sectors.insert(sector);
+        }
+
+        uint32_t last_page = pages.rbegin()->first;
+        for (uint32_t sector : touched_sectors) {
+            for (uint32_t page = sector * FLASH_SECTOR_ERASE_SIZE; page < (sector + 1) * FLASH_SECTOR_ERASE_SIZE; page += PAGE_SIZE) {
+                if (page < last_page) {
+                    // Create a dummy page, if it does not exist yet. note that all present pages are first
+                    // zeroed before they are filled with any contents, so a dummy page will be all zeros.
+                    auto &dummy = pages[page];
+                }
+            }
+        }
     }
     uf2_block block;
     block.magic_start0 = UF2_MAGIC_START0;
@@ -306,7 +333,8 @@
         block.target_addr = page_entry.first;
         block.block_no = page_num++;
         if (verbose) {
-            printf("Page %d / %d %08x\n", block.block_no, block.num_blocks, block.target_addr);
+            printf("Page %d / %d %08x%s\n", block.block_no, block.num_blocks, block.target_addr,
+                   page_entry.second.empty() ? " (padding)": "");
         }
         memset(block.data, 0, sizeof(block.data));
         rc = realize_page(in, page_entry.second, block.data, sizeof(block.data));