refactor: 📦 Prepare for future Mailbox mod

Mailbox mod is disabled for now.
Needs to become a driver.
This commit is contained in:
Berkus Decker 2023-08-11 01:37:30 +03:00 committed by Berkus Decker
parent c40797ed19
commit 84b596b2db
6 changed files with 54 additions and 44 deletions

View File

@ -7,13 +7,19 @@
*/
//! Broadcom mailbox interface between the VideoCore and the ARM Core.
//!
//! Mailbox is controlled by two parts: a MAILBOX driver that drives the MMIO registers and
//! a MailboxCommand, that incorporates a command buffer and concurrency controls.
#![allow(dead_code)]
use crate::synchronization::IRQSafeNullLock;
use {
super::BcmHost,
crate::{platform::device_driver::common::MMIODerefWrapper, println}, //DMA_ALLOCATOR
crate::{
memory::{Address, Virtual},
platform::device_driver::common::MMIODerefWrapper,
println,
}, //DMA_ALLOCATOR
aarch64_cpu::asm::barrier,
core::{
alloc::{AllocError, Allocator, Layout},
@ -30,26 +36,33 @@ use {
},
};
/// Mailbox MMIO registers access.
struct MailboxInner {
registers: Registers,
}
/// Mailbox driver
pub struct Mailbox {
inner: IRQSafeNullLock<MailboxInner>,
}
/// Public interface to the mailbox.
/// The address for the buffer needs to be 16-byte aligned
/// so that the VideoCore can handle it properly.
/// The reason is that lowest 4 bits of the address will contain the channel number.
pub struct Mailbox<const N_SLOTS: usize, Storage = DmaBackedMailboxStorage<N_SLOTS>> {
registers: Registers,
pub struct MailboxCommand<const N_SLOTS: usize, Storage = DmaBackedMailboxStorage<N_SLOTS>> {
pub buffer: Storage,
}
/// Mailbox that is ready to be called.
/// This prevents invalid use of the mailbox until it is fully prepared.
pub struct PreparedMailbox<const N_SLOTS: usize, Storage = DmaBackedMailboxStorage<N_SLOTS>>(
Mailbox<N_SLOTS, Storage>,
/// Mailbox command that is ready to be called.
/// This prevents invalid use of the mailbox command until it is fully prepared.
pub struct PreparedMailboxCommand<const N_SLOTS: usize, Storage = DmaBackedMailboxStorage<N_SLOTS>>(
MailboxCommand<N_SLOTS, Storage>,
);
const MAILBOX_ALIGNMENT: usize = 16;
const MAILBOX_ITEMS_COUNT: usize = 36;
/// We've identity mapped the MMIO register region on kernel start.
const MAILBOX_BASE: usize = BcmHost::get_peripheral_address() + 0xb880;
/// Lowest 4-bits are channel ID.
const CHANNEL_MASK: u32 = 0xf;
@ -109,10 +122,10 @@ pub type Result<T> = CoreResult<T, MailboxError>;
pub trait MailboxOps {
fn write(&self, channel: u32) -> Result<()>;
fn read(&self, channel: u32) -> Result<()>;
fn call(&self, channel: u32) -> Result<()> {
self.write(channel)?;
self.read(channel)
}
fn call(&self, channel: u32) -> Result<()>; //{
// self.write(channel)?;
// self.read(channel)
// }
}
pub trait MailboxStorage {
@ -367,19 +380,13 @@ impl<const N_SLOTS: usize> core::fmt::Debug for PreparedMailbox<N_SLOTS> {
}
}
impl<const N_SLOTS: usize> Default for Mailbox<N_SLOTS> {
fn default() -> Self {
unsafe { Self::new(MAILBOX_BASE) }.expect("Couldn't allocate a default mailbox")
}
}
impl<const N_SLOTS: usize, Storage: MailboxStorage + MailboxStorageRef> Mailbox<N_SLOTS, Storage> {
/// Create a new mailbox locally in an aligned stack space.
/// Create a new mailbox locally in an aligned storage space.
/// # Safety
/// Caller is responsible for picking the correct MMIO register base address.
pub unsafe fn new(base_addr: usize) -> Result<Mailbox<N_SLOTS, Storage>> {
pub unsafe fn new(mmio_base_addr: Address<Virtual>) -> Result<Mailbox<N_SLOTS, Storage>> {
Ok(Mailbox {
registers: Registers::new(base_addr),
registers: Registers::new(mmio_base_addr),
buffer: Storage::new()?,
})
}

View File

@ -7,6 +7,7 @@
pub mod gpio;
#[cfg(feature = "rpi3")]
pub mod interrupt_controller;
// pub mod mailbox;
pub mod mini_uart;
pub mod pl011_uart;
// pub mod power;

View File

@ -15,11 +15,7 @@ use {
devices::serial::SerialOps,
exception,
memory::{Address, Virtual},
platform::{
device_driver::{common::MMIODerefWrapper, gpio, IRQNumber},
mailbox::{self, Mailbox, MailboxOps},
BcmHost,
},
platform::device_driver::{common::MMIODerefWrapper, gpio, IRQNumber},
synchronization::{interface::Mutex, IRQSafeNullLock},
},
core::fmt::{self, Arguments},
@ -386,15 +382,17 @@ impl PL011UartInner {
const CLOCK: u32 = 4_000_000; // 4Mhz
const BAUD_RATE: u32 = 115_200;
let mut mailbox = Mailbox::<9>::default();
let index = mailbox.request();
let index = mailbox.set_clock_rate(index, mailbox::clock::UART, CLOCK);
let mailbox = mailbox.end(index);
if mailbox.call(mailbox::channel::PropertyTagsArmToVc).is_err() {
return Err("PL011 UART setup failed in mailbox operation");
// return Err(PL011UartError::MailboxError); // Abort if UART clocks couldn't be set
};
// // Should have a MailboxCommand with ref to a command buffer, and access to global MAILBOX
// // driver to run those commands atomically..
// let mut mailbox = Mailbox::<9>::default();
// let index = mailbox.request();
// let index = mailbox.set_clock_rate(index, mailbox::clock::UART, CLOCK);
// let mailbox = mailbox.end(index);
//
// if mailbox.call(mailbox::channel::PropertyTagsArmToVc).is_err() {
// return Err("PL011 UART setup failed in mailbox operation");
// // return Err(PL011UartError::MailboxError); // Abort if UART clocks couldn't be set
// };
// From the PL011 Technical Reference Manual:
//

View File

@ -1,4 +1,7 @@
use super::mailbox::{self, LocalMailboxStorage, Mailbox, MailboxError, MailboxOps};
use {
super::mailbox::{self, LocalMailboxStorage, Mailbox, MailboxError, MailboxOps},
crate::memory::{Address, Virtual},
};
/// FrameBuffer channel supported structure - use with mailbox::channel::FrameBuffer
/// Must have the same alignment as the mailbox buffers.
@ -13,10 +16,11 @@ mod index {
pub const DEPTH: usize = 5;
pub const X_OFFSET: usize = 6;
pub const Y_OFFSET: usize = 7;
pub const POINTER: usize = 8; // FIXME: could be 4096 for the alignment restriction.
pub const POINTER: usize = 8; // FIXME: Value could be 4096 for the alignment restriction.
pub const SIZE: usize = 9;
}
// control: MailboxCommand<10, FrameBufferData>
pub struct FrameBuffer {
mailbox: Mailbox<10, FrameBufferData>,
}
@ -42,13 +46,13 @@ impl core::fmt::Debug for FrameBufferData {
impl FrameBuffer {
pub fn new(
base_addr: usize,
mmio_base_addr: Address<Virtual>, // skip this, use MAILBOX driver
width: u32,
height: u32,
depth: u32,
) -> Result<FrameBuffer, MailboxError> {
let mut fb = FrameBuffer {
mailbox: unsafe { Mailbox::<10, FrameBufferData>::new(base_addr)? },
mailbox: unsafe { Mailbox::<10, FrameBufferData>::new(mmio_base_addr)? },
};
fb.mailbox.buffer.storage[index::WIDTH] = width;
fb.mailbox.buffer.storage[index::VIRTUAL_WIDTH] = width;

View File

@ -9,10 +9,9 @@ pub mod device_driver;
pub mod display;
pub mod drivers;
pub mod exception;
pub mod fb;
pub mod mailbox;
// pub mod fb;
pub mod memory;
pub mod vc;
// pub mod vc;
/// See BCM2835-ARM-Peripherals.pdf
/// See <https://www.raspberrypi.org/forums/viewtopic.php?t=186090> for more details.

View File

@ -42,6 +42,7 @@ impl VC {
* (if the base or size has changed) is implicitly freed.
*/
// control: MailboxCommand<10, FrameBufferData>
let mut mbox = Mailbox::<36>::default();
let index = mbox.request();
let index = mbox.set_physical_wh(index, w, h);