tsb: asm tier reaches full oracle feature parity at 502 B
Rewrite the inline-asm tier so it matches the hand-written fixed-baud oracle's feature set inside the 512 B boot section: watchdog-reset bail, one-wire half-duplex (RXEN/TXEN toggled per direction, TX turnaround guard), config-page activation timeout, the password gate (wrong byte hangs draining the UART), emergency erase (password \0 + double-confirm wipes flash, EEPROM and the config page), and config/flash/EEPROM read-write. Every geometry, baud and info-block constant comes from libavr consteval; only the dense control flow is hand-written. 502 B, byte-identical across generated and reflect modes. Test harness: seed the config page from TSB_CONFIG so the password and emergency-erase paths are exercisable, and clear simavr's AVR_UART_FLAG_POLL_ SLEEP — a host-CPU-saving usleep(1)-per-idle-poll hack that models no hardware and paces a one-wire loader (which releases TX between bytes) in real time, distorting protocol timing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "avr_uart.h"
|
||||
#include "sim_avr.h"
|
||||
#include "sim_elf.h"
|
||||
#include "uart_pty.h"
|
||||
@@ -68,6 +69,28 @@ int main(int argc, char *argv[])
|
||||
avr->pc = boot_base;
|
||||
avr->codeend = avr->flashend;
|
||||
|
||||
// Optional: seed the config page (one page below the boot section) with a
|
||||
// hex byte string, so the password gate and emergency erase can be tested.
|
||||
// Layout: [appjump lo][appjump hi][timeout][password...][0xff].
|
||||
const char *cfg = getenv("TSB_CONFIG");
|
||||
if (cfg) {
|
||||
uint32_t app_end = boot_base - 128; // config page sits directly below the boot code
|
||||
for (int i = 0; cfg[i] && cfg[i + 1]; i += 2) {
|
||||
char b[3] = {cfg[i], cfg[i + 1], 0};
|
||||
avr->flash[app_end + i / 2] = (uint8_t)strtoul(b, NULL, 16);
|
||||
}
|
||||
}
|
||||
|
||||
// POLL_SLEEP makes simavr usleep(1) on every status-register read while the
|
||||
// UART is idle — a host-CPU-saving hack that models no hardware and paces a
|
||||
// tight-polling loader (one that releases TX between bytes, as one-wire does)
|
||||
// in real time, distorting protocol timing. Clear it so the loader runs at
|
||||
// true cycle speed.
|
||||
uint32_t uflags = 0;
|
||||
avr_ioctl(avr, AVR_IOCTL_UART_GET_FLAGS('0'), &uflags);
|
||||
uflags &= ~AVR_UART_FLAG_POLL_SLEEP;
|
||||
avr_ioctl(avr, AVR_IOCTL_UART_SET_FLAGS('0'), &uflags);
|
||||
|
||||
uart_pty_init(avr, &uart_pty);
|
||||
uart_pty_connect(&uart_pty, '0');
|
||||
printf("TSB_PTY %s\n", uart_pty.pty.slavename);
|
||||
|
||||
Reference in New Issue
Block a user