Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Disk Peripheral #54

Open
20 tasks
rrbutani opened this issue Feb 23, 2020 · 1 comment
Open
20 tasks

The Disk Peripheral #54

rrbutani opened this issue Feb 23, 2020 · 1 comment
Labels
✨ feature New things!

Comments

@rrbutani
Copy link
Member

rrbutani commented Feb 23, 2020

what

An Peripheral that allows for persistent storage. Should have a straight-forward interface like the below:

pub trait Disk: Default {
    fn read(&self, addr: Addr) -> Word;
    fn write(&mut self, addr: Addr, data: Word) -> Result<(), ()>;
}

Updated with the below, it might look something like this:

pub enum DiskError {
    DiskIsNotReal,
    AddressOutOfRange { capacity: Addr, given: Addr },
}

pub trait Disk: Default {
    fn is_real(&self) -> bool { true }
    fn capacity(&self) -> Addr;

    fn read(&self, addr: Addr) -> Result<Word, DiskError>;
    fn write(&mut self, addr: Addr, data: Word) -> Result<(), DiskError>;
}

steps

  • answer the questions below
  • add the peripheral trait to lc3-traits
    • add and write the trait
    • write a stub
    • update PeripheralSet; use an Option if this is an optional peripheral?
      • need to figure out how the PeripheralSet dispatch works if the trait is optional
      • actually, probably just use the stub (which indicates that it's not real somehow) by default (using a default type on the type alias) without altering how the dispatch works
  • add a shim to lc3-shims
    • file backed? tbd
    • update PeripheralsShim
    • add tests for it
  • update Control
    • update how capabilities are reported to use whatever hook we add in Disk to find out if there's a real Disk
    • update the trait to add functions to read/write from disk
    • update the messages to match
  • update the board support crate
    • either reuse the flash API for this or make a new trait
    • create the necessary macros and machinery to generate an peripheral impl given a thing that implements the trait above
  • tm4c support
    • add an impl of the trait from board-support that uses EEPROM
  • application support
    • update the shims type with the disk shim
  • tui/gui
    • add a widget for this
    • need to figure out how we'd offer persistent storage (i.e. files) on all the platforms (i.e. Local Storage for wasm?)

where

We'll probably have branches for each stage of the above.

(TBD) branch: feat-disk-peripheral

open questions

  • Should we fix on a capacity or allow different impls to have different capacities?
    • If we say fixed:
      • How big?
      • What types should we use to represent the address/data elements?
    • If we say variable:
      • We should add a function to the trait indicating capacity that's exposed via LC-3 userspace.
        • Not a constant because: 1) object safety, 2) we don't have const generics and might want to allow dynamically set capacities on a Disk shim, 3) we'll need to expose this to LC-3 userspace anyways
      • Associated types for addr/data or fixed?
        • I think we should do fixed w/just Addr for address (i.e. the biggest possible) for simplicity.
        • Having the data type be anything other than a Word seems like a bad idea.
  • Should the read and write functions both be fallible?
    • i.e. what happens when users try to read/write to addresses that don't exist?
      • This probably arises whether we choose fixed or variable capacity. Unless we do something like 256 Words; u8 for the address (i.e. make an out of bounds case unrepresentable). Really though, this is just moving the error state to the TRAPs or to the mem_mapped.rs interface.
  • What does the LC-3 interface look like?
    • I think a mem mapped disk_addr and disk_data register would work?
      • The addr register is stateful and determines what reads/writes to the data register actually get routed to.
    • For TRAPs, something like:
      • DISK_READ(addr: R0) -> (data: R0, failure: n) (i.e n bit set on failure)
      • DISK_WRITE(addr: R0, data: R1) -> (failure: n)
      • DISK_CAPACITY() -> (size: R0)
      • DISK_PRESENT() -> (failure: n, success: z)
      • maybe always use R1 for data for consistency or something; details very much tbd
  • With this and the potential Display peripheral (doesn't yet exist yet) we're starting to have peripherals that we can't realistically require all simulator/devices to have.
    • What infrastructure do we need to build/make for 'optional' peripherals?
      • I think adding a function to the trait to indicate whether it's real or not. The stub will indicate that it's not real.
      • This raises a new question: what happens if you try to read/write to a disk that says it's not real?
    • How do we signal whether a peripheral is there or not to LC-3 user space?
    • To the controlling device?
      • The Capabilities type that's exposed as part of DeviceInfo is currently our answer to this.
@rrbutani rrbutani added ✨ feature New things! ➕ improvement Chores and fixes: the small things. labels Feb 23, 2020
@gipsond gipsond removed the ✨ feature New things! label May 21, 2020
@rrbutani rrbutani mentioned this issue Aug 31, 2022
1 task
@rrbutani rrbutani added ✨ feature New things! and removed ➕ improvement Chores and fixes: the small things. labels Aug 31, 2022
@rrbutani
Copy link
Member Author

(the example code in this issue needs updating of the changes we've made to the peripheral traits in general: no Default bound, should use the optional peripheral infra developed for #178; should also mention using the embedded-storage traits)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ feature New things!
Projects
None yet
Development

No branches or pull requests

2 participants