tsb: one spelling of the clock and the baud, and the asm's bits by name

The tricks and asm tiers spelled 16_MHz three times each and now name it once;
the policy tier's lean bring-up solves the baud from the link config the
serial unit is declared with instead of restating 115200 8N1. The asm tier's
immediates - RXEN0, RXC0's bit, SPMEN, PGWRT|SPMEN and the three UART
addresses - are operands read from the chip database rather than numbers with
comments beside them, so avr/io.h is left for SPMCSR's I/O address alone; pure
and tricks drop an include nothing used. Headers that described the code as it
was are corrected (pure's "only attribute", the policy tier's history), the
rule references leave the comments, and locals are const auto.

All four images are byte-identical to before, in both modes for tsb_asm.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
BlackMarkandClaude Opus 5.5 committed 2026-10-23 21:41:55 +02:00
1 parent 20b1485b6f
commit aafaf25a47
4 files changed
+62 -66

No files matched your search

+7 -10
View File
@@ -4,16 +4,13 @@
// TinySafeBoot native-UART fixed-baud protocol on libavr with the full feature
// set of the hand-written oracle: a watchdog-reset bail, one-wire half-duplex,
// a config-page activation timeout, the password gate, emergency erase, and
// config/flash/EEPROM read-write. This variant is written for clarity -
// config/flash/EEPROM read-write. This variant is written for clarity -
// well-factored functions, no compiler-specific size hacks, no inline assembly.
// The one-wire wiring, the flash-resident info block and every SPM/EEPROM lock
// are libavr's to handle; the only attribute is the naked reset entry that
// stands in for the absent C runtime.
// The one-wire wiring, the flash-resident info block, every SPM/EEPROM lock and
// the crt-free reset entry are libavr's to handle.
#include <libavr/libavr.hpp>
#include <avr/io.h> // SP / RAMEND for the crt-free boot entry
using namespace avr::literals;
namespace spm = avr::spm;
namespace ee = avr::eeprom;
@@ -144,8 +141,8 @@ void store_flash_page(std::uint16_t addr)
{
const auto open = spm::page::begin<spm::from::boot_section, off>(addr);
for (std::uint16_t i = 0; i < page; i += 2) {
std::uint8_t lo = rx();
std::uint8_t hi = rx();
const auto lo = rx();
const auto hi = rx();
spm::fill<off>(open, addr + i, static_cast<std::uint16_t>(lo | (hi << 8)));
}
spm::write_page<spm::from::boot_section, off>(addr); // blocking: waits the write out
@@ -265,11 +262,11 @@ enum class gate : std::uint8_t { pass, emergency };
gate password_gate()
{
for (const std::uint8_t *pw = flash_ptr(app_end + 3);; ++pw) {
std::uint8_t expected = avr::flash_load(pw);
const auto expected = avr::flash_load(pw);
if (expected == 0xff) {
return gate::pass;
}
std::uint8_t got = rx();
const auto got = rx();
if (got == 0) {
return gate::emergency;
}