Add FrameBuffer configuration

This commit is contained in:
Berkus Decker 2020-10-21 16:27:55 +03:00
parent 082a1c29e7
commit e19177da52
3 changed files with 113 additions and 2 deletions

View File

@ -0,0 +1,107 @@
use {
super::{
mailbox::{channel, read, write, MailboxOps, RegisterBlock, Result},
BcmHost,
},
core::ops::Deref,
};
/// FrameBuffer channel supported structure - use with mailbox::channel::FrameBuffer
/// Must have the same alignment as the mailbox buffers.
#[repr(C)]
#[repr(align(16))]
pub struct FrameBuffer {
pub width: u32,
pub height: u32,
pub vwidth: u32,
pub vheight: u32,
pub pitch: u32,
pub depth: u32,
pub x_offset: u32,
pub y_offset: u32,
pub pointer: u32,
pub size: u32,
// Must be after HW-dictated fields to not break structure alignment.
base_addr: usize,
}
// @todo rewrite in terms of using the Mailbox
/// Deref to RegisterBlock
///
/// Allows writing
/// ```
/// self.STATUS.read()
/// ```
/// instead of something along the lines of
/// ```
/// unsafe { (*FrameBuffer::ptr()).STATUS.read() }
/// ```
impl Deref for FrameBuffer {
type Target = RegisterBlock; // mailbox RegisterBlock reused here
fn deref(&self) -> &Self::Target {
unsafe { &*self.ptr() }
}
}
impl core::fmt::Debug for FrameBuffer {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(
f,
"\n\n\n#### FrameBuffer({}x{}, {}x{}, d{}, --{}--, +{}x{}, {}@{:x})\n\n\n",
self.width,
self.height,
self.vwidth,
self.vheight,
self.depth,
self.pitch,
self.x_offset,
self.y_offset,
self.size,
self.pointer,
)
}
}
impl FrameBuffer {
pub fn new(reg_base: usize, width: u32, height: u32, depth: u32) -> FrameBuffer {
FrameBuffer {
width,
height,
vwidth: width,
vheight: height,
pitch: 0,
depth,
x_offset: 0,
y_offset: 0,
pointer: 0, // could be 4096 for the alignment?
size: 0,
base_addr: reg_base,
}
}
}
impl MailboxOps for FrameBuffer {
/// Returns a pointer to the register block
fn ptr(&self) -> *const RegisterBlock {
self.base_addr as *const _
}
/// https://github.com/raspberrypi/firmware/wiki/Accessing-mailboxes says:
/// **With the exception of the property tags mailbox channel,**
/// when passing memory addresses as the data part of a mailbox message,
/// the addresses should be **bus addresses as seen from the VC.**
fn write(&self, _channel: u32) -> Result<()> {
write(
self,
BcmHost::phys2bus(&self as *const _ as usize) as *const _,
channel::FrameBuffer,
)
}
fn read(&self, _channel: u32) -> Result<()> {
read(self, 0, channel::FrameBuffer)
}
}

View File

@ -125,6 +125,9 @@ pub mod channel {
// Count = 7,
pub const PropertyTagsArmToVc: u32 = 8;
pub const PropertyTagsVcToArm: u32 = 9;
/// Channel number is ignored. Use for implementations of MailboxOps that use hardcoded
/// channel number.
pub const Ignored: u32 = !0;
}
// Single code indicating request
@ -236,7 +239,7 @@ pub mod alpha_mode {
pub const IGNORED: u32 = 2;
}
fn write(regs: &RegisterBlock, buf: *const u32, channel: u32) -> Result<()> {
pub fn write(regs: &RegisterBlock, buf: *const u32, channel: u32) -> Result<()> {
let mut count: u32 = 0;
let buf_ptr: u32 = buf as u32;
@ -265,7 +268,7 @@ fn write(regs: &RegisterBlock, buf: *const u32, channel: u32) -> Result<()> {
Ok(())
}
fn read(regs: &RegisterBlock, expected: u32, channel: u32) -> Result<()> {
pub fn read(regs: &RegisterBlock, expected: u32, channel: u32) -> Result<()> {
loop {
let mut count: u32 = 0;
while regs.STATUS.is_set(STATUS::EMPTY) {

View File

@ -5,6 +5,7 @@
#![allow(dead_code)]
pub mod fb;
pub mod mailbox;
/// See BCM2835-ARM-Peripherals.pdf