diff --git a/crates/adapter-riscv/src/boot/loader.rs b/crates/adapter-riscv/src/boot/loader.rs index 249d324..56c4781 100644 --- a/crates/adapter-riscv/src/boot/loader.rs +++ b/crates/adapter-riscv/src/boot/loader.rs @@ -38,13 +38,16 @@ pub fn load_init(uart: &Uart) -> LoadedProcess { } /// Storage's budget, carved from init's. -const STORAGE: Limits = Limits { - // A 16-page buffer per client (16), its image and cache. - pages: 512, - endpoints: 2, - notifications: 2, - // A buffer per client and the disk's DMA. - regions: 20, +const STORAGE: Limits = { + use types::storage::{BUFFER_PAGES, MAX_CLIENTS}; + Limits { + // A buffer per client, and its image, heap and cache. + pages: MAX_CLIENTS * BUFFER_PAGES + 256, + endpoints: 2, + notifications: 2, + // A buffer per client, and the disk's DMA. + regions: MAX_CLIENTS + 4, + } }; /// Storage, which init needs to read anything else, its budget carved diff --git a/crates/domain/src/memory/mod.rs b/crates/domain/src/memory/mod.rs index eb8fa69..b6cf3ff 100644 --- a/crates/domain/src/memory/mod.rs +++ b/crates/domain/src/memory/mod.rs @@ -18,7 +18,8 @@ mod quota_tests; #[path = "tests.rs"] mod tests; -pub const MAX_REGIONS: usize = if cfg!(kani) { 1 } else { 64 }; +/// System-wide: the display and storage hold a dozen or more each. +pub const MAX_REGIONS: usize = if cfg!(kani) { 1 } else { 256 }; pub const MAX_REGION_MAPPINGS: usize = if cfg!(kani) { 2 } else { 4 }; /// Where a region's frames come from. diff --git a/crates/init/src/manifest.rs b/crates/init/src/manifest.rs index 8deca9c..72b4f0a 100644 --- a/crates/init/src/manifest.rs +++ b/crates/init/src/manifest.rs @@ -102,6 +102,11 @@ const fn server(name: &'static str, file: &'static [u8], limits: Limits) -> Prog } } +const DISPLAY_PAGES: usize = (types::display::window::MAX_WINDOWS + 1) * types::display::window::BUFFER_PAGES + 256; +/// A region per window, the screen's, the GPU's queues, and themes' +/// reading buffer. +const DISPLAY_REGIONS: usize = types::display::window::MAX_WINDOWS + 5; + /// Started on every boot. The log server comes first so the rest can print. pub const SERVERS: &[Program] = &[ Program { console: true, ..server("log", b"bin/log", SMALL) }, @@ -118,9 +123,9 @@ pub const SERVERS: &[Program] = &[ // Its windows' state (input queues among it) is ~10 KiB, and the // server is built on the stack. stack_pages: 14, - // The framebuffer is ~1000 pages at 1280x800, and so is each of - // the (at most 8) windows' pixel buffers, which it owns. - ..server("display", b"bin/display", Limits { pages: 9300, regions: 13, ..SMALL }) + // The screen's pixel buffer and each window's, which it owns, and + // its own memory. + ..server("display", b"bin/display", Limits { pages: DISPLAY_PAGES, regions: DISPLAY_REGIONS, ..SMALL }) }, // Text on the display, lines from the keyboard (it takes input focus). // Its clients wait on lines and Ctrl+C. It draws its own text now, diff --git a/crates/servers/display-server/src/host.rs b/crates/servers/display-server/src/host.rs index db5c278..9e7b1b6 100644 --- a/crates/servers/display-server/src/host.rs +++ b/crates/servers/display-server/src/host.rs @@ -16,8 +16,11 @@ use crate::windows::MAX_WINDOWS; /// a 1280x800 window; high, clear of the GPU's mappings and of the heap, /// which grows from the bottom. const BUFFERS_VA: usize = 0x1000_0000; -const BUFFER_SPAN: usize = 0x0040_0000; const PAGE: usize = 4096; +const BUFFER_SPAN: usize = types::display::window::BUFFER_PAGES * PAGE; +// Every window's buffer fits between here and the themes' reading buffer +// (0x1800_0000), below the heap's end. +const _: () = assert!(BUFFERS_VA + MAX_WINDOWS * BUFFER_SPAN <= 0x1800_0000 && 0x1800_0000 < types::layout::HEAP_END); pub struct KernelHost { /// The display's own endpoint, which window capabilities are minted diff --git a/crates/servers/display-server/src/windows.rs b/crates/servers/display-server/src/windows.rs index 0e52ec2..b07ab3a 100644 --- a/crates/servers/display-server/src/windows.rs +++ b/crates/servers/display-server/src/windows.rs @@ -7,7 +7,7 @@ use types::display::window::{BADGE, NAME_BYTES}; -pub const MAX_WINDOWS: usize = 8; +pub use types::display::window::MAX_WINDOWS; /// Events received and not yet polled by the window in front. const QUEUED: usize = 32; diff --git a/crates/servers/storage-server/src/lib.rs b/crates/servers/storage-server/src/lib.rs index a5fe92a..7e3dca4 100644 --- a/crates/servers/storage-server/src/lib.rs +++ b/crates/servers/storage-server/src/lib.rs @@ -24,6 +24,8 @@ use types::permission::{Permission, PermissionSet}; /// Client buffers sit high in storage's window, clear of its heap. const BUFFERS_VA: VirtualAddress = VirtualAddress::from_raw(0x0100_0000); +// Every client's buffer fits below the disk driver's mappings (0x01D0_0000). +const _: () = assert!(0x0100_0000 + types::storage::MAX_CLIENTS * protocol::BUFFER_SIZE <= 0x01D0_0000); const EP: CapSlot = CapSlot::const_new(0); diff --git a/crates/servers/storage-server/src/server.rs b/crates/servers/storage-server/src/server.rs index e37dd81..fee2569 100644 --- a/crates/servers/storage-server/src/server.rs +++ b/crates/servers/storage-server/src/server.rs @@ -9,8 +9,7 @@ use crate::scope::Scope; mod session; -/// Connections at once: every program reading files, apps among them. -const MAX_CLIENTS: usize = 16; +use types::storage::MAX_CLIENTS; /// Handles at or past this are never valid (the file systems hand out /// fewer), so ownership fits a small table. const MAX_HANDLES: usize = 16; diff --git a/crates/types/src/display.rs b/crates/types/src/display.rs index 9bd57ab..f5b70fc 100644 --- a/crates/types/src/display.rs +++ b/crates/types/src/display.rs @@ -139,6 +139,12 @@ pub mod window { pub const BADGE: usize = 1 << 61; pub const OK: usize = 0; pub const PIXEL_BYTES: usize = 4; + /// Windows open at once. Each has a pixel buffer of the display's (as + /// does the screen), so this is what the display's budget is made of. + pub const MAX_WINDOWS: usize = 8; + /// The most a pixel buffer (a window's, the screen's) takes: room for + /// 1280x800. + pub const BUFFER_PAGES: usize = 1024; /// Longest name the OS bar shows. pub use crate::name::BYTES as NAME_BYTES; diff --git a/crates/types/src/storage.rs b/crates/types/src/storage.rs index e5ba1b1..87bfbd0 100644 --- a/crates/types/src/storage.rs +++ b/crates/types/src/storage.rs @@ -4,6 +4,10 @@ /// Size of each client's buffer. pub const BUFFER_PAGES: usize = 16; +/// Connections at once (every program reading files, apps among them): +/// each has a buffer of storage's, so this is what storage's budget is +/// made of. +pub const MAX_CLIENTS: usize = 16; pub const BUFFER_SIZE: usize = BUFFER_PAGES * 4096; /// Longest path the server will look at. pub const MAX_PATH: usize = 255;