console.rs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. use spec::binary::{Physical, SbiRet};
  2. /// Debug Console extension.
  3. ///
  4. /// The debug console extension defines a generic mechanism for debugging
  5. /// and boot-time early prints from supervisor-mode software.
  6. ///
  7. /// Kernel developers should switch to driver-based console implementation
  8. /// instead of using this extension to prevent possible race conditions between
  9. /// the firmware and the kernel when drivers are ready.
  10. ///
  11. /// If the underlying physical console has extra bits for error checking
  12. /// (or correction), then these extra bits should be handled by the SBI
  13. /// implementation.
  14. ///
  15. /// *NOTE:* It is recommended that bytes sent/received using the debug
  16. /// console extension follow UTF-8 character encoding.
  17. pub trait Console {
  18. /// Write bytes to the debug console from input memory.
  19. ///
  20. /// # Parameters
  21. ///
  22. /// The `bytes` parameter specifies the input memory, including its length
  23. /// and memory physical base address (both lower and upper bits).
  24. ///
  25. /// # Non-blocking function
  26. ///
  27. /// This is a non-blocking SBI call, and it may do partial or no write operations
  28. /// if the debug console is not able to accept more bytes.
  29. ///
  30. /// # Return value
  31. ///
  32. /// The number of bytes written is returned in `SbiRet.value` and the
  33. /// possible return error codes returned in `SbiRet.error` are shown in
  34. /// the table below:
  35. ///
  36. /// | Return code | Description
  37. /// |:--------------------------|:----------------------------------------------
  38. /// | `SbiRet::success()` | Bytes written successfully.
  39. /// | `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.
  40. /// | `SbiRet::failed()` | Failed to write due to I/O errors.
  41. fn write(&self, bytes: Physical<&[u8]>) -> SbiRet;
  42. /// Read bytes from the debug console into an output memory.
  43. ///
  44. /// # Parameters
  45. ///
  46. /// The `bytes` parameter specifies the output memory, including the maximum
  47. /// bytes which can be written, and its memory physical base address
  48. /// (both lower and upper bits).
  49. ///
  50. /// # Non-blocking function
  51. ///
  52. /// This is a non-blocking SBI call, and it will not write anything
  53. /// into the output memory if there are no bytes to be read in the
  54. /// debug console.
  55. ///
  56. /// # Return value
  57. ///
  58. /// The number of bytes read is returned in `SbiRet.value` and the
  59. /// possible return error codes returned in `SbiRet.error` are shown in
  60. /// the table below:
  61. ///
  62. /// | Return code | Description
  63. /// |:--------------------------|:----------------------------------------------
  64. /// | `SbiRet::success()` | Bytes read successfully.
  65. /// | `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.
  66. /// | `SbiRet::failed()` | Failed to read due to I/O errors.
  67. fn read(&self, bytes: Physical<&mut [u8]>) -> SbiRet;
  68. /// Write a single byte to the debug console.
  69. ///
  70. /// # Blocking function
  71. ///
  72. /// This is a blocking SBI call, and it will only return after writing
  73. /// the specified byte to the debug console.
  74. /// It will also return with `SbiRet::failed()` if there are I/O errors.
  75. ///
  76. /// # Return value
  77. ///
  78. /// The `SbiRet.value` is set to zero, and the possible return error
  79. /// codes returned in `SbiRet.error` are shown in the table below:
  80. ///
  81. /// | Return code | Description
  82. /// |:--------------------------|:----------------------------------------------
  83. /// | `SbiRet::success()` | Byte written successfully.
  84. /// | `SbiRet::failed()` | Failed to write the byte due to I/O errors.
  85. fn write_byte(&self, byte: u8) -> SbiRet;
  86. /// Function internal to macros. Do not use.
  87. #[doc(hidden)]
  88. #[inline]
  89. fn _rustsbi_probe(&self) -> usize {
  90. sbi_spec::base::UNAVAILABLE_EXTENSION.wrapping_add(1)
  91. }
  92. }
  93. impl<T: Console> Console for &T {
  94. #[inline]
  95. fn write(&self, bytes: Physical<&[u8]>) -> SbiRet {
  96. T::write(self, bytes)
  97. }
  98. #[inline]
  99. fn read(&self, bytes: Physical<&mut [u8]>) -> SbiRet {
  100. T::read(self, bytes)
  101. }
  102. #[inline]
  103. fn write_byte(&self, byte: u8) -> SbiRet {
  104. T::write_byte(self, byte)
  105. }
  106. }
  107. impl<T: Console> Console for Option<T> {
  108. #[inline]
  109. fn write(&self, bytes: Physical<&[u8]>) -> SbiRet {
  110. self.as_ref()
  111. .map(|inner| T::write(inner, bytes))
  112. .unwrap_or(SbiRet::not_supported())
  113. }
  114. #[inline]
  115. fn read(&self, bytes: Physical<&mut [u8]>) -> SbiRet {
  116. self.as_ref()
  117. .map(|inner| T::read(inner, bytes))
  118. .unwrap_or(SbiRet::not_supported())
  119. }
  120. #[inline]
  121. fn write_byte(&self, byte: u8) -> SbiRet {
  122. self.as_ref()
  123. .map(|inner| T::write_byte(inner, byte))
  124. .unwrap_or(SbiRet::not_supported())
  125. }
  126. #[inline]
  127. fn _rustsbi_probe(&self) -> usize {
  128. match self {
  129. Some(_) => sbi_spec::base::UNAVAILABLE_EXTENSION.wrapping_add(1),
  130. None => sbi_spec::base::UNAVAILABLE_EXTENSION,
  131. }
  132. }
  133. }