diff --git a/05_uart0/kernel8.img b/05_uart0/kernel8.img index 54459f9a..646ae32d 100755 Binary files a/05_uart0/kernel8.img and b/05_uart0/kernel8.img differ diff --git a/05_uart0/src/main.rs b/05_uart0/src/main.rs index 2e82856f..8b6c1d12 100644 --- a/05_uart0/src/main.rs +++ b/05_uart0/src/main.rs @@ -35,6 +35,8 @@ mod mbox; mod gpio; mod uart; +use core::sync::atomic::{compiler_fence, Ordering}; + fn main() { let mut mbox = mbox::Mbox::new(); let uart = uart::Uart::new(); @@ -54,6 +56,11 @@ fn main() { mbox.buffer[6] = 0; mbox.buffer[7] = mbox::tag::LAST; + // Insert a compiler fence that ensures that all stores to the + // mbox buffer are finished before the GPU is signaled (which is + // done by a store operation as well). + compiler_fence(Ordering::SeqCst); + // send the message to the GPU and receive answer let serial_avail = match mbox.call(mbox::channel::PROP) { Err(_) => false, diff --git a/05_uart0/src/uart.rs b/05_uart0/src/uart.rs index cb9c4df5..a724c8df 100644 --- a/05_uart0/src/uart.rs +++ b/05_uart0/src/uart.rs @@ -26,6 +26,7 @@ use super::MMIO_BASE; use volatile_register::*; use mbox; use gpio; +use core::sync::atomic::{compiler_fence, Ordering}; const UART_BASE: u32 = MMIO_BASE + 0x201000; @@ -77,6 +78,11 @@ impl Uart { mbox.buffer[7] = 0; // skip turbo setting mbox.buffer[8] = mbox::tag::LAST; + // Insert a compiler fence that ensures that all stores to the + // mbox buffer are finished before the GPU is signaled (which + // is done by a store operation as well). + compiler_fence(Ordering::SeqCst); + if let Err(_) = mbox.call(mbox::channel::PROP) { return Err(UartError::MailboxError); // Abort if UART clocks couldn't be set };