391 lines
15 KiB
Markdown
391 lines
15 KiB
Markdown
# Firmware - POS and PrometeuHub
|
|
|
|
Domain: firmware and system orchestration
|
|
Function: normative
|
|
|
|
This chapter defines the firmware layer of the PROMETEU machine.
|
|
|
|
It covers:
|
|
|
|
- machine authority above the VM;
|
|
- POS responsibilities;
|
|
- Hub responsibilities;
|
|
- firmware states and cartridge launch flow.
|
|
|
|
## 1 Firmware Scope
|
|
|
|
The PROMETEU firmware is composed of two cooperating layers:
|
|
|
|
- **PrometeuOS (POS)**: the machine authority responsible for boot, VM/runtime orchestration, peripherals, crash handling, and system-level policy;
|
|
- **PrometeuHub**: the launcher/UI layer that runs over POS and uses the system window model.
|
|
|
|
The VM does not own the machine lifecycle. Firmware does.
|
|
|
|
## 2 Terms
|
|
|
|
- **Host**: the real platform that drives the core loop and presents output.
|
|
- **POS**: system firmware/core authority.
|
|
- **PrometeuHub**: launcher and system UI running over POS.
|
|
- **PVM**: the VM subsystem that executes cartridge bytecode.
|
|
- **Cartridge**: the executable package loaded by firmware.
|
|
- **AppMode**: cartridge mode, currently `Game` or `System`.
|
|
- **Logical frame**: execution unit completed when the app reaches `FRAME_SYNC`.
|
|
- **Host tick**: the host-driven outer update tick.
|
|
- **Process**: technical execution owned by POS lifecycle.
|
|
- **Task**: navigable presence associated with an app flow.
|
|
- **Window**: visual presence for a shell/system task when that task is
|
|
represented by the system window model.
|
|
- **WindowOwner**: ownership marker for a system window. The v1 owners are
|
|
`Hub`, `Task(TaskId)`, and `Overlay`.
|
|
- **Shell task window**: a `WindowManager` window whose owner is
|
|
`WindowOwner::Task(TaskId)`.
|
|
- **Games root**: a host-provided local directory used by Hub/Home to discover
|
|
Game directory cartridges.
|
|
- **Library entry**: an internal catalog record retained by Hub/SystemOS for a
|
|
discovered cartridge.
|
|
- **Game switch target**: a SystemOS-owned launch target derived from a library
|
|
entry. It carries the cartridge path plus resolved identity such as `app_id`,
|
|
`title`, and `app_version`.
|
|
- **Foreground visual owner**: the single machine owner whose visual output may
|
|
be presented at a given time.
|
|
- **Paused**: a Game-visible lifecycle event/state. The Game may observe it and
|
|
prepare for foreground loss.
|
|
- **Suspended**: an OS-owned scheduler/runtime state. A suspended Game remains
|
|
resident but does not receive normal gameplay ticks, normal Game input, or
|
|
frame pacing.
|
|
- **VM session**: the POS-owned mutable execution context for one VM-backed
|
|
process. It contains the VM instance and per-session runtime state.
|
|
- **Hub resident Game kill control**: a Hub/Home affordance that terminates the
|
|
current resident Game instead of resuming it.
|
|
|
|
## 3 POS Responsibilities
|
|
|
|
POS is responsible for:
|
|
|
|
- deterministic reset into known machine state;
|
|
- VM session creation, initialization, activation, and teardown for cartridge
|
|
execution;
|
|
- input latching and logical-frame budgeting;
|
|
- peripheral reset/orchestration;
|
|
- fault capture and crash-flow transition;
|
|
- return to Hub after app exit or crash.
|
|
|
|
At the VM boundary, POS must preserve:
|
|
|
|
- logical-frame semantics;
|
|
- `FRAME_SYNC` as the canonical frame boundary;
|
|
- deterministic transition from host tick to VM slice execution.
|
|
|
|
Firmware must not treat a single global VM object as the canonical execution
|
|
owner for all cartridges. The firmware state machine orchestrates macro-state;
|
|
POS/session services own VM-backed process context.
|
|
|
|
## 4 PrometeuHub Responsibilities
|
|
|
|
PrometeuHub is responsible for:
|
|
|
|
- presenting available apps;
|
|
- reading cartridge metadata needed for launch decisions;
|
|
- deciding launch behavior based on `AppMode`;
|
|
- managing the system window surface for system-mode apps.
|
|
- presenting the host-provided local games library when `--games-root <dir>` is
|
|
configured;
|
|
- emitting system-owned launch actions for selected Home entries.
|
|
- presenting a resident Game kill control while Hub/Home owns foreground and a
|
|
Game is resident/suspended.
|
|
|
|
The Hub does not execute bytecode directly. It always delegates execution setup to POS.
|
|
|
|
For v1, the local games library is Game-only. Hub/Home must not expose Shell or
|
|
System cartridges from the games root. The internal library entry must retain
|
|
the loaded manifest data, `title`, `app_id`, `app_version`, the cartridge path,
|
|
and discovery metadata such as a timestamp or equivalent discovery marker.
|
|
|
|
The Home UI may display only `title`, `app_id`, and `app_version`. Path and
|
|
operational metadata may remain internal.
|
|
|
|
## 5 App Modes
|
|
|
|
### Game
|
|
|
|
Game-mode cartridges:
|
|
|
|
- transition firmware into the game-running state;
|
|
- run as the active app flow;
|
|
- present through the main frame path.
|
|
- run as fullscreen firmware sessions;
|
|
- are not `WindowManager` windows.
|
|
|
|
### System
|
|
|
|
System-mode cartridges:
|
|
|
|
- are initialized by POS;
|
|
- are integrated into the Hub/window environment;
|
|
- do not replace the firmware state with the game-running path.
|
|
- are represented as shell task windows when they expose a visual shell
|
|
presence.
|
|
|
|
## 6 Task-Owned Shell Windows
|
|
|
|
The shell window contract separates execution, navigation, and visual
|
|
presence:
|
|
|
|
```text
|
|
Process = technical execution
|
|
Task = navigable presence
|
|
Window = visual presence of the task
|
|
```
|
|
|
|
For shell/system apps managed by the window model, the visible shell presence
|
|
must be a `WindowManager` window owned by `WindowOwner::Task(TaskId)`.
|
|
|
|
`Hub` windows are not shell task windows. `Overlay` windows are not shell task
|
|
windows in this v1 contract. Overlay/modal policy, minimization, app switching,
|
|
dock behavior, background services, and complex multi-window semantics are
|
|
future contracts and are not defined here.
|
|
|
|
Game cartridges must not be represented as `WindowManager` windows. They remain
|
|
fullscreen sessions driven by `GameRunningStep`.
|
|
|
|
For v1, `ShellRunningStep` continues a shell task only while both conditions are
|
|
true:
|
|
|
|
```text
|
|
TaskState::Foreground
|
|
+
|
|
focused window owner == WindowOwner::Task(task_id)
|
|
```
|
|
|
|
The runtime query for the focused-window ownership predicate is:
|
|
|
|
```text
|
|
os.windows().focused_window_belongs_to_task(task_id)
|
|
```
|
|
|
|
If a foreground shell task loses its eligible focused window,
|
|
`ShellRunningStep` must close the task through `SystemOS` lifecycle before
|
|
returning to Hub:
|
|
|
|
```text
|
|
Shell task loses its eligible focused window
|
|
-> os.lifecycle().close_task(task_id)
|
|
-> TaskState::Closed
|
|
-> ProcessState::Stopped
|
|
-> FirmwareState::HubHome
|
|
```
|
|
|
|
## 7 Foreground Stack and Game Pause
|
|
|
|
The v1 foreground contract is single-owner:
|
|
|
|
- exactly one foreground visual owner exists at a time;
|
|
- at most one Game may be resident;
|
|
- at most one Shell app may be foreground;
|
|
- Hub/Home is the root Shell owner and back-stack controller.
|
|
|
|
The minimal supported navigation cycle is:
|
|
|
|
```text
|
|
Game foreground
|
|
-> Home request
|
|
-> Game pause notification
|
|
-> Game suspended by SystemOS after a bounded budget
|
|
-> Hub/Home foreground
|
|
-> optional Shell foreground
|
|
-> Shell close returns to Hub/Home
|
|
-> same Game resume/foreground-restore notification
|
|
-> Game foreground after a valid current-epoch render submission
|
|
```
|
|
|
|
`Paused` is cooperative and visible to the Game. `Suspended` is imposed by
|
|
SystemOS. The Game may react to pause/resume, but it must not control whether
|
|
the OS suspends or resumes its VM.
|
|
|
|
When Home is requested during Game execution, SystemOS must notify the Game and
|
|
grant a short bounded pause budget. After the budget, SystemOS may suspend the
|
|
VM even if the Game did not cooperate. While suspended, the Game must not
|
|
receive normal gameplay ticks, normal Game input, or frame pacing.
|
|
|
|
When returning to the same Game, SystemOS must reactivate the VM and send a
|
|
resume or foreground-restore notification before visual foreground is restored.
|
|
The Game may remain internally paused while it synchronizes. Hub/Shell remains
|
|
visible until the resumed Game publishes a valid render submission for the
|
|
current ownership epoch.
|
|
|
|
Input pending for the Game must be cleared or barriered across pause/resume
|
|
boundaries. Game audio pauses with the Game VM in v1. Independent background
|
|
audio, real background execution, multiple resident Games, multiple foreground
|
|
Shells, and direct Game-to-Game switching are outside this contract.
|
|
|
|
The resident Game VM session remains allocated while Hub or Shell is foreground.
|
|
It preserves Game VM state but is not execution-eligible except for the bounded
|
|
pause handoff and later foreground resume. A VM-backed Shell has a separate VM
|
|
session. A native Shell has no VM session.
|
|
|
|
When Hub/Home is foreground and a Game cartridge remains resident/suspended,
|
|
PrometeuHub MUST render a red control in the bottom-right of the Hub viewport.
|
|
The control MUST display only the resident Game title. It MUST NOT be rendered
|
|
for no resident Game, Shell tasks, System tasks, or native Shell tasks.
|
|
|
|
Clicking the Hub resident Game kill control is a system-owned immediate
|
|
termination request. Firmware MUST keep the user in Hub/Home, MUST NOT ask for
|
|
confirmation in v1, and MUST NOT resume the killed Game on subsequent Home
|
|
actions. The control MUST disappear on the next Hub frame after the resident
|
|
Game is no longer present.
|
|
|
|
## 8 Cartridge Load Flow
|
|
|
|
Current high-level flow:
|
|
|
|
1. POS receives a cartridge to load;
|
|
2. asset manager is initialized from the cartridge asset table, preload list, and packed asset bytes;
|
|
3. POS creates or selects the VM session for the cartridge;
|
|
4. POS initializes the session-owned VM/runtime for the cartridge;
|
|
5. launch behavior branches by `AppMode`:
|
|
- `Game` -> transition to the game-running firmware state;
|
|
- `System` -> create/focus a Hub window and return to the Hub state.
|
|
|
|
If VM initialization fails, firmware transitions to the crash path.
|
|
|
|
For v1, POS must enforce at most one resident Game session. Selecting the same
|
|
resident Game from Home resumes that session. Selecting a different Game from
|
|
Home is a SystemOS-owned Game switch and MUST be destructive replacement:
|
|
|
|
```text
|
|
Game A resident
|
|
-> Hub/Home selected Game B with different app_id
|
|
-> SystemOS terminates Game A resident task/session
|
|
-> SystemOS removes Game A from resumable state
|
|
-> firmware loads Game B through LoadCartridge
|
|
-> Game B receives a fresh VM session
|
|
```
|
|
|
|
SystemOS MUST NOT create a second resident Game session. SystemOS MUST NOT
|
|
reuse the old Game VM session, transient VM handles, pending lifecycle delivery
|
|
state, render ownership, debug pause state, or crash/debug runtime state for the
|
|
new Game. Durable app data remains governed by the relevant storage specs and
|
|
may still be keyed by `app_id`.
|
|
|
|
SystemOS MAY emit a cooperative non-blocking terminate/save lifecycle event
|
|
before closing the old Game when such an event exists. Replacement MUST NOT
|
|
block on that event in v1. VM-backed Shell loading creates a distinct Shell
|
|
session and must not overwrite resident Game VM state.
|
|
|
|
Manual Hub resident Game kill and destructive different-Game replacement MUST
|
|
share the canonical resident-Game termination path. That path MUST:
|
|
|
|
- close the resident Game task;
|
|
- mark its process stopped;
|
|
- remove its VM session;
|
|
- clear resident Game state and pending Game lifecycle delivery for that task;
|
|
- keep or return foreground ownership to Hub/Home;
|
|
- transition render ownership to Shell/Hub (`AppMode::Shell`, `app_id = 0`);
|
|
- clear the Game lifecycle audio pause state;
|
|
- unbind the Game2D frame composer scene;
|
|
- shut down cartridge-scoped asset manager state, including slot identity and
|
|
physical glyph/scene/sound banks.
|
|
|
|
After this operation, the killed Game MUST NOT be resumable. Launching that
|
|
same Game again from Home is a fresh cartridge load and a fresh VM session.
|
|
Manual Hub kill MUST emit an INFO Hub log with the message shape:
|
|
|
|
```text
|
|
Resident game killed from Hub: <title>
|
|
```
|
|
|
|
POS selects the cartridge and its execution context, but the cartridge's initial callable is not chosen by firmware metadata. Execution starts from the cartridge boot protocol defined in [`13-cartridge.md`](13-cartridge.md), currently `func_id = 0`.
|
|
|
|
When Home launches a discovered Game entry, the request is a system-owned action
|
|
from PrometeuHub to POS/firmware. Firmware must load the selected cartridge
|
|
through the normal cartridge loader and transition to `LoadCartridge` on
|
|
success. This path must not use a guest syscall and must not reintroduce
|
|
userland `run_cart`.
|
|
|
|
If the selected cartridge cannot be loaded, firmware must leave or return the
|
|
machine in the Hub/Home flow and record the failure through diagnostics or
|
|
logging. A polished Home error surface is not required by v1.
|
|
|
|
If a destructive Game switch has already begun and the new Game fails to load or
|
|
initialize, firmware MUST return to Hub/Home, MUST discard any partial new Game
|
|
task/session/window/render/input/audio state, and MUST NOT restore the previous
|
|
Game. Direct boot and debug boot failures remain governed by the boot profile
|
|
that requested them and may still transition to the crash path.
|
|
|
|
Switch validation MUST include two distinct Game cartridges. The current
|
|
repository evidence uses `Stress Console` and `Dummy Boy`; those cartridges are
|
|
test evidence, not required runtime features.
|
|
|
|
## 9 Firmware States
|
|
|
|
The current firmware state model includes:
|
|
|
|
- `Reset`
|
|
- `SplashScreen`
|
|
- `LaunchHub`
|
|
- `HubHome`
|
|
- `LoadCartridge`
|
|
- `GameRunning`
|
|
- `ShellRunning`
|
|
- `AppCrashes`
|
|
|
|
These states express machine orchestration above the VM. They are not guest-visible bytecode states.
|
|
|
|
## 10 Execution Contract
|
|
|
|
For game-mode execution, firmware/runtime coordination preserves:
|
|
|
|
- input latched per logical frame;
|
|
- execution in host-driven slices until `FRAME_SYNC`;
|
|
- present only when a logical frame completes;
|
|
- no frame present when budget ends before `FRAME_SYNC`.
|
|
|
|
This keeps the machine model deterministic and observable.
|
|
|
|
## 11 Crash Handling
|
|
|
|
Firmware owns terminal fault presentation.
|
|
|
|
When a terminal app fault occurs:
|
|
|
|
- POS captures the crash report;
|
|
- firmware leaves normal app execution flow;
|
|
- the machine transitions to `AppCrashes`.
|
|
|
|
Crash handling is outside the guest VM execution model.
|
|
|
|
## 12 Desktop Smoke Validation
|
|
|
|
The foreground contract can be smoke-tested on the desktop host with:
|
|
|
|
```text
|
|
cargo run --release -p prometeu-host-desktop-winit -- --run test-cartridges/stress-console
|
|
cargo run --release -p prometeu-host-desktop-winit -- --games-root test-cartridges
|
|
```
|
|
|
|
Expected behavior:
|
|
|
|
- direct `--run` still boots the selected Game without using a guest cartridge
|
|
switching API;
|
|
- `--games-root` starts in Home and launches Games through the Home library;
|
|
- while a Game is running, `Esc` opens Home/SystemOS without entering the guest
|
|
pad input surface;
|
|
- the Game is paused, then suspended after the bounded SystemOS budget;
|
|
- Home remains foreground while the Game is resident;
|
|
- launching and closing a Shell app returns to Home without losing the resident
|
|
Game;
|
|
- a VM-backed Shell advances its own VM session and does not tick the suspended
|
|
resident Game session;
|
|
- returning to the same Game resumes it through the foreground lifecycle and
|
|
waits for current-epoch Game rendering before visual Game presentation.
|
|
- clicking the red bottom-right resident Game kill control terminates the
|
|
resident Game, keeps Home foreground, clears runtime/cartridge residue, and
|
|
removes the resume path.
|
|
|
|
## 13 Relationship to Other Specs
|
|
|
|
- [`02-vm-instruction-set.md`](02-vm-instruction-set.md) defines the VM subsystem run by firmware.
|
|
- [`09-events-and-concurrency.md`](09-events-and-concurrency.md) defines the frame-boundary model used by firmware.
|
|
- [`13-cartridge.md`](13-cartridge.md) defines cartridge structure and metadata consumed by firmware.
|
|
- [`14-boot-profiles.md`](14-boot-profiles.md) defines startup target selection.
|