2 Commits

31 changed files with 1999 additions and 8 deletions

View File

@@ -0,0 +1,104 @@
#
# Automatically generated file; DO NOT EDIT.
# Fiasco configuration
#
CONFIG_HAS_FPU_OPTION=y
CONFIG_HAS_VIRT_OBJ_SPACE_OPTION=y
CONFIG_HAS_SERIAL_OPTION=y
CONFIG_HAS_JDB_GZIP_OPTION=y
CONFIG_HAS_MP_OPTION=y
CONFIG_HAS_CPU_VIRT=y
#
# Target configuration
#
# CONFIG_IA32 is not set
# CONFIG_AMD64 is not set
CONFIG_ARM=y
# CONFIG_MIPS is not set
# CONFIG_PF_INTEGRATOR is not set
# CONFIG_PF_REALVIEW is not set
# CONFIG_PF_SUNXI is not set
CONFIG_PF_BCM283X=y
# CONFIG_PF_SA1100 is not set
# CONFIG_PF_XSCALE is not set
# CONFIG_PF_ARMADA38X is not set
# CONFIG_PF_KIRKWOOD is not set
# CONFIG_PF_TEGRA is not set
# CONFIG_PF_LAYERSCAPE is not set
# CONFIG_PF_IMX is not set
# CONFIG_PF_ARM_VIRT is not set
# CONFIG_PF_RCAR3 is not set
# CONFIG_PF_EXYNOS is not set
# CONFIG_PF_S3C2410 is not set
# CONFIG_PF_OMAP is not set
# CONFIG_PF_ZYNQ is not set
# CONFIG_PF_ZYNQMP is not set
CONFIG_BSP_NAME="bcm283x"
CONFIG_HAS_64BIT=y
CONFIG_CAN_ARM_CPU_CORTEX_A53=y
CONFIG_ARM_V6PLUS=y
CONFIG_ARM_V7PLUS=y
CONFIG_ARM_V8=y
# CONFIG_PF_BCM283X_RPI1 is not set
# CONFIG_PF_BCM283X_RPI2 is not set
CONFIG_PF_BCM283X_RPI3=y
CONFIG_ABI_VF=y
CONFIG_ARM_CORTEX_A53=y
# CONFIG_CPU_VIRT is not set
CONFIG_FPU=y
# CONFIG_ARM_ALIGNMENT_CHECK is not set
CONFIG_ARM_EM_STD=y
# CONFIG_ARM_SMC_USER is not set
# CONFIG_BIT64_CHOICE is not set
# CONFIG_ARM_LPAE is not set
CONFIG_ARM_CPU_ERRATA=y
#
# Kernel options
#
CONFIG_MP=y
CONFIG_MP_MAX_CPUS=4
CONFIG_CONTEXT_4K=y
CONFIG_FINE_GRAINED_CPUTIME=y
CONFIG_SCHED_FIXED_PRIO=y
CONFIG_VIRT_OBJ_SPACE=y
#
# Debugging
#
CONFIG_INLINE=y
# CONFIG_NDEBUG is not set
CONFIG_NO_FRAME_PTR=y
# CONFIG_STACK_DEPTH is not set
# CONFIG_LIST_ALLOC_SANITY is not set
CONFIG_SERIAL=y
CONFIG_JDB=y
CONFIG_JDB_LOGGING=y
CONFIG_JDB_GZIP=y
# CONFIG_JDB_ACCOUNTING is not set
# CONFIG_WARN_NONE is not set
CONFIG_WARN_WARNING=y
# CONFIG_WARN_ANY is not set
#
# ARM debugging options
#
# CONFIG_VMEM_ALLOC_TEST is not set
# CONFIG_DEBUG_KERNEL_PAGE_FAULTS is not set
#
# Compiling
#
CONFIG_CC="gcc"
CONFIG_CXX="g++"
CONFIG_HOST_CC="gcc"
CONFIG_HOST_CXX="g++"
# CONFIG_MAINTAINER_MODE is not set
CONFIG_LABEL=""
# CONFIG_EXPERIMENTAL is not set
CONFIG_PERF_CNT=y
CONFIG_BIT32=y
CONFIG_WARN_LEVEL=1
CONFIG_XARCH="arm"
CONFIG_ABI="vf"

View File

@@ -0,0 +1,91 @@
#
# Automatically generated file; DO NOT EDIT.
# L4Re Configuration
#
CONFIG_ARCH_ENABLE_STACK_PROTECTOR=y
# CONFIG_BUILD_ARCH_amd64 is not set
CONFIG_BUILD_ARCH_arm=y
# CONFIG_BUILD_ARCH_arm64 is not set
# CONFIG_BUILD_ARCH_mips is not set
# CONFIG_BUILD_ARCH_ppc32 is not set
# CONFIG_BUILD_ARCH_sparc is not set
# CONFIG_BUILD_ARCH_x86 is not set
CONFIG_BUILD_ARCH="arm"
CONFIG_BUILD_ABI_l4f=y
CONFIG_BUILD_ABI="l4f"
# CONFIG_CPU_ARM_ARMV4 is not set
# CONFIG_CPU_ARM_ARMV4T is not set
# CONFIG_CPU_ARM_ARMV5 is not set
# CONFIG_CPU_ARM_ARMV5T is not set
# CONFIG_CPU_ARM_ARMV5TE is not set
# CONFIG_CPU_ARM_ARMV6 is not set
# CONFIG_CPU_ARM_ARMV6T2 is not set
# CONFIG_CPU_ARM_ARMV6ZK is not set
CONFIG_CPU_ARM_ARMV7A=y
CONFIG_CPU="armv7a"
CONFIG_CPU_ARMV6KPLUS=y
CONFIG_CPU_ARMV6PLUS=y
# CONFIG_PLATFORM_TYPE_wand_quad is not set
# CONFIG_PLATFORM_TYPE_bb_x15 is not set
# CONFIG_PLATFORM_TYPE_rpi2 is not set
# CONFIG_PLATFORM_TYPE_sabre_lite is not set
CONFIG_PLATFORM_TYPE_rpi3=y
# CONFIG_PLATFORM_TYPE_imx6 is not set
# CONFIG_PLATFORM_TYPE_zedboard is not set
# CONFIG_PLATFORM_TYPE_imx35 is not set
# CONFIG_PLATFORM_TYPE_rv_pbx is not set
# CONFIG_PLATFORM_TYPE_rv is not set
# CONFIG_PLATFORM_TYPE_kirkwood is not set
# CONFIG_PLATFORM_TYPE_pandaboard is not set
# CONFIG_PLATFORM_TYPE_arm_virt is not set
# CONFIG_PLATFORM_TYPE_tegra2 is not set
# CONFIG_PLATFORM_TYPE_imx7 is not set
# CONFIG_PLATFORM_TYPE_exynos4 is not set
# CONFIG_PLATFORM_TYPE_cubieboard2 is not set
# CONFIG_PLATFORM_TYPE_omap3_am33xx is not set
# CONFIG_PLATFORM_TYPE_ls1012afrdm is not set
# CONFIG_PLATFORM_TYPE_rpi_b is not set
# CONFIG_PLATFORM_TYPE_rv_vexpress_a15 is not set
# CONFIG_PLATFORM_TYPE_imx51 is not set
# CONFIG_PLATFORM_TYPE_ls1021atwr is not set
# CONFIG_PLATFORM_TYPE_tegra3 is not set
# CONFIG_PLATFORM_TYPE_imx28 is not set
# CONFIG_PLATFORM_TYPE_omap3evm is not set
# CONFIG_PLATFORM_TYPE_exynos5 is not set
# CONFIG_PLATFORM_TYPE_rcar3_m3 is not set
# CONFIG_PLATFORM_TYPE_parallella is not set
# CONFIG_PLATFORM_TYPE_zynqmp is not set
# CONFIG_PLATFORM_TYPE_beagleboard is not set
# CONFIG_PLATFORM_TYPE_imx21 is not set
# CONFIG_PLATFORM_TYPE_imx6ul is not set
# CONFIG_PLATFORM_TYPE_armada38x is not set
# CONFIG_PLATFORM_TYPE_omap5 is not set
# CONFIG_PLATFORM_TYPE_rv_vexpress is not set
# CONFIG_PLATFORM_TYPE_rpi_a is not set
# CONFIG_PLATFORM_TYPE_integrator is not set
# CONFIG_PLATFORM_TYPE_custom is not set
CONFIG_PLATFORM_TYPE="rpi3"
# CONFIG_USE_DROPS_STDDIR is not set
# CONFIG_USE_DICE is not set
CONFIG_DROPS_STDDIR="/path/to/l4re"
CONFIG_DROPS_INSTDIR="/path/to/l4re"
CONFIG_BID_COLORED_PHASES=y
#
# Building
#
CONFIG_YACC="yacc"
CONFIG_LEX="flex"
CONFIG_CTAGS="ctags"
CONFIG_ETAGS="etags"
CONFIG_HAVE_LDSO=y
CONFIG_INT_CPP_NAME_SWITCH=y
CONFIG_INT_LD_NAME_SWITCH=y
# CONFIG_BID_STRIP_PROGS is not set
# CONFIG_BID_GCC_OMIT_FP is not set
CONFIG_BID_GCC_ENABLE_STACK_PROTECTOR=y
# CONFIG_BID_GCC_STACK_PROTECTOR_ALL is not set
CONFIG_BID_GCC_STACK_PROTECTOR=y
# CONFIG_BID_BUILD_DOC is not set
# CONFIG_RELEASE_MODE is not set
CONFIG_MAKECONFS_ADD=""

View File

@@ -0,0 +1,3 @@
KERNEL_CONFIG := $(REP_DIR)/config/rpi3_32b.kernel
include $(REP_DIR)/lib/mk/kernel-foc.inc

View File

@@ -0,0 +1,5 @@
L4_CONFIG := $(call select_from_repositories,config/rpi3_32b.user)
L4_BIN_DIR := $(LIB_CACHE_DIR)/syscall-foc/build/bin/arm_armv7a
include $(REP_DIR)/lib/mk/spec/arm/syscall-foc.inc

View File

@@ -1 +1 @@
9403f0e7a6b3369796b877391f51969dc59ae3e8
980a414ef3f040da40bed1cb8af3e933f3d92c1b

View File

@@ -2,5 +2,5 @@ LICENSE := GPLv2
VERSION := git
DOWNLOADS := foc.git
URL(foc) := https://git.mousetrap.xyz/alex/foc.git
REV(foc) := 1d4cf94b59a9a6fe83b0d6a0d61b92736dcf75f2
REV(foc) := 25251fe6dc56d1e1baaccdc7282b53c1870f7d77
DIR(foc) := src/kernel/foc

View File

@@ -0,0 +1,75 @@
/*
* \brief MMIO and IRQ definitions for the Raspberry Pi
* \author Norman Feske
* \date 2013-04-05
*/
/*
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__DRIVERS__DEFS__RPI_H_
#define _INCLUDE__DRIVERS__DEFS__RPI_H_
/* Genode includes */
#include <util/mmio.h>
namespace Rpi {
enum {
RAM_0_BASE = 0x00000000,
RAM_0_SIZE = 0x10000000, /* XXX ? */
MMIO_0_BASE = 0x3f000000,
MMIO_0_SIZE = 0x02000000,
/*
* IRQ numbers 0..7 refer to the basic IRQs.
* IRQ numbers 8..39 refer to GPU IRQs 0..31.
* IRQ numbers 40..71 refer to GPU IRQs 32..63.
*/
GPU_IRQ_BASE = 8,
SYSTEM_TIMER_IRQ = GPU_IRQ_BASE + 1,
SYSTEM_TIMER_MMIO_BASE = 0x3f003000,
SYSTEM_TIMER_MMIO_SIZE = 0x1000,
SYSTEM_TIMER_CLOCK = 1000000,
PL011_0_IRQ = 57,
PL011_0_MMIO_BASE = 0x3f201000,
PL011_0_MMIO_SIZE = 0x1000,
PL011_0_CLOCK = 3000000,
IRQ_CONTROLLER_BASE = 0x3f00b200,
IRQ_CONTROLLER_SIZE = 0x100,
GPIO_CONTROLLER_BASE = 0x3f200000,
GPIO_CONTROLLER_SIZE = 0x1000,
USB_DWC_OTG_BASE = 0x3f980000,
USB_DWC_OTG_SIZE = 0x20000,
/* timer */
TIMER_IRQ = 0,
/* USB host controller */
DWC_IRQ = 17,
/* CPU cache */
CACHE_LINE_SIZE_LOG2 = 5,
/* SD card */
SDHCI_BASE = MMIO_0_BASE + 0x300000,
SDHCI_SIZE = 0x100,
SDHCI_IRQ = 62,
};
enum Videocore_cache_policy { NON_COHERENT = 0,
COHERENT = 1,
L2_ONLY = 2,
UNCACHED = 3 };
};
#endif /* _INCLUDE__DRIVERS__DEFS__RPI_H_ */

View File

@@ -0,0 +1,5 @@
SPECS += arm_v7a usb gpio
REP_INC_DIR += include/spec/rpi3_32b
include $(BASE_DIR)/mk/spec/arm_v7a.mk

View File

@@ -1,6 +1,7 @@
proc is_platform_rpi {} {
return [expr [have_spec rpi] \
|| [have_spec rpi2]]
|| [have_spec rpi2] \
|| [have_spec rpi3_32b]]
}
proc have_platform_drv {} {

View File

@@ -0,0 +1,51 @@
SRC_C += \
usb/host/dwc_otg/dwc_otg/dwc_otg_adp.c \
usb/host/dwc_otg/dwc_otg/dwc_otg_attr.c \
usb/host/dwc_otg/dwc_otg/dwc_otg_cfi.c \
usb/host/dwc_otg/dwc_otg/dwc_otg_cil.c \
usb/host/dwc_otg/dwc_otg/dwc_otg_cil_intr.c \
usb/host/dwc_otg/dwc_otg/dwc_otg_driver.c \
usb/host/dwc_otg/dwc_otg/dwc_otg_hcd.c \
usb/host/dwc_otg/dwc_otg/dwc_otg_hcd_ddma.c \
usb/host/dwc_otg/dwc_otg/dwc_otg_hcd_intr.c \
usb/host/dwc_otg/dwc_otg/dwc_otg_hcd_linux.c \
usb/host/dwc_otg/dwc_otg/dwc_otg_hcd_queue.c
SRC_C += \
usb/host/dwc_otg/dwc_common_port/dwc_cc.c \
usb/host/dwc_otg/dwc_common_port/dwc_common_linux.c \
usb/host/dwc_otg/dwc_common_port/dwc_crypto.c \
usb/host/dwc_otg/dwc_common_port/dwc_dh.c \
usb/host/dwc_otg/dwc_common_port/dwc_mem.c \
usb/host/dwc_otg/dwc_common_port/dwc_modpow.c \
usb/host/dwc_otg/dwc_common_port/dwc_notifier.c
SRC_C += net/usb/usbnet.c net/usb/smsc95xx.c
include $(REP_DIR)/lib/mk/spec/arm_v7/usb.inc
CC_OPT += -DDWC_LINUX -DPLATFORM_INTERFACE
# needed for 'ehci-hcd.c', which we don't use on the rpi, but it is still
# part of the generic usb USB driver
CC_OPT += -DCONFIG_USB_EHCI_PCI=1
# for 'dwc_otg_hcd_linux.c' for enabling the FIQ, which we don't use anyway
CC_OPT += -DINTERRUPT_VC_USB=9
# for 'dwc_otg_driver.c' for preventing calls to set_irq_type
CC_OPT += -DIRQF_TRIGGER_LOW=1
INC_DIR += $(LX_CONTRIB_DIR)/drivers/usb/host/dwc_otg/dwc_common_port \
$(LX_CONTRIB_DIR)/drivers/usb/host/dwc_otg/dwc_otg
SRC_CC += platform.cc
vpath platform.cc $(LIB_DIR)/spec/rpi3_32b
vpath %.c $(LX_CONTRIB_DIR)/drivers/net/usb
# enable C++11 support
CC_CXX_OPT += -std=gnu++11
LIBS += rpi_usb
CC_CXX_WARN_STRICT =

View File

@@ -26,6 +26,10 @@ ifneq (,$(findstring rpi2,$(SPECS)))
CC_OPT += -DPLATFORM_RPI2
endif
ifneq (,$(findstring rpi3_32b,$(SPECS)))
CC_OPT += -DPLATFORM_RPI3_32B
endif
CC_WARN = -Wall -Wno-unused-variable -Wno-uninitialized \
-Wno-unused-function -Wno-overflow

View File

@@ -595,7 +595,7 @@ void *dma_alloc_coherent(struct device *, size_t size, dma_addr_t *dma, gfp_t)
if (!addr)
return 0;
#if defined(PLATFORM_RPI2)
#if defined(PLATFORM_RPI2) || defined(PLATFORM_RPI3_32B)
*dma = (dma_addr_t) ((u32) dma | (u32) 0xc0000000);
#endif
@@ -627,7 +627,7 @@ dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
Genode::error("translation virt->phys ", ptr, "->", Genode::Hex(phys), "failed, return ip ",
__builtin_return_address(0));
#if defined(PLATFORM_RPI2)
#if defined(PLATFORM_RPI2) || defined(PLATFORM_RPI3_32B)
phys = (dma_addr_t) ((u32) phys | (u32) 0xc0000000);
#endif

View File

@@ -0,0 +1,199 @@
/*
* \brief USB initialization for Raspberry Pi
* \author Norman Feske
* \date 2013-09-11
*/
/*
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
/* Genode includes */
#include <io_mem_session/connection.h>
#include <util/mmio.h>
#include <platform_session/connection.h>
/* emulation */
#include <platform.h>
#include <lx_emul.h>
#include <timer_session/connection.h>
/* dwc-otg */
#define new new_
#include <dwc_otg_dbg.h>
#undef new
using namespace Genode;
unsigned dwc_irq();
/************************************************
** Resource info passed to the dwc_otg driver **
************************************************/
enum {
DWC_BASE = 0x3f980000,
DWC_SIZE = 0x20000,
};
static resource _dwc_otg_resource[] =
{
{ DWC_BASE, DWC_BASE + DWC_SIZE - 1, "dwc_otg", IORESOURCE_MEM },
{ dwc_irq(), dwc_irq(), "dwc_otg-irq" /* name unused */, IORESOURCE_IRQ }
};
/***************************************
** Supplement to lx_emul environment **
***************************************/
#if VERBOSE_LX_EMUL
#define TRACE lx_printf("\033[32m%s\033[0m called, not implemented\n", __PRETTY_FUNCTION__)
#else
#define TRACE
#endif
#define DUMMY(retval, name) \
extern "C" long name() { \
lx_printf("\033[32m%s\033[0m called, not implemented, stop\n", #name); \
bt(); \
for (;;); \
return retval; \
}
#define CHECKED_DUMMY(retval, name) \
extern "C" long name() { \
lx_printf("\033[32m%s\033[0m called, not implemented, ignored\n", #name); \
bt(); \
return retval; \
}
#define SILENT_DUMMY(retval, name) \
extern "C" long name() { return retval; }
/*********************
** linux/hardirq.h **
*********************/
int in_irq()
{
TRACE;
return 0;
}
/*******************
** linux/delay.h **
*******************/
unsigned long loops_per_jiffy = 1;
/***********************************
** Dummies for unused PCD driver **
***********************************/
/*
* The PCD driver is used for driving the DWC-OTG device as gadget. The
* Raspberry Pi solely supports the use of the controller as host device.
* Hence, the PCD parts are not needed.
*/
DUMMY(-1, dwc_otg_pcd_disconnect_us);
DUMMY(-1, dwc_otg_pcd_remote_wakeup);
DUMMY(-1, dwc_otg_pcd_get_rmwkup_enable);
DUMMY(-1, dwc_otg_pcd_initiate_srp);
DUMMY(-1, pcd_remove);
SILENT_DUMMY( 0, pcd_init);
/************************************************************************
** Prevent use of FIQ fix, need to resolve FIQ-related symbols anyway **
************************************************************************/
void local_fiq_disable() { }
void local_fiq_enable() { }
extern "C" void fiq_fsm_spin_lock(void *lock) { }
extern "C" void fiq_fsm_spin_unlock(void *lock) { }
int claim_fiq(struct fiq_handler *f) { return 0; }
void set_fiq_regs(struct pt_regs const *regs) { }
void set_fiq_handler(void *start, unsigned int length) { }
void enable_fiq() { }
void __FIQ_Branch(unsigned long *regs) { TRACE; }
extern "C" int fiq_fsm_too_late(struct fiq_state *st, int n) { TRACE; return 0; }
extern "C" void dwc_otg_fiq_nop(struct fiq_state *state) { TRACE; }
extern "C" void dwc_otg_fiq_fsm(struct fiq_state *state, int num_channels) { TRACE; }
unsigned char _dwc_otg_fiq_stub, _dwc_otg_fiq_stub_end;
/***********************
** asm/dma_mapping.h **
***********************/
void *dma_to_virt(struct device *dev, dma_addr_t phys)
{
return phys_to_virt(phys);
}
/*******************
** linux/timer.h **
*******************/
struct tvec_base { };
struct tvec_base boot_tvec_bases;
/*******************
** Init function **
*******************/
extern "C" void module_dwc_otg_driver_init();
extern "C" int module_usbnet_init();
extern "C" int module_smsc95xx_driver_init();
void platform_hcd_init(Services *services)
{
/* enable USB power */
Platform::Connection platform;
platform.power_state(Platform::Session::POWER_USB_HCD, true);
/* register network */
if (services->nic) {
module_usbnet_init();
module_smsc95xx_driver_init();
}
/* disable fiq optimization */
fiq_enable = false;
fiq_fsm_enable = false;
bool const verbose = false;
if (verbose)
g_dbg_lvl = DBG_HCD | DBG_CIL | DBG_HCD_URB;
module_dwc_otg_driver_init();
/* setup host-controller platform device */
platform_device *pdev = (platform_device *)kzalloc(sizeof(platform_device), 0);
pdev->name = (char *)"dwc_otg";
pdev->id = 0;
pdev->num_resources = sizeof(_dwc_otg_resource)/sizeof(resource);
pdev->resource = _dwc_otg_resource;
/* needed for DMA buffer allocation. See 'hcd_buffer_alloc' in 'buffer.c' */
static u64 dma_mask = ~(u64)0;
pdev->dev.dma_mask = &dma_mask;
pdev->dev.coherent_dma_mask = ~0;
platform_device_register(pdev);
}

View File

@@ -20,7 +20,7 @@
# tun/tap proxy driver at os/src/drivers/nic/linux)
#
set use_usb_driver [expr [have_spec omap4] || [have_spec arndale] || [have_spec rpi] || [have_spec rpi2]]
set use_usb_driver [expr [have_spec omap4] || [have_spec arndale] || [have_spec rpi] || [have_spec rpi2] || [have_spec rpi3_32b]]
set use_nic_driver [expr !$use_usb_driver && ![have_spec imx53] && ![have_spec odroid_xu] && ![have_spec linux]]
if {[expr !$use_usb_driver && !$use_nic_driver]} {
@@ -42,7 +42,7 @@ lappend_if $use_usb_driver build_components drivers/usb
lappend_if [have_spec gpio] build_components drivers/gpio
proc gpio_drv { } { if {[have_spec rpi] && [have_spec hw]} { return hw_gpio_drv }
if {([have_spec rpi] || [have_spec rpi2]) && [have_spec foc]} { return foc_gpio_drv }
if {([have_spec rpi] || [have_spec rpi2] || [have_spec rpi3_32b]) && [have_spec foc]} { return foc_gpio_drv }
return gpio_drv }
source ${genode_dir}/repos/base/run/platform_drv.inc

View File

@@ -0,0 +1,59 @@
/*
* \brief Framebuffer info structure
* \author Norman Feske
* \date 2013-09-15
*/
/*
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _PLATFORM__FRAMEBUFFER_INFO_H_
#define _PLATFORM__FRAMEBUFFER_INFO_H_
#include <base/stdint.h>
namespace Platform {
using namespace Genode;
struct Framebuffer_info;
}
/**
* Structure used by the protocol between the Videocore GPU and the ARM CPU for
* setting up the framebuffer via the mbox.
*/
struct Platform::Framebuffer_info
{
uint32_t phys_width;
uint32_t phys_height;
uint32_t virt_width;
uint32_t virt_height;
uint32_t pitch = 0;
uint32_t depth;
uint32_t x_offset = 0;
uint32_t y_offset = 0;
uint32_t addr = 0;
uint32_t size = 0;
/**
* Default constructor needed to make the object transferable via RPC
*/
Framebuffer_info()
:
phys_width(0), phys_height(0), virt_width(0), virt_height(),
depth(0)
{ }
Framebuffer_info(uint32_t width, uint32_t height, uint32_t depth)
:
phys_width(width), phys_height(height),
virt_width(width), virt_height(height),
depth(depth)
{ }
};
#endif /* _PLATFORM__FRAMEBUFFER_INFO_H_ */

View File

@@ -0,0 +1,226 @@
/*
* \brief Marshalling of mbox messages for property channel
* \author Norman Feske
* \date 2013-09-15
*/
/*
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _PLATFORM__PROPERTY_MESSAGE_H_
#define _PLATFORM__PROPERTY_MESSAGE_H_
/* Genode includes */
#include <util/misc_math.h>
#include <base/printf.h>
/* board-specific includes */
#include <drivers/defs/rpi3_32b.h>
namespace Platform {
using namespace Genode;
struct Property_message;
}
/**
* Mailbox message buffer for the property channel
*
* This data structure is overlayed with memory shared with the VC. It
* contains a header, followed by a sequence of so-called command tags, wrapped
* up by a zero as an end marker.
*/
struct Platform::Property_message
{
uint32_t buf_size = 0;
enum Code { REQUEST = 0,
RESPONSE_SUCCESS = 0x80000000 };
Code code = REQUEST;
/*
* Start of the buffer that contains a sequence of tags
*/
char buffer[0];
/*
* There must be no member variables after this point
*/
/*
* Each tag consists of a header, a part with request arguments, and a
* part with responses.
*/
template <typename TAG>
struct Tag
{
uint32_t const opcode;
/**
* Size of tag buffer
*/
uint32_t const buf_size;
/**
* Size of request part of the tag
*
* The value is never changed locally. Therefore, it is declared as
* const. However, it will be updated by the VC. So we declare it
* volatile, too.
*/
uint32_t volatile const len;
char payload[0];
/**
* Utility for returning a response size of a tag type
*
* Depending on the presence of a 'TAG::Response' type, we need to
* return the actual size of the response (if the type is present) or
* 0. Both overloads are called with a compliant parameter 0. But only
* if 'T::Response' exists, the first overload is selected.
*
* SFINAE to the rescue!
*/
template <typename T>
static size_t response_size(typename T::Response *)
{
return sizeof(typename T::Response);
}
template <typename>
static size_t response_size(...)
{
return 0;
}
template <typename T>
static size_t request_size(typename T::Request *)
{
return sizeof(typename T::Request);
}
template <typename>
static size_t request_size(...)
{
return 0;
}
template <typename T>
struct Placeable : T
{
template <typename... ARGS>
Placeable(ARGS... args) : T(args...) { }
inline void *operator new (__SIZE_TYPE__, void *ptr) { return ptr; }
};
template <typename T, typename... ARGS>
void construct_request(typename T::Request *, ARGS... args)
{
new ((typename T::Request *)payload)
Placeable<typename T::Request>(args...);
}
template <typename>
void construct_request(...) { }
template <typename T>
void construct_response(typename T::Response *)
{
new (payload) Placeable<typename T::Response>;
}
template <typename>
void construct_response(...) { }
static constexpr size_t payload_size()
{
return max(request_size<TAG>(0), response_size<TAG>(0));
}
template <typename... REQUEST_ARGS>
Tag(REQUEST_ARGS... request_args)
:
opcode(TAG::opcode()),
buf_size(payload_size()),
len(request_size<TAG>(0))
{
/*
* The order is important. If we called 'construct_response' after
* 'construct_request', we would overwrite the request parameters
* with the default response.
*/
construct_response<TAG>(0);
construct_request<TAG>(0, request_args...);
}
inline void *operator new (__SIZE_TYPE__, void *ptr) { return ptr; }
};
void reset()
{
buf_size = 0;
code = REQUEST;
}
/**
* \return reference to tag in the message buffer
*/
template <typename POLICY, typename... REQUEST_ARGS>
typename POLICY::Response const &append(REQUEST_ARGS... request_args)
{
auto *tag = new (buffer + buf_size) Tag<POLICY>(request_args...);
buf_size += sizeof(Tag<POLICY>) + Tag<POLICY>::payload_size();
return *(typename POLICY::Response *)tag->payload;
}
template <typename POLICY, typename... REQUEST_ARGS>
void append_no_response(REQUEST_ARGS... request_args)
{
new (buffer + buf_size) Tag<POLICY>(request_args...);
buf_size += sizeof(Tag<POLICY>) + Tag<POLICY>::payload_size();
}
void finalize()
{
/* append end tag */
*(uint32_t *)(buffer + buf_size) = 0;
buf_size += sizeof(uint32_t);
}
static unsigned channel() { return 8; }
static Rpi::Videocore_cache_policy cache_policy()
{
return Rpi::NON_COHERENT; /* for channel 8 only */
}
void dump(char const *label)
{
unsigned const *buf = (unsigned *)this;
printf("%s message:\n", label);
for (unsigned i = 0;; i++) {
for (unsigned j = 0; j < 8; j++) {
unsigned const msg_word_idx = i*8 + j;
printf(" %08x", buf[msg_word_idx]);
if (msg_word_idx*sizeof(unsigned) < buf_size)
continue;
printf("\n");
return;
}
}
}
inline void *operator new (__SIZE_TYPE__, void *ptr) { return ptr; }
};
#endif /* _PLATFORM__PROPERTY_MESSAGE_H_ */

View File

@@ -0,0 +1,41 @@
/*
* \brief Raspberry Pi specific platform session client side
* \author Norman Feske
* \date 2013-09-16
*/
/*
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__PLATFORM_SESSION__CLIENT_H_
#define _INCLUDE__PLATFORM_SESSION__CLIENT_H_
#include <base/capability.h>
#include <base/rpc_client.h>
#include <platform_session/platform_session.h>
namespace Platform { struct Client; }
struct Platform::Client : Genode::Rpc_client<Platform::Session>
{
explicit Client(Capability<Session> session)
: Genode::Rpc_client<Session>(session) { }
void setup_framebuffer(Framebuffer_info &info) override {
call<Rpc_setup_framebuffer>(info); }
bool power_state(Power power) override {
return call<Rpc_get_power_state>(power); }
void power_state(Power power, bool enable) override {
call<Rpc_set_power_state>(power, enable); }
uint32_t clock_rate(Clock clock) {
return call<Rpc_get_clock_rate>(clock); }
};
#endif /* _INCLUDE__PLATFORM_SESSION__CLIENT_H_ */

View File

@@ -0,0 +1,89 @@
/*
* \brief Raspberry Pi specific platform session
* \author Norman Feske
* \date 2013-09-16
*/
/*
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__PLATFORM_SESSION__PLATFORM_SESSION_H_
#define _INCLUDE__PLATFORM_SESSION__PLATFORM_SESSION_H_
#include <base/capability.h>
#include <base/rpc.h>
#include <dataspace/capability.h>
#include <platform/framebuffer_info.h>
namespace Platform {
using namespace Genode;
struct Session;
}
struct Platform::Session : Genode::Session
{
/**
* \noapi
*/
static const char *service_name() { return "Platform"; }
enum { CAP_QUOTA = 2 };
/**
* Setup framebuffer
*
* The 'info' argument serves as both input and output parameter. As input,
* it describes the desired properties of the framebuffer. In return, the
* method delivers the values that were actually taken into effect.
*/
virtual void setup_framebuffer(Framebuffer_info &info) = 0;
enum Power {
POWER_SDHCI = 0,
POWER_UART0 = 1,
POWER_UART1 = 2,
POWER_USB_HCD = 3,
POWER_I2C0 = 4,
POWER_I2C1 = 5,
POWER_I2C2 = 6,
POWER_SPI = 7,
POWER_CCP2TX = 8,
};
/**
* Request power state
*/
virtual bool power_state(Power) = 0;
/**
* Set power state
*/
virtual void power_state(Power, bool enable) = 0;
enum Clock { CLOCK_EMMC = 1 };
/**
* Request clock rate
*/
virtual uint32_t clock_rate(Clock) = 0;
/*********************
** RPC declaration **
*********************/
GENODE_RPC(Rpc_setup_framebuffer, void, setup_framebuffer, Framebuffer_info &);
GENODE_RPC(Rpc_get_power_state, bool, power_state, Power);
GENODE_RPC(Rpc_set_power_state, void, power_state, Power, bool);
GENODE_RPC(Rpc_get_clock_rate, uint32_t, clock_rate, Clock);
GENODE_RPC_INTERFACE(Rpc_setup_framebuffer, Rpc_set_power_state,
Rpc_get_power_state, Rpc_get_clock_rate);
};
#endif /* _INCLUDE__PLATFORM_SESSION__PLATFORM_SESSION_H_ */

View File

@@ -0,0 +1,208 @@
/*
* \brief Gpio driver for the RaspberryPI
* \author Reinier Millo Sánchez <rmillo@uclv.cu>
* \author Alexy Gallardo Segura <alexy@uclv.cu>
* \author Humberto Lopéz Leon <humberto@uclv.cu>
* \date 2015-07-23
*/
/*
* Copyright (C) 2012 Ksys Labs LLC
* Copyright (C) 2012-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _DRIVERS__GPIO__SPEC__RPI__DRIVER_H_
#define _DRIVERS__GPIO__SPEC__RPI__DRIVER_H_
/* Genode includes */
#include <base/log.h>
#include <drivers/defs/rpi3_32b.h>
#include <gpio/driver.h>
#include <irq_session/connection.h>
/* local includes */
#include <irq.h>
#include <gpio.h>
static int verbose = 1;
namespace Gpio { class Rpi_driver; }
class Gpio::Rpi_driver : public Driver
{
private:
enum { MAX_PINS = 54 };
Reg _reg;
Genode::Irq_connection _irq;
Genode::Signal_handler<Rpi_driver> _dispatcher;
Genode::Signal_context_capability _sig_cap[MAX_PINS];
bool _irq_enabled[MAX_PINS];
bool _async;
void _handle()
{
_reg.for_each_gpio_status([&] (unsigned i, bool s) {
if (!s || !_irq_enabled[i] || !_sig_cap[i].valid()) { return; }
Genode::Signal_transmitter(_sig_cap[i]).submit();
});
}
Rpi_driver(Genode::Env &env)
:
_reg(env, Rpi::GPIO_CONTROLLER_BASE, 0, Rpi::GPIO_CONTROLLER_SIZE),
_irq(env, IRQ),
_dispatcher(env.ep(), *this, &Rpi_driver::_handle),
_async(false)
{
_irq.sigh(_dispatcher);
_irq.ack_irq();
}
void _invalid_gpio(unsigned gpio) {
Genode::error("invalid GPIO pin number ", gpio); }
public:
void set_async_events(bool async) { _async = async; }
void set_func(unsigned gpio, Reg::Function function)
{
if (verbose)
Genode::log("set_func: gpio=", gpio, " function=", (int)function);
_reg.set_gpio_function(gpio, function);
}
static Rpi_driver& factory(Genode::Env &env);
/******************************
** Driver interface **
******************************/
bool gpio_valid(unsigned gpio) { return gpio < MAX_PINS; }
void direction(unsigned gpio, bool input)
{
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
if (verbose)
Genode::log("direction: gpio=", gpio, " input=", input);
Reg::Function f = input ? Reg::FSEL_INPUT : Reg::FSEL_OUTPUT;
_reg.set_gpio_function(gpio, f);
}
void write(unsigned gpio, bool level)
{
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
if (verbose)
Genode::log("write: gpio=", gpio, " level=", level);
if (_reg.get_gpio_function(gpio)!=Reg::FSEL_OUTPUT)
warning("GPIO pin ", gpio, " is not configured for output");
if (level)
_reg.set_gpio_level(gpio);
else
_reg.clear_gpio_level(gpio);
}
bool read(unsigned gpio)
{
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return 0; }
if(_reg.get_gpio_function(gpio) != Reg::FSEL_INPUT)
warning("GPIO pin ", gpio, " is not configured for input");
return _reg.get_gpio_level(gpio);
}
void debounce_enable(unsigned, bool) {
Genode::warning("debounce_enable not supported!"); }
void debounce_time(unsigned, unsigned long) {
Genode::warning("debounce_time not supported!"); }
void falling_detect(unsigned gpio)
{
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
if (verbose) Genode::log("falling_detect: gpio=", gpio);
if(_async)
_reg.set_gpio_async_falling_detect(gpio);
else
_reg.set_gpio_falling_detect(gpio);
}
void rising_detect(unsigned gpio)
{
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
if (verbose) Genode::log("rising_detect: gpio=", gpio);
if(_async)
_reg.set_gpio_async_rising_detect(gpio);
else
_reg.set_gpio_rising_detect(gpio);
}
void high_detect(unsigned gpio)
{
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
if (verbose) Genode::log("high_detect: gpio=", gpio);
_reg.set_gpio_high_detect(gpio);
}
void low_detect(unsigned gpio)
{
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
if (verbose) Genode::log("low_detect: gpio=", gpio);
_reg.set_gpio_low_detect(gpio);
}
void irq_enable(unsigned gpio, bool enable)
{
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
if (verbose) Genode::log("irq_enable: gpio=", gpio, " enable=", enable);
_irq_enabled[gpio] = enable;
}
void ack_irq(unsigned gpio)
{
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
if (verbose) Genode::log("ack_irq: gpio=", gpio);
_reg.clear_event(gpio);
_irq.ack_irq();
}
void register_signal(unsigned gpio,
Genode::Signal_context_capability cap)
{
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
if (verbose) Genode::log("register_signal: gpio=", gpio);
_sig_cap[gpio] = cap;
}
void unregister_signal(unsigned gpio)
{
if (!gpio_valid(gpio)) { _invalid_gpio(gpio); return; }
if (verbose) Genode::log("unregister_signal: gpio=", gpio);
Genode::Signal_context_capability cap;
_sig_cap[gpio] = cap;
}
};
#endif /* _DRIVERS__GPIO__SPEC__RPI__DRIVER_H_ */

View File

@@ -0,0 +1,3 @@
/*
* Dummy compilation unit needed to link a valid target.
*/

View File

@@ -0,0 +1,19 @@
/*
* \brief GPIO interrupt number
* \author Reinier Millo Sánchez <rmillo@uclv.cu>
* \date 2015-07-27
*/
/*
* Copyright (C) 2015-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _DRIVERS__GPIO__SPEC__RPI__SPEC__FOC__IRQ_H_
#define _DRIVERS__GPIO__SPEC__RPI__SPEC__FOC__IRQ_H_
namespace Gpio { enum { IRQ = 49 }; }
#endif /* _DRIVERS__GPIO__SPEC__RPI__SPEC__FOC__IRQ_H_ */

View File

@@ -0,0 +1,7 @@
TARGET = foc_gpio_drv
REQUIRES = rpi3_32b
SRC_CC += main.cc
LIBS = base
INC_DIR += $(PRG_DIR) $(PRG_DIR)/..
vpath main.cc $(PRG_DIR)/..

View File

@@ -0,0 +1,242 @@
/*
* \brief Gpio driver for the RaspberryPI
* \author Reinier Millo Sánchez <rmillo@uclv.cu>
* \author Alexy Gallardo Segura <alexy@uclv.cu>
* \author Humberto Lopéz Leon <humberto@uclv.cu>
* \date 2015-07-23
*/
/*
* Copyright (C) 2012 Ksys Labs LLC
* Copyright (C) 2012-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _DRIVERS__GPIO__SPEC__RPI__GPIO_H_
#define _DRIVERS__GPIO__SPEC__RPI__GPIO_H_
/* Genode includes */
#include <base/printf.h>
#include <base/attached_io_mem_dataspace.h>
#include <util/mmio.h>
#include <timer_session/connection.h>
namespace Gpio {
using namespace Genode;
class Reg;
}
class Gpio::Reg : Attached_io_mem_dataspace, Mmio
{
private:
/**
* GPIO Function Select Registers
*/
struct Gpfsel : Register_array <0x00,32,6,32> {
struct Sel0 : Bitfield <0,3> {};
struct Sel1 : Bitfield <3,3> {};
struct Sel2 : Bitfield <6,3> {};
struct Sel3 : Bitfield <9,3> {};
struct Sel4 : Bitfield <12,3> {};
struct Sel5 : Bitfield <15,3> {};
struct Sel6 : Bitfield <18,3> {};
struct Sel7 : Bitfield <21,3> {};
struct Sel8 : Bitfield <24,3> {};
struct Sel9 : Bitfield <27,3> {};
};
/**
* GPIO Pin Output Set Registers
*/
struct Gpset : Register_array <0x1c,32,64,1> {};
/**
* GPIO Pin Output Clear Registers
*/
struct Gpclr : Register_array <0x28,32,64,1> {};
/**
* GPIO Pin Level Registers
*/
struct Gplev : Register_array <0x34,32,64,1> {};
/**
* GPIO Pin Event Detect Status Registers
*/
struct Gppeds : Register_array <0x40,32,64,1> {};
struct Gppeds_raw : Register <0x40,64> {};
/**
* GPIO Pin Rising Edge Detect Enable Registers
*/
struct Gpren : Register_array <0x4c,32,64,1> {};
/**
* GPIO Pin Falling Edge Detect Enable Registers
*/
struct Gpfen : Register_array <0x58,32,64,1> {};
/**
* GPIO Pin High Detect Enable Registers
*/
struct Gphen : Register_array <0x64,32,64,1> {};
/**
* GPIO Pin Low Detect Enable Registers
*/
struct Gplen : Register_array <0x70,32,64,1> {};
/**
* GPIO Pin Aync. Rising Edge Detect Registers
*/
struct Gparen : Register_array <0x7c,32,64,1> {};
/**
* GPIO Pin Async. Falling Edge Detect Registers
*/
struct Gpafen : Register_array <0x88,32,64,1> {};
/**
* GPIO Pin Pull-up/down Enable Registers
*/
struct Gppud : Register <0x94,32> {};
/**
* GPIO Pin Pull-up/down Enable Clock Registers
*/
struct Gppudclk : Register_array <0x98,32,64,1> {};
struct Timer_delayer : Timer::Connection, Mmio::Delayer
{
Timer_delayer(Genode::Env &env) : Timer::Connection(env) { }
/**
* Implementation of 'Delayer' interface
*/
void usleep(unsigned us) { Timer::Connection::usleep(us); }
} _delayer;
template <typename T0, typename T1, typename T2,
typename T3, typename T4, typename T5>
void _set_gpio_det(unsigned gpio)
{
write<T0>(0, gpio);
write<T1>(0, gpio);
write<T2>(0, gpio);
write<T3>(0, gpio);
write<T4>(0, gpio);
write<T5>(1, gpio);
}
public:
Reg(Genode::Env &env,
addr_t base, off_t offset, size_t size)
:
Attached_io_mem_dataspace(env, base, size),
Mmio((addr_t)local_addr<Reg>() + offset),
_delayer(env)
{ }
enum Function {
FSEL_INPUT = 0,
FSEL_OUTPUT = 1,
FSEL_ALT0 = 4,
FSEL_ALT1 = 5,
FSEL_ALT2 = 6,
FSEL_ALT3 = 7,
FSEL_ALT4 = 3,
FSEL_ALT5 = 2,
};
void set_gpio_function(unsigned gpio, Function function)
{
/*
* Set a pull-up internal resistor in the input pin to avoid
* electromagnetic radiation or static noise
*/
if (function == FSEL_INPUT) {
write<Gppud>(1);
_delayer.usleep(1);
write<Gppudclk>(1, gpio);
_delayer.usleep(1);
write<Gppud>(0);
write<Gppudclk>(0, gpio);
}
/* set the pin function */
unsigned sel_id = gpio % 10;
unsigned reg_id = gpio / 10;
switch(sel_id){
case 0: write<Gpfsel::Sel0>(function, reg_id); break;
case 1: write<Gpfsel::Sel1>(function, reg_id); break;
case 2: write<Gpfsel::Sel2>(function, reg_id); break;
case 3: write<Gpfsel::Sel3>(function, reg_id); break;
case 4: write<Gpfsel::Sel4>(function, reg_id); break;
case 5: write<Gpfsel::Sel5>(function, reg_id); break;
case 6: write<Gpfsel::Sel6>(function, reg_id); break;
case 7: write<Gpfsel::Sel7>(function, reg_id); break;
case 8: write<Gpfsel::Sel8>(function, reg_id); break;
case 9: write<Gpfsel::Sel9>(function, reg_id); break;
default:;
}
}
unsigned get_gpio_function(unsigned gpio)
{
unsigned sel_id = gpio % 10;
unsigned reg_id = gpio / 10;
switch(sel_id){
case 0: return read<Gpfsel::Sel0>(reg_id);
case 1: return read<Gpfsel::Sel1>(reg_id);
case 2: return read<Gpfsel::Sel2>(reg_id);
case 3: return read<Gpfsel::Sel3>(reg_id);
case 4: return read<Gpfsel::Sel4>(reg_id);
case 5: return read<Gpfsel::Sel5>(reg_id);
case 6: return read<Gpfsel::Sel6>(reg_id);
case 7: return read<Gpfsel::Sel7>(reg_id);
case 8: return read<Gpfsel::Sel8>(reg_id);
case 9: return read<Gpfsel::Sel9>(reg_id);
default: return 0;
}
}
int get_gpio_level(unsigned gpio) { return read<Gppudclk>(gpio); }
void set_gpio_level(unsigned gpio) { write<Gpset>(1, gpio); }
void clear_gpio_level(unsigned gpio) { write<Gpclr>(1, gpio); }
void set_gpio_falling_detect(unsigned gpio) {
_set_gpio_det<Gpren, Gphen, Gplen, Gparen, Gpafen, Gpfen>(gpio); }
void set_gpio_rising_detect(unsigned gpio) {
_set_gpio_det<Gphen, Gplen, Gparen, Gpafen, Gpfen, Gpren>(gpio); }
void set_gpio_high_detect(unsigned gpio) {
_set_gpio_det<Gpren, Gplen, Gparen, Gpafen, Gpfen, Gphen>(gpio); }
void set_gpio_low_detect(unsigned gpio) {
_set_gpio_det<Gpren, Gphen, Gparen, Gpafen, Gpfen, Gplen>(gpio); }
void set_gpio_async_falling_detect(unsigned gpio) {
_set_gpio_det<Gpren, Gphen, Gplen, Gparen, Gpfen, Gpafen>(gpio); }
void set_gpio_async_rising_detect(unsigned gpio) {
_set_gpio_det<Gpren, Gphen, Gplen, Gpafen, Gpfen, Gparen>(gpio); }
template <typename F>
void for_each_gpio_status(F f)
{
Gppeds_raw::access_t const gppeds = read<Gppeds_raw>();
for(unsigned i = 0; i < Gppeds_raw::ACCESS_WIDTH; i++) {
f(i, gppeds & (1 << i)); }
}
void clear_event(unsigned gpio) { write<Gppeds>(1, gpio); }
};
#endif /* _DRIVERS__GPIO__SPEC__RPI__GPIO_H_ */

View File

@@ -0,0 +1,107 @@
/*
* \brief Gpio driver for the RaspberryPI
* \author Reinier Millo Sánchez <rmillo@uclv.cu>
* \author Alexy Gallardo Segura <alexy@uclv.cu>
* \author Humberto Lopéz Leon <humberto@uclv.cu>
* \date 2015-07-23
*/
/*
* Copyright (C) 2015-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* Genode includes */
#include <base/attached_rom_dataspace.h>
#include <base/component.h>
#include <base/log.h>
#include <base/heap.h>
#include <gpio/component.h>
#include <gpio/config.h>
#include <os/server.h>
/* local includes */
#include "driver.h"
Gpio::Rpi_driver& Gpio::Rpi_driver::factory(Genode::Env &env)
{
static Rpi_driver driver(env);
return driver;
}
struct Main
{
Genode::Env &env;
Genode::Sliced_heap sliced_heap;
Gpio::Rpi_driver &driver;
Gpio::Root root;
Genode::Attached_rom_dataspace config_rom { env, "config" };
Main(Genode::Env &env)
:
env(env),
sliced_heap(env.ram(), env.rm()),
driver(Gpio::Rpi_driver::factory(env)),
root(&env.ep().rpc_ep(), &sliced_heap, driver)
{
using namespace Genode;
log("--- Raspberry Pi GPIO driver ---");
/*
* Check configuration for async events detect
*/
unsigned int async = 0;
try {
config_rom.xml().attribute("async_events").value(&async);
} catch (...) { }
driver.set_async_events(async>0);
/*
* Check for common GPIO configuration
*/
Gpio::process_config(config_rom.xml(), driver);
/*
* Check configuration for specific function
*/
try {
Xml_node gpio_node = config_rom.xml().sub_node("gpio");
for (;; gpio_node = gpio_node.next("gpio")) {
unsigned num = 0;
unsigned function = 0;
try {
gpio_node.attribute("num").value(&num);
gpio_node.attribute("function").value(&function);
switch(function){
case 0: driver.set_func(num, Gpio::Reg::FSEL_ALT0); break;
case 1: driver.set_func(num, Gpio::Reg::FSEL_ALT1); break;
case 2: driver.set_func(num, Gpio::Reg::FSEL_ALT2); break;
case 3: driver.set_func(num, Gpio::Reg::FSEL_ALT3); break;
case 4: driver.set_func(num, Gpio::Reg::FSEL_ALT4); break;
case 5: driver.set_func(num, Gpio::Reg::FSEL_ALT5); break;
default: warning("wrong pin function, ignore node");
}
} catch(Xml_node::Nonexistent_attribute) {
warning("missing attribute, ignore node");
}
if (gpio_node.last("gpio")) break;
}
} catch (Xml_node::Nonexistent_sub_node) { warning("no GPIO config"); }
/*
* Announce service
*/
env.parent().announce(env.ep().manage(root));
}
};
void Component::construct(Genode::Env &env) { static Main main(env); }

View File

@@ -0,0 +1,63 @@
/*
* \brief Marshalling of mbox messages for framebuffer channel
* \author Norman Feske
* \date 2013-09-15
*/
/*
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _FRAMEBUFFER_MESSAGE_H_
#define _FRAMEBUFFER_MESSAGE_H_
/* Genode includes */
#include <util/misc_math.h>
#include <base/printf.h>
/* board-specific includes */
#include <drivers/defs/rpi3_32b.h>
#include <platform/framebuffer_info.h>
namespace Platform { struct Framebuffer_message; }
/**
* Mailbox message buffer for the framebuffer channel
*/
struct Platform::Framebuffer_message : Framebuffer_info
{
Framebuffer_message(Framebuffer_info const &info) : Framebuffer_info(info) { }
void finalize() { }
static unsigned channel() { return 1; }
static Rpi::Videocore_cache_policy cache_policy() {
return Rpi::COHERENT;
}
void dump(char const *label)
{
using Genode::printf;
printf("%s message:\n", label);
printf(" phys_width: %u\n", phys_width);
printf(" phys_height: %u\n", phys_height);
printf(" virt_width: %u\n", virt_width);
printf(" virt_height: %u\n", virt_height);
printf(" pitch: %u\n", pitch);
printf(" depth: %d\n", depth);
printf(" x_offset: %d\n", x_offset);
printf(" y_offset: %d\n", y_offset);
printf(" addr: 0x%08x\n", addr);
printf(" size: 0x%08x\n", size);
}
inline void *operator new (__SIZE_TYPE__, void *ptr) { return ptr; }
};
#endif /* _FRAMEBUFFER_MESSAGE_H_ */

View File

@@ -0,0 +1,118 @@
/*
* \brief Driver for Raspberry Pi specific platform devices
* \author Norman Feske
* \date 2013-09-16
*/
/*
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* Genode includes */
#include <base/log.h>
#include <base/component.h>
#include <base/heap.h>
#include <root/component.h>
/* platform includes */
#include <platform_session/platform_session.h>
#include <platform/property_message.h>
/* local includes */
#include <mbox.h>
#include <property_command.h>
#include <framebuffer_message.h>
namespace Platform {
class Session_component;
class Root;
}
class Platform::Session_component : public Genode::Rpc_object<Platform::Session>
{
private:
Mbox &_mbox;
public:
Session_component(Mbox &mbox) : _mbox(mbox) { }
/**********************************
** Platform session interface **
**********************************/
void setup_framebuffer(Framebuffer_info &info)
{
auto const &msg = _mbox.message<Framebuffer_message>(info);
_mbox.call<Framebuffer_message>();
info = msg;
}
bool power_state(Power id)
{
auto &msg = _mbox.message<Property_message>();
auto const &res = msg.append<Property_command::Get_power_state>(id);
_mbox.call<Property_message>();
return res.state;
}
void power_state(Power id, bool enable)
{
auto &msg = _mbox.message<Property_message>();
msg.append_no_response<Property_command::Set_power_state>(id, enable, true);
_mbox.call<Property_message>();
}
uint32_t clock_rate(Clock id)
{
auto &msg = _mbox.message<Property_message>();
auto const &res = msg.append<Property_command::Get_clock_rate>(id);
_mbox.call<Property_message>();
return res.hz;
}
};
class Platform::Root : public Genode::Root_component<Platform::Session_component>
{
private:
Mbox _mbox;
protected:
Session_component *_create_session(const char *) {
return new (md_alloc()) Session_component(_mbox); }
public:
Root(Env& env, Allocator & md_alloc)
: Root_component<Session_component>(env.ep(), md_alloc), _mbox(env)
{ }
};
struct Main
{
Genode::Env & env;
Genode::Heap heap { env.ram(), env.rm() };
Platform::Root root { env, heap };
Main(Genode::Env & env) : env(env) {
env.parent().announce(env.ep().manage(root)); }
};
void Component::construct(Genode::Env &env)
{
Genode::log("--- Raspberry Pi platform driver ---");
static Main main(env);
}

View File

@@ -0,0 +1,127 @@
/*
* \brief Mbox for communicating between Videocore and ARM
* \author Norman Feske
* \date 2013-09-14
*/
/*
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _DRIVERS__PLATFORM__SPEC__RPI__MBOX_H_
#define _DRIVERS__PLATFORM__SPEC__RPI__MBOX_H_
/* Genode includes */
#include <util/mmio.h>
#include <base/env.h>
#include <os/attached_mmio.h>
#include <base/attached_ram_dataspace.h>
#include <base/log.h>
#include <dataspace/client.h>
#include <timer_session/connection.h>
class Mbox : Genode::Attached_mmio
{
private:
Genode::Env &_env;
enum { verbose = false };
typedef Genode::addr_t addr_t;
typedef Genode::uint32_t uint32_t;
typedef Genode::Dataspace_client Dataspace_client;
enum { BASE = 0x3f00b800,
SIZE = 0x100 };
struct Read : Register<0x80, 32> { };
struct Status : Register<0x98, 32>
{
struct Rd_empty : Bitfield<30, 1> { };
struct Wr_full : Bitfield<31, 1> { };
};
struct Write : Register<0xa0, 32>
{
struct Channel : Bitfield<0, 4> { };
struct Value : Bitfield<4, 26> { };
struct Cache_policy : Bitfield<30, 2> { };
};
enum { MSG_BUFFER_SIZE = 0x1000 };
Genode::Attached_ram_dataspace _msg_buffer { _env.ram(), _env.rm(),
MSG_BUFFER_SIZE };
addr_t const _msg_phys = { Dataspace_client(_msg_buffer.cap()).phys_addr() };
struct Delayer : Mmio::Delayer
{
Timer::Connection timer;
void usleep(unsigned us) { timer.usleep(us); }
Delayer(Genode::Env &env) : timer(env) { }
} _delayer { _env };
template <typename MESSAGE>
MESSAGE &_message()
{
return *_msg_buffer.local_addr<MESSAGE>();
}
public:
Mbox(Genode::Env &env)
: Genode::Attached_mmio(env, BASE, SIZE), _env(env) { }
/**
* Return reference to typed message buffer
*/
template <typename MESSAGE, typename... ARGS>
MESSAGE &message(ARGS... args)
{
return *(new (_msg_buffer.local_addr<void>()) MESSAGE(args...));
}
template <typename MESSAGE>
void call()
{
_message<MESSAGE>().finalize();
if (verbose)
_message<MESSAGE>().dump("Input");
/* flush pending data in the read buffer */
while (!read<Status::Rd_empty>())
read<Read>();
try { wait_for(Attempts(500), Microseconds(1), _delayer,
Status::Wr_full::Equal(0)); }
catch (Polling_timeout) {
Genode::error("Mbox: timeout waiting for ready-to-write");
return;
}
Write::access_t value = 0;
Write::Channel:: set(value, MESSAGE::channel());
Write::Value:: set(value, _msg_phys >> Write::Value::SHIFT);
Write::Cache_policy::set(value, MESSAGE::cache_policy());
write<Write>(value);
try { wait_for(Attempts(500), Microseconds(1), _delayer,
Status::Rd_empty::Equal(0)); }
catch (Polling_timeout) {
Genode::error("Mbox: timeout waiting for response");
return;
}
if (verbose)
_message<MESSAGE>().dump("Output");
}
};
#endif /* _DRIVERS__PLATFORM__SPEC__RPI__MBOX_H_ */

View File

@@ -0,0 +1,133 @@
/*
* \brief Command definitions for the property mbox channel
* \author Norman Feske
* \date 2013-09-15
*/
/*
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _PROPERTY_COMMAND_H_
#define _PROPERTY_COMMAND_H_
/* Genode includes */
#include <base/stdint.h>
namespace Property_command {
using namespace Genode;
struct Get_power_state
{
static uint32_t opcode() { return 0x00020001; };
struct Request
{
uint32_t const device_id;
Request(uint32_t device_id) : device_id(device_id) { }
};
struct Response
{
uint32_t const device_id = 0;
uint32_t const state = 0;
};
};
struct Set_power_state
{
static uint32_t opcode() { return 0x00028001; };
struct Request
{
uint32_t const device_id;
uint32_t const state;
Request(uint32_t device_id, bool enable, bool wait)
:
device_id(device_id),
state(enable | (wait << 1))
{ }
};
struct Response
{
uint32_t const device_id = 0;
uint32_t const state = 0;
};
};
struct Get_clock_rate
{
static uint32_t opcode() { return 0x00030002; };
struct Request
{
uint32_t const clock_id;
Request(uint32_t clock_id) : clock_id(clock_id) { }
};
struct Response
{
uint32_t const clock_id = 0;
uint32_t const hz = 0;
};
};
struct Allocate_buffer
{
static uint32_t opcode() { return 0x00040001; };
struct Request
{
uint32_t const alignment = 0x100;
};
struct Response
{
uint32_t const address = 0;
uint32_t const size = 0;
};
};
struct Release_buffer
{
static uint32_t opcode() { return 0x00048001; };
};
struct Get_physical_w_h
{
static uint32_t opcode() { return 0x00040003; };
struct Response
{
uint32_t const width = 0;
uint32_t const height = 0;
};
};
struct Set_physical_w_h
{
static uint32_t opcode() { return 0x00048003; };
struct Request
{
uint32_t const width;
uint32_t const height;
Request(uint32_t width, uint32_t height)
: width(width), height(height) { }
};
};
}
#endif /* _PROPERTY_COMMAND_H_ */

View File

@@ -0,0 +1,8 @@
TARGET = platform_drv
REQUIRES = rpi3_32b
SRC_CC = main.cc
INC_DIR += ${PRG_DIR}
LIBS = base
# enable C++11 support
CC_CXX_OPT += -std=gnu++11

View File

@@ -10,7 +10,7 @@ MAKEOVERRIDES =
PLATFORM = $(MAKECMDGOALS)
PLATFORMS = x86_32 x86_64 panda pbxa9 rpi rpi2 arndale imx53_qsb imx53_qsb_tz \
PLATFORMS = x86_32 x86_64 panda pbxa9 rpi rpi2 rpi3_32b arndale imx53_qsb imx53_qsb_tz \
usb_armory wand_quad sabre_lite odroid_xu odroid_x2 zynq_qemu muen \
riscv_spike linux bb_x15
@@ -140,6 +140,7 @@ BUILD_CONF(pbxa9) := run_kernel_hw_foc $(BUILD_CONF_PBXA9)
BUILD_CONF(panda) := run_kernel_hw_foc run_boot_dir repos
BUILD_CONF(rpi) := run_kernel_hw_foc run_boot_dir repos
BUILD_CONF(rpi2) := run_kernel_foc run_boot_dir repos
BUILD_CONF(rpi3_32b) := run_kernel_foc run_boot_dir repos
BUILD_CONF(arndale) := run_kernel_hw_foc run_boot_dir repos
BUILD_CONF(imx53_qsb) := run_kernel_hw run_boot_dir repos
BUILD_CONF(imx53_qsb_tz) := run_kernel_hw run_boot_dir repos
@@ -226,6 +227,7 @@ SPECS(pbxa9) := pbxa9
SPECS(panda) := panda
SPECS(rpi) := rpi
SPECS(rpi2) := rpi2
SPECS(rpi3_32b) := rpi3_32b
SPECS(arndale) := arndale
SPECS(imx53_qsb) := imx53_qsb
SPECS(imx53_qsb_tz) := imx53_qsb trustzone

View File

@@ -13,6 +13,7 @@ proc core_link_address { } {
if {[have_spec arndale ]} { return "0x80100000" }
if {[have_spec rpi ]} { return "0x00800000" }
if {[have_spec rpi2 ]} { return "0x00800000" }
if {[have_spec rpi3_32b ]} { return "0x00800000" }
if {[have_spec panda ]} { return "0xa0000000" }
if {[have_spec pbxa9 ]} { return "0x76000000" }
if {[have_spec odroid_x2]} { return "0x80100000" }