diff --git a/headers/private/kernel/arch/arm/bcm2708.h b/headers/private/kernel/arch/arm/bcm2708.h index 78c21d8853..0b9bbbb78f 100644 --- a/headers/private/kernel/arch/arm/bcm2708.h +++ b/headers/private/kernel/arch/arm/bcm2708.h @@ -40,6 +40,18 @@ #define BCM2708_SDRAM_BASE 0x00000000 #define BCM2708_PERIPHERAL_BASE 0x20000000 +// Added to physical addresses to select the different cache behaviours +#define BCM2708_VIDEO_CORE_L1_L2_CACHED (0 << 30) +#define BCM2708_VIDEO_CORE_L2_COHERENT (1 << 30) +#define BCM2708_VIDEO_CORE_L2_CACHED (2 << 30) +#define BCM2708_VIDEO_CORE_UNCACHED (3 << 30) + +// The highest two bits are used to select aliases to the physical memory +// with different cache semantic. Clearing them converts the address to +// physical memory as seen by ARM. +#define BCM2708_BUS_TO_PHYSICAL(x) (x & ~BCM2708_VIDEO_CORE_UNCACHED) + + #define ST_BASE 0x3000 // System Timer, sec 12.0, page 172 #define DMA_BASE 0x7000 @@ -122,4 +134,19 @@ #define UART_SYSC 20 +/* Mailbox */ +#define ARM_CTRL_0_MAILBOX_BASE (ARM_CTRL_0_SBM_BASE + 0x80) + +#define ARM_MAILBOX_READ 0x00 +#define ARM_MAILBOX_STATUS 0x18 +#define ARM_MAILBOX_WRITE 0x20 + +#define ARM_MAILBOX_FULL (1 << 31) +#define ARM_MAILBOX_EMPTY (1 << 30) + +#define ARM_MAILBOX_DATA_MASK 0xfffffff0 +#define ARM_MAILBOX_CHANNEL_MASK 0x0000000f + +#define ARM_MAILBOX_CHANNEL_FRAMEBUFFER 1 + #endif /* __PLATFORM_BCM2708_H */ diff --git a/src/system/boot/platform/raspberrypi_arm/Jamfile b/src/system/boot/platform/raspberrypi_arm/Jamfile index e1cb1f77ca..09761f2095 100644 --- a/src/system/boot/platform/raspberrypi_arm/Jamfile +++ b/src/system/boot/platform/raspberrypi_arm/Jamfile @@ -29,6 +29,7 @@ BootMergeObject boot_platform_raspberrypi_arm.o : devices.cpp gpio.cpp keyboard.cpp + mailbox.cpp menu.cpp serial.cpp video.cpp diff --git a/src/system/boot/platform/raspberrypi_arm/mailbox.cpp b/src/system/boot/platform/raspberrypi_arm/mailbox.cpp new file mode 100644 index 0000000000..c2ab2b6cba --- /dev/null +++ b/src/system/boot/platform/raspberrypi_arm/mailbox.cpp @@ -0,0 +1,74 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Michael Lotz, mmlr@mlotz.ch + */ + +#include + +#include "bcm2708.h" + + +extern addr_t gPeripheralBase; + + +static inline addr_t +convert_mailbox_reg(addr_t reg) +{ + return gPeripheralBase + ARM_CTRL_0_MAILBOX_BASE + reg; +} + + +static inline void +write_mailbox_reg(addr_t reg, uint32 value) +{ + arch_cpu_memory_write_barrier(); + *(volatile uint32*)convert_mailbox_reg(reg) = value; +} + + +static inline uint32 +read_mailbox_reg(addr_t reg) +{ + uint32 result = *(volatile uint32*)convert_mailbox_reg(reg); + arch_cpu_memory_read_barrier(); + return result; +} + + +status_t +write_mailbox(uint8 channel, uint32 value) +{ + // We have to wait for the mailbox to drain if it is marked full. + while ((read_mailbox_reg(ARM_MAILBOX_STATUS) & ARM_MAILBOX_FULL) != 0) + ; + + value &= ARM_MAILBOX_DATA_MASK; + write_mailbox_reg(ARM_MAILBOX_WRITE, value | channel); + return B_OK; +} + + +status_t +read_mailbox(uint8 channel, uint32& value) +{ + while (true) { + // Wait for something to arrive in the mailbox. + if ((read_mailbox_reg(ARM_MAILBOX_STATUS) & ARM_MAILBOX_EMPTY) != 0) + continue; + + value = read_mailbox_reg(ARM_MAILBOX_READ); + if ((value & ARM_MAILBOX_CHANNEL_MASK) != channel) { + // Not for us, retry. + continue; + } + + break; + } + + value &= ARM_MAILBOX_DATA_MASK; + return B_OK; +} + diff --git a/src/system/boot/platform/raspberrypi_arm/mailbox.h b/src/system/boot/platform/raspberrypi_arm/mailbox.h new file mode 100644 index 0000000000..b5bbeeb983 --- /dev/null +++ b/src/system/boot/platform/raspberrypi_arm/mailbox.h @@ -0,0 +1,12 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _PLATFORM_MAILBOX_H_ +#define _PLATFORM_MAILBOX_H_ + +status_t write_mailbox(uint8 channel, uint32 value); +status_t read_mailbox(uint8 channel, uint32& value); + +#endif // _PLATFORM_MAILBOX_H_ +