1 // Copyright 2022, The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //! Minimal driver for an 8250 UART. This only implements enough to work with the emulated 8250 16 //! provided by crosvm, and won't work with real hardware. 17 18 use core::fmt::{self, Write}; 19 20 /// Minimal driver for an 8250 UART. This only implements enough to work with the emulated 8250 21 /// provided by crosvm, and won't work with real hardware. 22 pub struct Uart { 23 base_address: *mut u8, 24 } 25 26 impl Uart { 27 /// Constructs a new instance of the UART driver for a device at the given base address. 28 /// 29 /// # Safety 30 /// 31 /// The given base address must point to the 8 MMIO control registers of an appropriate UART 32 /// device, which must be mapped into the address space of the process as device memory and not 33 /// have any other aliases. new(base_address: usize) -> Self34 pub unsafe fn new(base_address: usize) -> Self { 35 Self { base_address: base_address as *mut u8 } 36 } 37 38 /// Writes a single byte to the UART. write_byte(&self, byte: u8)39 pub fn write_byte(&self, byte: u8) { 40 // SAFETY: We know that the base address points to the control registers of a UART device 41 // which is appropriately mapped. 42 unsafe { 43 core::arch::asm!( 44 "strb {value:w}, [{ptr}]", 45 value = in(reg) byte, 46 ptr = in(reg) self.base_address, 47 ); 48 } 49 } 50 } 51 52 impl Write for Uart { write_str(&mut self, s: &str) -> fmt::Result53 fn write_str(&mut self, s: &str) -> fmt::Result { 54 for c in s.as_bytes() { 55 self.write_byte(*c); 56 } 57 Ok(()) 58 } 59 } 60 61 // SAFETY: `Uart` just contains a pointer to device memory, which can be accessed from any context. 62 unsafe impl Send for Uart {} 63