Skip to content

Commit cde681f

Browse files
Eric Migicovskyclaude
andcommitted
qemu-wasm: persistence, autoboot, console input, sensors, gabbro
- The 32 MB SPI flash is saved to OPFS when dirty (15 s cadence, strided FNV change detection) and restored on the next boot, so installed apps and settings survive reloads; PebbleKit JS sources are persisted alongside in localStorage. Factory reset wipes both. - The page boots automatically on load (?noauto restores the button); switching boards reloads onto the chosen machine. - gabbro (getafix_dvt) is a first-class board option with v4.35.0 firmware in the site bundle. - dbgserial (UART2) gains a browser input ring behind a wasm-console device property, giving the console panel a working prompt. - Sensors & phone panel injects battery, compass, tap and time-format QemuProtocol frames over the existing serial bridge. Verified in Chromium: autoboot, install -> OPFS save -> reload -> restore (no re-fetch, JS registry intact), and the dbgserial prompt answering 'help'. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pi1WErefJ7c6kXodajm25M Signed-off-by: Eric Migicovsky <eric@repebble.com>
1 parent 13c978a commit cde681f

9 files changed

Lines changed: 556 additions & 22 deletions

File tree

tools/qemu-wasm/jit/overlay/hw/arm/pebble_generic.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ static void pbl_generic_init(MachineState *machine)
154154
if (i != 1) {
155155
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
156156
}
157+
if (i == 2) {
158+
/* dbgserial: enable browser console input on wasm builds */
159+
qdev_prop_set_bit(dev, "wasm-console", true);
160+
}
157161
sysbus_realize_and_unref(sbd, &error_fatal);
158162
sysbus_mmio_map(sbd, 0, uart_base[i]);
159163
sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(armv7m, uart_irq[i]));

tools/qemu-wasm/jit/overlay/hw/misc/pebble_simple_uart.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,18 @@
1717

1818
#include "qemu/osdep.h"
1919
#include "qemu/log.h"
20+
#include "qemu/timer.h"
2021
#include "hw/core/irq.h"
2122
#include "hw/core/sysbus.h"
23+
#include "hw/core/qdev-properties.h"
2224
#include "hw/core/qdev-properties-system.h"
2325
#include "hw/arm/pebble_simple_uart.h"
2426
#include "chardev/char-fe.h"
2527

28+
#ifdef EMSCRIPTEN
29+
#include <emscripten/emscripten.h>
30+
#endif
31+
2632
#define TYPE_PEBBLE_SIMPLE_UART "pebble-simple-uart"
2733
OBJECT_DECLARE_SIMPLE_TYPE(PblSimpleUart, PEBBLE_SIMPLE_UART)
2834

@@ -68,8 +74,33 @@ struct PblSimpleUart {
6874
/* Optional write interceptor (for pebble_control) */
6975
PblUartWriteHandler write_handler;
7076
void *write_handler_opaque;
77+
78+
/* Browser console input (UART2 on the wasm build) */
79+
bool wasm_console;
80+
#ifdef EMSCRIPTEN
81+
QEMUTimer *wasm_poll_timer;
82+
#endif
7183
};
7284

85+
#ifdef EMSCRIPTEN
86+
/* Ring for browser -> guest console bytes. The page appends at head
87+
* (Atomics); an 8 ms virtual-clock poll feeds the RX FIFO. Enabled on
88+
* the UART the machine marks wasm-console (the dbgserial prompt). */
89+
#define WASM_CON_RING 4096
90+
static uint8_t s_wasm_con_buf[WASM_CON_RING];
91+
static struct {
92+
uint32_t buf, size;
93+
uint32_t head, tail;
94+
} s_wasm_con_ctrl;
95+
96+
EMSCRIPTEN_KEEPALIVE void *pebble_wasm_console_ctrl(void)
97+
{
98+
s_wasm_con_ctrl.buf = (uint32_t)(uintptr_t)s_wasm_con_buf;
99+
s_wasm_con_ctrl.size = WASM_CON_RING;
100+
return &s_wasm_con_ctrl;
101+
}
102+
#endif
103+
73104
static void pbl_uart_update_irq(PblSimpleUart *s)
74105
{
75106
bool level = false;
@@ -235,13 +266,46 @@ static void pbl_uart_receive(void *opaque, const uint8_t *buf, int size)
235266
}
236267
}
237268

269+
#ifdef EMSCRIPTEN
270+
static void pbl_uart_wasm_poll(void *opaque)
271+
{
272+
PblSimpleUart *s = opaque;
273+
uint32_t head = qatomic_load_acquire(&s_wasm_con_ctrl.head);
274+
uint32_t tail = s_wasm_con_ctrl.tail;
275+
276+
while (tail != head) {
277+
int space = pbl_uart_can_receive(s);
278+
if (space <= 0) {
279+
break;
280+
}
281+
uint32_t off = tail % WASM_CON_RING;
282+
uint32_t n = MIN(head - tail, WASM_CON_RING - off);
283+
n = MIN(n, (uint32_t)space);
284+
pbl_uart_receive(s, &s_wasm_con_buf[off], n);
285+
tail += n;
286+
qatomic_store_release(&s_wasm_con_ctrl.tail, tail);
287+
}
288+
timer_mod(s->wasm_poll_timer,
289+
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 8);
290+
}
291+
#endif
292+
238293
static void pbl_uart_realize(DeviceState *dev, Error **errp)
239294
{
240295
PblSimpleUart *s = PEBBLE_SIMPLE_UART(dev);
241296

242297
qemu_chr_fe_set_handlers(&s->chr, pbl_uart_can_receive,
243298
pbl_uart_receive, NULL, NULL,
244299
s, NULL, true);
300+
301+
#ifdef EMSCRIPTEN
302+
if (s->wasm_console) {
303+
s->wasm_poll_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
304+
pbl_uart_wasm_poll, s);
305+
timer_mod(s->wasm_poll_timer,
306+
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 8);
307+
}
308+
#endif
245309
}
246310

247311
static void pbl_uart_init(Object *obj)
@@ -269,6 +333,7 @@ static void pbl_uart_reset(DeviceState *dev)
269333

270334
static const Property pbl_uart_properties[] = {
271335
DEFINE_PROP_CHR("chardev", PblSimpleUart, chr),
336+
DEFINE_PROP_BOOL("wasm-console", PblSimpleUart, wasm_console, false),
272337
};
273338

274339
static void pbl_uart_class_init(ObjectClass *klass, const void *data)

tools/qemu-wasm/site-dist/apply.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ gunzip -c "$src/qemu-system-arm.js.gz" > "$dst/qemu-system-arm.js"
1717
gunzip -c "$src/qemu-system-arm.wasm.gz" > "$dst/qemu-system-arm.wasm"
1818
gunzip -c "$src/qemu_micro_flash.bin.gz" > "$dst/firmware/emery/qemu_micro_flash.bin"
1919
gunzip -c "$src/qemu_spi_flash.bin.gz" > "$dst/firmware/emery/qemu_spi_flash.bin"
20+
mkdir -p "$dst/firmware/gabbro"
21+
gunzip -c "$src/qemu_micro_flash_gabbro.bin.gz" > "$dst/firmware/gabbro/qemu_micro_flash.bin"
22+
gunzip -c "$src/qemu_spi_flash_gabbro.bin.gz" > "$dst/firmware/gabbro/qemu_spi_flash.bin"
2023

2124
echo "Applied. New site files:"
2225
(cd "$dst" && ls -la index.html qemu-system-arm.js qemu-system-arm.wasm \

0 commit comments

Comments
 (0)