Skip to content

Commit e1693fd

Browse files
committed
Expose read-only storage inventory
1 parent 2298487 commit e1693fd

2 files changed

Lines changed: 166 additions & 2 deletions

File tree

crates/abi/src/mdriver_control.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub const MDRIVER_CONTROL_OPEN_BLOCK_QUEUE: u16 = 11;
1414
pub const MDRIVER_CONTROL_REGISTER_BLOCK_BUFFER: u16 = 12;
1515
pub const MDRIVER_CONTROL_START_BLOCK_QUEUE: u16 = 13;
1616
pub const MDRIVER_CONTROL_STOP_BLOCK_QUEUE: u16 = 14;
17+
pub const MDRIVER_CONTROL_INSPECT_STORAGE: u16 = 15;
1718

1819
pub const MDRIVER_CONTROL_STATUS_OK: u32 = 0;
1920
pub const MDRIVER_CONTROL_STATUS_UNSUPPORTED_VERSION: u32 = 1;
@@ -31,11 +32,17 @@ pub const MDRIVER_CONTROL_CAP_DEVICE_STATUS: u64 = 1 << 1;
3132
pub const MDRIVER_CONTROL_CAP_SESSION: u64 = 1 << 2;
3233
pub const MDRIVER_CONTROL_CAP_PING: u64 = 1 << 3;
3334
pub const MDRIVER_CONTROL_CAP_BLOCK_IO: u64 = 1 << 4;
35+
pub const MDRIVER_CONTROL_CAP_STORAGE_INSPECTION: u64 = 1 << 5;
3436
pub const MDRIVER_CONTROL_CAPABILITIES: u64 = MDRIVER_CONTROL_CAP_INVENTORY
3537
| MDRIVER_CONTROL_CAP_DEVICE_STATUS
3638
| MDRIVER_CONTROL_CAP_SESSION
3739
| MDRIVER_CONTROL_CAP_PING
38-
| MDRIVER_CONTROL_CAP_BLOCK_IO;
40+
| MDRIVER_CONTROL_CAP_BLOCK_IO
41+
| MDRIVER_CONTROL_CAP_STORAGE_INSPECTION;
42+
43+
pub const MDRIVER_STORAGE_QUERY_DISK: u64 = 0;
44+
pub const MDRIVER_STORAGE_QUERY_PARTITION_GUIDS: u64 = 1;
45+
pub const MDRIVER_STORAGE_QUERY_PARTITION_RANGE: u64 = 2;
3946

4047
pub const MDRIVER_DEVICE_KIND_OTHER: u64 = 0;
4148
pub const MDRIVER_DEVICE_KIND_BLOCK: u64 = 1;

src/mochios_domain.rs

Lines changed: 158 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,15 @@ use mnu_abi::mdriver_control::{
3333
MDRIVER_CONTROL_PING, MDRIVER_CONTROL_REGISTER_BLOCK_BUFFER, MDRIVER_CONTROL_START_BLOCK_QUEUE,
3434
MDRIVER_CONTROL_START_SESSION, MDRIVER_CONTROL_STATUS_END, MDRIVER_CONTROL_STATUS_OK,
3535
MDRIVER_CONTROL_STATUS_OUT_OF_RANGE, MDRIVER_CONTROL_STATUS_UNSUPPORTED_OPERATION,
36-
MDRIVER_CONTROL_STOP_BLOCK_QUEUE, MDRIVER_CONTROL_VERSION,
36+
MDRIVER_CONTROL_STOP_BLOCK_QUEUE, MDRIVER_CONTROL_VERSION, MDRIVER_CONTROL_INSPECT_STORAGE,
3737
MDRIVER_DEVICE_FEATURE_BLOCK_ASYNC_QUEUE, MDRIVER_DEVICE_FEATURE_BLOCK_FLUSH,
3838
MDRIVER_DEVICE_FEATURE_BLOCK_READ, MDRIVER_DEVICE_FEATURE_BLOCK_WRITE,
3939
MDRIVER_DEVICE_FEATURE_DMA_ISOLATED, MDRIVER_DEVICE_FEATURE_EPHEMERAL,
4040
MDRIVER_DEVICE_FEATURE_INTERRUPT_ACTIVE, MDRIVER_DEVICE_FEATURE_PARTITIONED,
4141
MDRIVER_DEVICE_FEATURE_PHYSICAL, MDRIVER_DEVICE_FEATURE_READ_ONLY, MDRIVER_DEVICE_KIND_BLOCK,
4242
MDRIVER_DEVICE_KIND_SOUND, MDRIVER_DEVICE_STATE_ONLINE,
43+
MDRIVER_STORAGE_QUERY_DISK, MDRIVER_STORAGE_QUERY_PARTITION_GUIDS,
44+
MDRIVER_STORAGE_QUERY_PARTITION_RANGE,
4345
};
4446
use mnu_abi::shared_ring::{
4547
initialize, pop_response, push_request, SharedRingMessage, SharedRingPage,
@@ -50,6 +52,7 @@ static MDRIVER_EVENT_MESSAGE: &[u8] = b"mDriver control Event Channel verified\n
5052
static MDRIVER_PROTOCOL_MESSAGE: &[u8] = b"mDriver device control protocol ready\n";
5153
static MDRIVER_BLOCK_MESSAGE: &[u8] = b"mDriver block data path ready\n";
5254
static MDRIVER_ASYNC_BLOCK_MESSAGE: &[u8] = b"mDriver asynchronous block queue ready\n";
55+
static MDRIVER_STORAGE_MESSAGE: &[u8] = b"mDriver read-only storage inspection ready\n";
5356
const CONTROL_IRQ_YIELD_LIMIT: usize = 1024;
5457
const CONTROL_REQUEST_ID: u64 = 1;
5558

@@ -374,12 +377,166 @@ fn start_control_protocol(boot_info: &DomainBootInfo) {
374377
initialization_failed(boot_info)
375378
}
376379
if let Some((device_id, features)) = block_device {
380+
if features & MDRIVER_DEVICE_FEATURE_READ_ONLY != 0 {
381+
inspect_read_only_storage(boot_info, ring, &mut request_id, device_id);
382+
}
377383
verify_block_data_path(boot_info, ring, &mut request_id, device_id, features);
378384
verify_async_block_queue(boot_info, ring, &mut request_id, device_id, features);
379385
}
380386
console_write(boot_info, MDRIVER_PROTOCOL_MESSAGE);
381387
}
382388

389+
fn inspect_read_only_storage(
390+
boot_info: &DomainBootInfo,
391+
ring: *mut SharedRingPage,
392+
request_id: &mut u64,
393+
device_id: u32,
394+
) {
395+
let mut report = [0_u8; 4096];
396+
let mut report_len = 0;
397+
append_report(&mut report, &mut report_len, b"DISPLAY\nSTORAGE READ ONLY\n");
398+
let disk = transact(
399+
boot_info,
400+
ring,
401+
request_id,
402+
MdriverControlRequest::new(
403+
MDRIVER_CONTROL_INSPECT_STORAGE,
404+
device_id,
405+
[MDRIVER_STORAGE_QUERY_DISK, 0, 0, 0],
406+
),
407+
);
408+
if disk.status != MDRIVER_CONTROL_STATUS_OK
409+
|| disk.values[2] == 0
410+
|| disk.values[3] < MDRIVER_BLOCK_SECTOR_SIZE
411+
|| !disk.values[3].is_power_of_two()
412+
{
413+
initialization_failed(boot_info)
414+
}
415+
let (line, line_len) = storage_guid_line(b"STORAGE DISK ", 0, disk.values[0], disk.values[1]);
416+
console_write(boot_info, &line[..line_len]);
417+
append_report(&mut report, &mut report_len, &line[..line_len]);
418+
419+
for ordinal in 0..128_u64 {
420+
let guids = transact(
421+
boot_info,
422+
ring,
423+
request_id,
424+
MdriverControlRequest::new(
425+
MDRIVER_CONTROL_INSPECT_STORAGE,
426+
device_id,
427+
[MDRIVER_STORAGE_QUERY_PARTITION_GUIDS, ordinal, 0, 0],
428+
),
429+
);
430+
if guids.status == MDRIVER_CONTROL_STATUS_END {
431+
if ordinal > 9 {
432+
append_report(&mut report, &mut report_len, b"MORE IN SERIAL\n");
433+
}
434+
console_write(boot_info, &report[..report_len]);
435+
console_write(boot_info, MDRIVER_STORAGE_MESSAGE);
436+
return;
437+
}
438+
if guids.status != MDRIVER_CONTROL_STATUS_OK {
439+
initialization_failed(boot_info)
440+
}
441+
let (type_line, type_len) =
442+
storage_guid_line(b"STORAGE TYPE ", ordinal, guids.values[0], guids.values[1]);
443+
console_write(boot_info, &type_line[..type_len]);
444+
if ordinal < 9 {
445+
append_report(&mut report, &mut report_len, &type_line[..type_len]);
446+
}
447+
let (part_line, part_len) =
448+
storage_guid_line(b"STORAGE PART ", ordinal, guids.values[2], guids.values[3]);
449+
console_write(boot_info, &part_line[..part_len]);
450+
if ordinal < 9 {
451+
append_report(&mut report, &mut report_len, &part_line[..part_len]);
452+
}
453+
454+
let range = transact(
455+
boot_info,
456+
ring,
457+
request_id,
458+
MdriverControlRequest::new(
459+
MDRIVER_CONTROL_INSPECT_STORAGE,
460+
device_id,
461+
[MDRIVER_STORAGE_QUERY_PARTITION_RANGE, ordinal, 0, 0],
462+
),
463+
);
464+
if range.status != MDRIVER_CONTROL_STATUS_OK || range.values[1] == 0 {
465+
initialization_failed(boot_info)
466+
}
467+
let range_line = storage_range_line(ordinal, range.values[0], range.values[1]);
468+
console_write(boot_info, &range_line);
469+
if ordinal < 9 {
470+
append_report(&mut report, &mut report_len, &range_line);
471+
}
472+
}
473+
initialization_failed(boot_info)
474+
}
475+
476+
fn storage_guid_line(
477+
label: &[u8; 13],
478+
ordinal: u64,
479+
low: u64,
480+
high: u64,
481+
) -> ([u8; 54], usize) {
482+
let mut line = [b' '; 54];
483+
line[..13].copy_from_slice(label);
484+
let mut guid = [0_u8; 16];
485+
guid[..8].copy_from_slice(&low.to_le_bytes());
486+
guid[8..].copy_from_slice(&high.to_le_bytes());
487+
if label == b"STORAGE DISK " {
488+
write_gpt_guid(&mut line[14..50], &guid);
489+
line[50] = b'\n';
490+
(line, 51)
491+
} else {
492+
write_hex_byte(&mut line[13..15], ordinal as u8);
493+
write_gpt_guid(&mut line[16..52], &guid);
494+
line[52] = b'\n';
495+
(line, 53)
496+
}
497+
}
498+
499+
fn storage_range_line(ordinal: u64, first: u64, count: u64) -> [u8; 52] {
500+
let mut line = *b"STORAGE P00 RANGE 0000000000000000 0000000000000000\n";
501+
write_hex_byte(&mut line[9..11], ordinal as u8);
502+
write_hex_u64(&mut line[18..34], first);
503+
write_hex_u64(&mut line[35..51], count);
504+
line
505+
}
506+
507+
fn append_report(buffer: &mut [u8], length: &mut usize, value: &[u8]) {
508+
if value.len() <= buffer.len().saturating_sub(*length) {
509+
buffer[*length..*length + value.len()].copy_from_slice(value);
510+
*length += value.len();
511+
}
512+
}
513+
514+
fn write_gpt_guid(output: &mut [u8], guid: &[u8; 16]) {
515+
const ORDER: [usize; 16] = [3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15];
516+
let mut position = 0;
517+
for (index, byte) in ORDER.iter().copied().enumerate() {
518+
if matches!(index, 4 | 6 | 8 | 10) {
519+
output[position] = b'-';
520+
position += 1;
521+
}
522+
write_hex_byte(&mut output[position..position + 2], guid[byte]);
523+
position += 2;
524+
}
525+
}
526+
527+
fn write_hex_byte(output: &mut [u8], value: u8) {
528+
const HEX: &[u8; 16] = b"0123456789ABCDEF";
529+
output[0] = HEX[(value >> 4) as usize];
530+
output[1] = HEX[(value & 0xf) as usize];
531+
}
532+
533+
fn write_hex_u64(output: &mut [u8], value: u64) {
534+
const HEX: &[u8; 16] = b"0123456789ABCDEF";
535+
for (index, digit) in output.iter_mut().enumerate() {
536+
*digit = HEX[((value >> ((15 - index) * 4)) & 0xf) as usize];
537+
}
538+
}
539+
383540
fn verify_block_data_path(
384541
boot_info: &DomainBootInfo,
385542
ring: *mut SharedRingPage,

0 commit comments

Comments
 (0)