blob: 427499bc5ad4f2126acb38939906f7eb676db794 [file] [log] [blame]
Andrew Walbranf2594882022-03-15 17:32:53 +00001// 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
Pierre-Clément Tosi4ec3a932024-10-08 18:10:25 +010018use crate::arch::write_volatile_u8;
Andrew Walbranf2594882022-03-15 17:32:53 +000019use core::fmt::{self, Write};
Andrew Walbranf2594882022-03-15 17:32:53 +000020
21/// Minimal driver for an 8250 UART. This only implements enough to work with the emulated 8250
22/// provided by crosvm, and won't work with real hardware.
23pub struct Uart {
24 base_address: *mut u8,
25}
26
27impl Uart {
28 /// Constructs a new instance of the UART driver for a device at the given base address.
29 ///
30 /// # Safety
31 ///
32 /// The given base address must point to the 8 MMIO control registers of an appropriate UART
33 /// device, which must be mapped into the address space of the process as device memory and not
34 /// have any other aliases.
35 pub unsafe fn new(base_address: usize) -> Self {
36 Self { base_address: base_address as *mut u8 }
37 }
38
39 /// Writes a single byte to the UART.
40 pub fn write_byte(&self, byte: u8) {
Andrew Walbranc06e7342023-07-05 14:00:51 +000041 // SAFETY: We know that the base address points to the control registers of a UART device
42 // which is appropriately mapped.
Pierre-Clément Tosi4ec3a932024-10-08 18:10:25 +010043 unsafe { write_volatile_u8(self.base_address, byte) }
Andrew Walbranf2594882022-03-15 17:32:53 +000044 }
45}
46
47impl Write for Uart {
48 fn write_str(&mut self, s: &str) -> fmt::Result {
49 for c in s.as_bytes() {
50 self.write_byte(*c);
51 }
52 Ok(())
53 }
54}
55
Andrew Walbranc06e7342023-07-05 14:00:51 +000056// SAFETY: `Uart` just contains a pointer to device memory, which can be accessed from any context.
Andrew Walbranf2594882022-03-15 17:32:53 +000057unsafe impl Send for Uart {}