default-uart-client: a fallback io client (mostly) for autostart

Adds a kata-io-compatible client that returns data from a slice and
sends writes to the kernel (if possible) or discards them.  This will
be used for running cli scripts and for platforms that do not have a
uart device/driver.

Change-Id: I84facebf16eb9b6692e872e930db027998dd160f
GitOrigin-RevId: 11a3502fb2f8716f9d1a204519b5e93162274590
This commit is contained in:
Sam Leffler 2022-10-14 23:02:10 +00:00
parent 613d5e8783
commit fed472240d
4 changed files with 126 additions and 0 deletions

View File

@ -15,6 +15,7 @@
[workspace]
members = [
"default-uart-client",
"kata-debug-console",
"kata-io",
"kata-line-reader",

View File

@ -0,0 +1,31 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[package]
name = "default-uart-client"
version = "0.1.0"
edition = "2021"
build = "build.rs"
[build-dependencies]
sel4-config = { path = "../../kata-os-common/src/sel4-config" }
[features]
default = []
CONFIG_PRINTING = []
[dependencies]
core2 = { version = "0.3", default-features = false }
kata-io = { path = "../kata-io" }
sel4-sys = { path = "../../kata-os-common/src/sel4-sys", default-features = false }

View File

@ -0,0 +1,33 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::env;
fn main() {
// If SEL4_OUT_DIR is not set we expect the kernel build at a fixed
// location relative to the ROOTDIR env variable.
println!("SEL4_OUT_DIR {:?}", env::var("SEL4_OUT_DIR"));
let sel4_out_dir = env::var("SEL4_OUT_DIR")
.unwrap_or_else(|_| format!("{}/out/kata/kernel", env::var("ROOTDIR").unwrap()));
println!("sel4_out_dir {}", sel4_out_dir);
// Dredge seL4 kernel config for settings we need as features to generate
// correct code: e.g. CONFIG_KERNEL_MCS enables MCS support which changes
// the system call numbering.
let features = sel4_config::get_sel4_features(&sel4_out_dir);
println!("features={:?}", features);
for feature in features {
println!("cargo:rustc-cfg=feature=\"{}\"", feature);
}
}

View File

@ -0,0 +1,61 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#![no_std]
use core2::io::{Cursor, Read};
use kata_io as io;
/// Rx io trait that returns data from a byte string.
pub struct Rx<'a> {
data: Cursor<&'a [u8]>,
}
impl<'a> Rx<'a> {
pub fn new(data: &'a [u8]) -> Self {
Self {
data: Cursor::new(data),
}
}
}
impl<'a> io::Read for Rx<'a> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.data.read(buf).map_err(|_| io::Error)
}
}
/// Tx io trait that uses the kernel if console output is
/// is supported, otherwise discards all writes.
pub struct Tx {}
impl Tx {
pub fn new() -> Self { Self {} }
}
impl Default for Tx {
fn default() -> Self { Self::new() }
}
impl io::Write for Tx {
#[cfg(not(feature = "CONFIG_PRINTING"))]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len() as usize) }
#[cfg(feature = "CONFIG_PRINTING")]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
for &b in buf {
unsafe {
sel4_sys::seL4_DebugPutChar(b);
}
}
Ok(buf.len() as usize)
}
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}