Completes the ADR-0004 log primitive set (log_init + log_str shipped
in the previous commit). Each is a leaf or single-call wrapper:
log_hex — width hex digits, MSB first, lowercase a-f
log_u32 — unsigned decimal, no leading zeros, special-case 0
log_bytes — space-separated 2-digit pairs
log_event — <ts8hex>\t<tag>\r\n with the timestamp placeholder
at 0 until clock_get_freq lands; the wire format is
final, only the sampled value will change
_main now calls log_init then log_event("boot\tready") instead
of writing a hard-coded banner. The qemu output is byte-identical
(00000000\tboot\tready\r\n) so test__main.py is unchanged; the
refactor proves the log chain works end-to-end.
108 tests, all green.
log_init is a single ret today; the ts source lands when clock_get_freq
is wired and log_event needs a real ms-since-boot value. The function
exists now so log_event can call it without forward dependency.
log_str tail-calls uart_tx_bytes — no frame, ra threads through. The
indirection exists so log_event and downstream primitives don't couple
to the underlying TX implementation; a future IRQ-driven uart_tx_bytes
swap stays local to one file.