Skip to content

Commit c00b18f

Browse files
O(1) LRU eviction block device cache; move flanterm to its own directory; tidy up some generated documentation
1 parent 09f3749 commit c00b18f

24 files changed

Lines changed: 616 additions & 41 deletions

File tree

include/block_cache.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* @file block_cache.h
3+
* @brief Per-device write-through block cache.
4+
*
5+
* This cache sits above block device drivers. It caches fixed-size sectors,
6+
* evicting the oldest (by last access) when full. Reads and writes are
7+
* write-through and counted as accesses. One cache instance is created
8+
* per storage device.
9+
*/
10+
#pragma once
11+
#include <kernel.h>
12+
13+
/* Forward declarations */
14+
typedef struct block_cache block_cache_t;
15+
16+
/**
17+
* @brief Create a new cache for a storage device.
18+
*
19+
* @param dev Device to attach cache to.
20+
* @return Pointer to cache instance, or NULL on error.
21+
*/
22+
block_cache_t *block_cache_create(storage_device_t *dev);
23+
24+
/**
25+
* @brief Destroy a cache and free all associated resources.
26+
*
27+
* @param pcache Pointer to cache pointer; set to NULL on return.
28+
*/
29+
void block_cache_destroy(block_cache_t **pcache);
30+
31+
/**
32+
* @brief Read bytes from a cached device.
33+
*
34+
* Granularity is per sector; the cache works in multiples of the device’s
35+
* block size. Reads hitting the cache are served immediately; misses are
36+
* read from the device and then cached.
37+
*
38+
* @param c Cache instance.
39+
* @param lba Starting sector number.
40+
* @param bytes Number of bytes to read.
41+
* @param out Destination buffer.
42+
* @return 1 on success, 0 on failure (fs_set_error() is set).
43+
*/
44+
int block_cache_read(block_cache_t *c, uint64_t lba, uint32_t bytes, unsigned char *out);
45+
46+
/**
47+
* @brief Write bytes through to a cached device.
48+
*
49+
* Writes are always passed to the device. The cache is updated (write-allocate)
50+
* so subsequent reads will hit.
51+
*
52+
* @param c Cache instance.
53+
* @param lba Starting sector number.
54+
* @param bytes Number of bytes to write.
55+
* @param src Source buffer.
56+
* @return 1 on success, 0 on failure (fs_set_error() is set).
57+
*/
58+
int block_cache_write(block_cache_t *c, uint64_t lba, uint32_t bytes, const unsigned char *src);
59+
60+
/**
61+
* @brief Invalidate all entries in a cache.
62+
*
63+
* Useful when a device is reset or forcibly changed.
64+
*
65+
* @param c Cache instance.
66+
*/
67+
void block_cache_invalidate(block_cache_t *c);
68+

include/filesystem.h

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,15 @@ typedef enum fs_error_t {
8282
FS_ERR_LFN_TOO_LONG,
8383
FS_ERR_IS_EXFAT,
8484
FS_ERR_BAD_CLUSTER,
85+
FS_ERR_INTERNAL,
86+
FS_ERR_OUT_OF_BOUNDS,
8587
} fs_error_t;
8688

8789
/**
8890
* @brief Retrieve a human-readable string for the last filesystem error code.
8991
*
9092
* This function maps an fs_error_t code to its corresponding descriptive
91-
* string. It does not reset or clear the error code the last error value
93+
* string. It does not reset or clear the error code - the last error value
9294
* is retained until a new filesystem error is set via fs_set_error().
9395
*
9496
* @note The validity of the returned error string depends on the result of the
@@ -246,6 +248,8 @@ typedef struct {
246248
bool is_optical;
247249
} storage_device_ui_t;
248250

251+
struct block_cache;
252+
249253
/**
250254
* @brief Represents a block storage device e.g. a hard disk, DVD-ROM drive, etc.
251255
*
@@ -301,8 +305,17 @@ typedef struct storage_device_t {
301305
*/
302306
void* opaque2;
303307

308+
/**
309+
* @brief User interface strings, model name, capacity, type
310+
* as human-readable text.
311+
*/
304312
storage_device_ui_t ui;
305313

314+
/**
315+
* @brief Block cache for the device
316+
*/
317+
struct block_cache* cache;
318+
306319
/**
307320
* @brief Pointer to next storage device, or NULL
308321
*/
@@ -668,4 +681,34 @@ uint32_t fs_get_error(void);
668681
*/
669682
bool install_gpt_esp_rfs_whole_image(const char *devname, const char *esp_image_vfs_path);
670683

671-
void installer();
684+
/**
685+
* @brief Installation stub, installer/main.c
686+
*/
687+
void installer();
688+
689+
/**
690+
* @brief Enable a block-level cache for a storage device.
691+
*
692+
* This attaches a new cache instance to the device if one is not already
693+
* present. The cache is only created when the device has a valid sector size
694+
* and read path. Devices that do not benefit from caching (e.g. ramdisks)
695+
* should not call this function.
696+
*
697+
* @param device Storage device to enable caching for.
698+
* @return true if a cache was successfully created and attached,
699+
* false if caching could not be enabled (invalid arguments,
700+
* already enabled, or allocation failure).
701+
*/
702+
bool storage_enable_cache(storage_device_t *device);
703+
704+
/**
705+
* @brief Disable and destroy the cache attached to a storage device.
706+
*
707+
* If a cache is present on the device it will be destroyed and all resources
708+
* freed. After this call, @p sd->cache will be set to NULL. Calling this on
709+
* a device without a cache is safe and has no effect.
710+
*
711+
* @param sd Storage device to disable caching for.
712+
*/
713+
void storage_disable_cache(storage_device_t *sd);
714+

include/idt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ extern volatile idt_ptr_t idt64;
3838
* for broadcast and never used. Any CPUs with IDs above 254 are ignored.
3939
*
4040
* By sizing arrays to 256, we can index directly by LAPIC ID without needing
41-
* a LAPICOS CPU remapping table. This simplifies per‑CPU structures at the
41+
* a LAPIC->OS CPU remapping table. This simplifies per‑CPU structures at the
4242
* cost of a small amount of extra memory. Future support for >254 LAPIC IDs
4343
* may require remapping or dynamic allocation.
4444
*/

include/interrupt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ typedef struct shared_interrupt_t {
7272
* handlers for multiple PCI devices on the same line can be tracked and
7373
* dispatched safely. This is a requirement of shared interrupt delivery.
7474
*
75-
* @param n Interrupt number 0–31 are reserved ISRs; 32+ are IRQs.
75+
* @param n Interrupt number - 0–31 are reserved ISRs; 32+ are IRQs.
7676
* @param handler Function pointer to the interrupt handler.
7777
* @param device For PCI devices, specify the device node responsible.
7878
* Used to manage IRQ sharing.

include/retrofs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* @file retrofs.h
33
* @author Craig Edwards (craigedwards@brainbox.cc)
4-
* @brief Core structures, constants, and API definitions for RetroFS an
4+
* @brief Core structures, constants, and API definitions for RetroFS - an
55
* ADFS 'L' format–inspired filesystem for Retro Rocket.
66
*
77
* RetroFS is a sector-based filesystem inspired by the Acorn ADFS 'L' format.

include/tinyalloc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* @file tinyalloc.h
3-
* @brief Tinyalloc a small, page-aware heap allocator for Retro Rocket.
3+
* @brief Tinyalloc - a small, page-aware heap allocator for Retro Rocket.
44
*
55
* Provides aligned heap allocation and free operations with
66
* low overhead. Intended for kernel use where predictable

os/system/keymaps/en-US.keymap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,5 +111,5 @@
111111
&52 0 0
112112
&53 . .
113113

114-
# ISO extra key (next to Enter) unused in US layout
114+
# ISO extra key (next to Enter) - unused in US layout
115115
&2B \ |

src/acpi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ uacpi_status uacpi_kernel_pci_device_open(uacpi_pci_address address, uacpi_handl
395395
}
396396

397397
uacpi_status uacpi_kernel_io_map(uacpi_io_addr base, uacpi_size len, uacpi_handle *out_handle) {
398-
// For I/O ports, mapping isn't needed just pass the base through.
398+
// For I/O ports, mapping isn't needed - just pass the base through.
399399
*out_handle = (uacpi_handle) base;
400400
return UACPI_STATUS_OK;
401401
}

src/ahci.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -378,13 +378,13 @@ void probe_port(ahci_hba_mem_t *abar, pci_dev_t dev)
378378
abar->ghc |= (1 << 1); // global IE
379379

380380

381-
storage_device_t* sd = NULL;
382-
sd = kmalloc(sizeof(storage_device_t));
381+
storage_device_t* sd = kmalloc(sizeof(storage_device_t));
383382
if (!sd) {
384383
return;
385384
}
386385
sd->opaque1 = i;
387386
sd->opaque2 = (void*)abar;
387+
sd->cache = NULL;
388388
sd->blockread = storage_device_ahci_block_read;
389389
sd->blockwrite = storage_device_ahci_block_write;
390390
sd->size = dt == AHCI_DEV_SATA ? ahci_read_size(&abar->ports[i], abar) : SIZE_MAX;
@@ -413,6 +413,7 @@ void probe_port(ahci_hba_mem_t *abar, pci_dev_t dev)
413413
}
414414
kprintf("%s storage, Port #%d: %s\n", dt == AHCI_DEV_SATA ? "SATA" : "ATAPI", i, sd->ui.label);
415415
register_storage_device(sd);
416+
storage_enable_cache(sd);
416417
}
417418
}
418419
pi >>= 1;

src/basic/datetime.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,7 @@ char* basic_get_upstr(struct basic_ctx* ctx)
6868
buffer[pos++] = ' ';
6969
}
7070

71-
int n = snprintf(buffer + pos, sizeof(buffer) - pos,
72-
"%lu %s",
73-
parts[i].v, parts[i].label);
74-
if (n < 0) {
75-
n = 0;
76-
}
71+
size_t n = snprintf(buffer + pos, sizeof(buffer) - pos, "%lu %s", parts[i].v, parts[i].label);
7772
if (n >= sizeof(buffer) - pos) {
7873
pos = sizeof(buffer) - 1;
7974
break;
@@ -83,7 +78,7 @@ char* basic_get_upstr(struct basic_ctx* ctx)
8378
}
8479

8580
if (!started) {
86-
(void)snprintf(buffer, sizeof(buffer), "0 sec");
81+
snprintf(buffer, sizeof(buffer), "0 sec");
8782
} else {
8883
buffer[pos] = '\0';
8984
}

0 commit comments

Comments
 (0)