Skip to content

Commit 06ea4b6

Browse files
authored
Merge pull request #15 from Neotron-Compute/add_block_api_back
2 parents af89cc5 + 87eab2d commit 06ea4b6

File tree

3 files changed

+154
-0
lines changed

3 files changed

+154
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ dual licensed as above, without any additional terms or conditions.
4646
* Add `time_ticks_get` and `time_ticks_per_second`
4747
* Add `bus_interrupt_status`
4848
* Remove `delay`
49+
* Add back in the `block_XXX` API for reading/writing Block Devices.
4950

5051
### v0.6.1
5152

src/block_dev.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
//! # Block Devices
2+
//!
3+
//! Block Device related types.
4+
//!
5+
//! Note that all types in this file *must* be `#[repr(C)]` and ABI stable.
6+
7+
// Copyright (C) The Neotron Developers, 2019-2022
8+
//
9+
// This program is free software: you can redistribute it and/or modify
10+
// it under the terms of the GNU General Public License as published by
11+
// the Free Software Foundation, either version 3 of the License, or
12+
// at your option) any later version.
13+
//
14+
// This program is distributed in the hope that it will be useful,
15+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
// GNU General Public License for more details.
18+
//
19+
// You should have received a copy of the GNU General Public License
20+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
21+
22+
// ============================================================================
23+
// Imports
24+
// ============================================================================
25+
26+
// None
27+
28+
// ============================================================================
29+
// Constants
30+
// ============================================================================
31+
32+
// None
33+
34+
// ============================================================================
35+
// Types
36+
// ============================================================================
37+
38+
/// The types of block device we support.
39+
#[repr(C)]
40+
#[derive(Clone, PartialEq, Eq, Debug)]
41+
pub enum DeviceType {
42+
/// An *SD* Card
43+
SecureDigitalCard,
44+
/// A Hard Drive
45+
HardDiskDrive,
46+
/// A floppy disk in a floppy disk drive
47+
FloppyDiskDrive,
48+
/// A compact flash card
49+
CompactFlashCard,
50+
}
51+
52+
/// Information about a block device.
53+
#[repr(C)]
54+
#[derive(Clone, PartialEq, Eq, Debug)]
55+
pub struct DeviceInfo {
56+
/// Some human-readable name for this block device (e.g. `SdCard0` or
57+
/// `CF1`)
58+
pub name: crate::ApiString<'static>,
59+
/// The kind of block device this is.
60+
pub device_type: DeviceType,
61+
/// The size of an addressable block, in bytes.
62+
pub block_size: u32,
63+
/// The total number of addressable blocks.
64+
pub num_blocks: u64,
65+
/// Can this device be ejected?
66+
pub ejectable: bool,
67+
/// Can this device be removed?
68+
pub removable: bool,
69+
/// Does this have media in it right now?
70+
pub media_present: bool,
71+
/// Is this media read-only?
72+
pub read_only: bool,
73+
}
74+
75+
/// Uniquely represents a block on a block device.
76+
#[repr(C)]
77+
#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Debug)]
78+
pub struct BlockIdx(pub u64);
79+
80+
// ============================================================================
81+
// Impls
82+
// ============================================================================
83+
84+
// None
85+
86+
// ============================================================================
87+
// End of File
88+
// ============================================================================

src/lib.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
// ============================================================================
2828

2929
pub mod audio;
30+
pub mod block_dev;
3031
pub mod bus;
3132
pub mod hid;
3233
pub mod i2c;
@@ -514,6 +515,70 @@ pub struct Api {
514515
/// set when the interrupt is pending. There is no masking - ignore the bits
515516
/// you don't care about.
516517
pub bus_interrupt_status: extern "C" fn() -> u32,
518+
519+
// ========================================================================
520+
// Block Device Support
521+
// ========================================================================
522+
/// Get information about the Block Devices in the system.
523+
///
524+
/// Block Devices are also known as *disk drives*. They can be read from
525+
/// (and often written to) but only in units called *blocks* or *sectors*.
526+
///
527+
/// The BIOS should enumerate removable devices first, followed by fixed
528+
/// devices.
529+
///
530+
/// The set of devices is not expected to change at run-time - removal of
531+
/// media is indicated with a boolean field in the
532+
/// `block_dev::DeviceInfo` structure.
533+
pub block_dev_get_info: extern "C" fn(device: u8) -> crate::Option<block_dev::DeviceInfo>,
534+
/// Eject a disk from the drive.
535+
///
536+
/// Will return an error if this device is not removable. Does not return an
537+
/// error if the drive is already empty.
538+
pub block_dev_eject: extern "C" fn(device: u8) -> crate::Result<()>,
539+
/// Write one or more sectors to a block device.
540+
///
541+
/// The function will block until all data is written. The array pointed
542+
/// to by `data` must be `num_blocks * block_size` in length, where
543+
/// `block_size` is given by `block_dev_get_info`.
544+
///
545+
/// There are no requirements on the alignment of `data` but if it is
546+
/// aligned, the BIOS may be able to use a higher-performance code path.
547+
pub block_write: extern "C" fn(
548+
device: u8,
549+
start_block: block_dev::BlockIdx,
550+
num_blocks: u8,
551+
data: ApiByteSlice,
552+
) -> crate::Result<()>,
553+
/// Read one or more sectors to a block device.
554+
///
555+
/// The function will block until all data is read. The array pointed
556+
/// to by `data` must be `num_blocks * block_size` in length, where
557+
/// `block_size` is given by `block_dev_get_info`.
558+
///
559+
/// There are no requirements on the alignment of `data` but if it is
560+
/// aligned, the BIOS may be able to use a higher-performance code path.
561+
pub block_read: extern "C" fn(
562+
device: u8,
563+
start_block: block_dev::BlockIdx,
564+
num_blocks: u8,
565+
data: ApiBuffer,
566+
) -> crate::Result<()>,
567+
/// Verify one or more sectors on a block device (that is read them and
568+
/// check they match the given data).
569+
///
570+
/// The function will block until all data is verified. The array pointed
571+
/// to by `data` must be `num_blocks * block_size` in length, where
572+
/// `block_size` is given by `block_dev_get_info`.
573+
///
574+
/// There are no requirements on the alignment of `data` but if it is
575+
/// aligned, the BIOS may be able to use a higher-performance code path.
576+
pub block_verify: extern "C" fn(
577+
device: u8,
578+
start_block: block_dev::BlockIdx,
579+
num_blocks: u8,
580+
data: ApiByteSlice,
581+
) -> crate::Result<()>,
517582
}
518583

519584
// ============================================================================

0 commit comments

Comments
 (0)