refactor: 📦 Prepare for future Mailbox mod
Mailbox mod is disabled for now. Needs to become a driver.
This commit is contained in:
parent
c40797ed19
commit
84b596b2db
|
@ -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()?,
|
||||
})
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
//
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue