123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- use spec::binary::{Physical, SbiRet};
- /// Debug Console extension.
- ///
- /// The debug console extension defines a generic mechanism for debugging
- /// and boot-time early prints from supervisor-mode software.
- ///
- /// Kernel developers should switch to driver-based console implementation
- /// instead of using this extension to prevent possible race conditions between
- /// the firmware and the kernel when drivers are ready.
- ///
- /// If the underlying physical console has extra bits for error checking
- /// (or correction), then these extra bits should be handled by the SBI
- /// implementation.
- ///
- /// *NOTE:* It is recommended that bytes sent/received using the debug
- /// console extension follow UTF-8 character encoding.
- pub trait Console {
- /// Write bytes to the debug console from input memory.
- ///
- /// # Parameters
- ///
- /// The `bytes` parameter specifies the input memory, including its length
- /// and memory physical base address (both lower and upper bits).
- ///
- /// # Non-blocking function
- ///
- /// This is a non-blocking SBI call, and it may do partial or no write operations
- /// if the debug console is not able to accept more bytes.
- ///
- /// # Return value
- ///
- /// The number of bytes written is returned in `SbiRet.value` and the
- /// possible return error codes returned in `SbiRet.error` are shown in
- /// the table below:
- ///
- /// | Return code | Description
- /// |:--------------------------|:----------------------------------------------
- /// | `SbiRet::success()` | Bytes written successfully.
- /// | `SbiRet::invalid_param()` | The memory pointed to by `bytes` does not satisfy the [requirements](struct.Physical.html#Requirements) described in shared memory physical address range.
- /// | `SbiRet::failed()` | Failed to write due to I/O errors.
- fn write(&self, bytes: Physical<&[u8]>) -> SbiRet;
- /// Read bytes from the debug console into an output memory.
- ///
- /// # Parameters
- ///
- /// The `bytes` parameter specifies the output memory, including the maximum
- /// bytes which can be written, and its memory physical base address
- /// (both lower and upper bits).
- ///
- /// # Non-blocking function
- ///
- /// This is a non-blocking SBI call, and it will not write anything
- /// into the output memory if there are no bytes to be read in the
- /// debug console.
- ///
- /// # Return value
- ///
- /// The number of bytes read is returned in `SbiRet.value` and the
- /// possible return error codes returned in `SbiRet.error` are shown in
- /// the table below:
- ///
- /// | Return code | Description
- /// |:--------------------------|:----------------------------------------------
- /// | `SbiRet::success()` | Bytes read successfully.
- /// | `SbiRet::invalid_param()` | The memory pointed to by `bytes` does not satisfy the [requirements](struct.Physical.html#Requirements) described in shared memory physical address range.
- /// | `SbiRet::failed()` | Failed to read due to I/O errors.
- fn read(&self, bytes: Physical<&mut [u8]>) -> SbiRet;
- /// Write a single byte to the debug console.
- ///
- /// # Blocking function
- ///
- /// This is a blocking SBI call, and it will only return after writing
- /// the specified byte to the debug console.
- /// It will also return with `SbiRet::failed()` if there are I/O errors.
- ///
- /// # Return value
- ///
- /// The `SbiRet.value` is set to zero, and the possible return error
- /// codes returned in `SbiRet.error` are shown in the table below:
- ///
- /// | Return code | Description
- /// |:--------------------------|:----------------------------------------------
- /// | `SbiRet::success()` | Byte written successfully.
- /// | `SbiRet::failed()` | Failed to write the byte due to I/O errors.
- fn write_byte(&self, byte: u8) -> SbiRet;
- /// Function internal to macros. Do not use.
- #[doc(hidden)]
- #[inline]
- fn _rustsbi_probe(&self) -> usize {
- sbi_spec::base::UNAVAILABLE_EXTENSION.wrapping_add(1)
- }
- }
- impl<T: Console> Console for &T {
- #[inline]
- fn write(&self, bytes: Physical<&[u8]>) -> SbiRet {
- T::write(self, bytes)
- }
- #[inline]
- fn read(&self, bytes: Physical<&mut [u8]>) -> SbiRet {
- T::read(self, bytes)
- }
- #[inline]
- fn write_byte(&self, byte: u8) -> SbiRet {
- T::write_byte(self, byte)
- }
- }
- impl<T: Console> Console for Option<T> {
- #[inline]
- fn write(&self, bytes: Physical<&[u8]>) -> SbiRet {
- self.as_ref()
- .map(|inner| T::write(inner, bytes))
- .unwrap_or(SbiRet::not_supported())
- }
- #[inline]
- fn read(&self, bytes: Physical<&mut [u8]>) -> SbiRet {
- self.as_ref()
- .map(|inner| T::read(inner, bytes))
- .unwrap_or(SbiRet::not_supported())
- }
- #[inline]
- fn write_byte(&self, byte: u8) -> SbiRet {
- self.as_ref()
- .map(|inner| T::write_byte(inner, byte))
- .unwrap_or(SbiRet::not_supported())
- }
- #[inline]
- fn _rustsbi_probe(&self) -> usize {
- match self {
- Some(_) => sbi_spec::base::UNAVAILABLE_EXTENSION.wrapping_add(1),
- None => sbi_spec::base::UNAVAILABLE_EXTENSION,
- }
- }
- }
|