├── .gitignore
├── LICENSE
├── README.md
├── board
├── rpi
│ ├── arch
│ ├── devices
│ └── image_link_address
└── rpi3
│ ├── arch
│ ├── image_link_address
│ └── qemu_args
├── include
└── rpi_mbox_session
│ ├── client.h
│ ├── connection.h
│ └── rpi_mbox_session.h
├── lib
├── import
│ └── import-rpi_lx_emul.mk
└── mk
│ ├── rpi_lx_emul.mk
│ └── spec
│ ├── arm_v6
│ ├── bootstrap-hw-rpi.mk
│ ├── core-hw-rpi.mk
│ └── rpi_linux_generated.mk
│ └── arm_v8
│ ├── bootstrap-hw-rpi3.mk
│ └── core-hw-rpi3.mk
├── ports
├── rpi_linux.hash
└── rpi_linux.port
├── recipes
├── api
│ ├── rpi_linux
│ │ ├── content.mk
│ │ └── hash
│ └── rpi_mbox_session
│ │ ├── content.mk
│ │ └── hash
├── pkg
│ ├── drivers_interactive-rpi
│ │ ├── README
│ │ ├── archives
│ │ └── hash
│ ├── drivers_nic-rpi
│ │ ├── README
│ │ ├── archives
│ │ └── hash
│ └── test_usb_host-rpi
│ │ ├── README
│ │ ├── archives
│ │ └── hash
├── raw
│ ├── drivers_interactive-rpi
│ │ ├── content.mk
│ │ ├── drivers.config
│ │ ├── event_filter.config
│ │ ├── fb.config
│ │ └── hash
│ ├── drivers_nic-rpi
│ │ ├── content.mk
│ │ ├── drivers.config
│ │ └── hash
│ ├── rpi-devices
│ │ ├── content.mk
│ │ └── hash
│ └── test_usb_host-rpi
│ │ ├── content.mk
│ │ ├── drivers.config
│ │ └── hash
└── src
│ ├── base-hw-rpi
│ ├── content.mk
│ ├── hash
│ └── used_apis
│ ├── base-hw-rpi3
│ ├── content.mk
│ ├── hash
│ └── used_apis
│ ├── rpi_fb
│ ├── content.mk
│ ├── hash
│ └── used_apis
│ ├── rpi_platform
│ ├── content.mk
│ ├── hash
│ └── used_apis
│ └── rpi_usb_host
│ ├── content.mk
│ ├── hash
│ └── used_apis
├── run
└── rpi1_framebuffer.run
└── src
├── bootstrap
└── board
│ ├── rpi
│ ├── board.h
│ └── platform.cc
│ └── rpi3
│ ├── board.h
│ └── platform.cc
├── core
├── board
│ ├── rpi
│ │ └── board.h
│ └── rpi3
│ │ └── board.h
└── spec
│ └── arm
│ ├── bcm2835_pic.cc
│ ├── bcm2835_pic.h
│ ├── bcm2837_pic.cc
│ ├── bcm2837_pic.h
│ ├── system_timer.cc
│ └── system_timer.h
├── driver
├── framebuffer
│ └── rpi
│ │ ├── README
│ │ ├── main.cc
│ │ └── target.mk
├── platform
│ └── rpi
│ │ ├── main.cc
│ │ ├── mbox.h
│ │ ├── power_domains.h
│ │ ├── property_command.h
│ │ ├── property_message.h
│ │ ├── rpi_mbox_root.h
│ │ └── target.mk
├── uart
│ └── rpi3
│ │ ├── target.mk
│ │ └── uart_driver.h
└── usb_host
│ └── rpi
│ ├── README
│ ├── asm-generic
│ └── preempt.h
│ ├── clear_tt_buffers.patch
│ ├── dep.list
│ ├── dummies.c
│ ├── fiq_fsm_disable.patch
│ ├── generated_dummies.c
│ ├── lx_emul.c
│ ├── lx_emul.h
│ ├── main.cc
│ ├── nyet_error_genode.patch
│ ├── sof_irq_genode.patch
│ ├── source.list
│ ├── split_trans_irq.patch
│ └── target.mk
├── include
├── hw
│ ├── spec
│ │ ├── arm
│ │ │ └── rpi_board.h
│ │ └── arm_64
│ │ │ └── rpi3_board.h
│ └── uart
│ │ └── bcm2835_mini.h
└── spec
│ └── arm_v6
│ └── lx_emul
│ └── initcall_order.h
├── lib
└── rpi_linux_generated
│ └── arm_v6
│ └── dep.list
└── rpi_linux
└── arm_v6
├── target.inc
└── target.mk
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | *.orig
3 | *.swp
4 | *.rej
5 | .git
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Genode support for Raspberry Pi boards
2 |
3 | This repository complements the Genode OS framework (https://genode.org) with
4 | the board support needed to use Genode on Raspberry Pi based devices.
5 |
6 | To use it, you first need to obtain a clone of Genode:
7 |
8 | ! git clone https://github.com/genodelabs/genode.git genode
9 |
10 | Now, clone the _genode-rpi.git_ repository to _genode/repos/rpi_:
11 |
12 | ! git clone https://github.com/skalk/genode-rpi.git genode/repos/rpi
13 |
14 | For enabling the board support, adjust the build-directory configuration
15 | _etc/build.conf_ by adding the following line to the 'REPOSITORIES'
16 | definitions.
17 |
18 | ! REPOSITORIES += $(GENODE_DIR)/repos/rpi
19 |
20 |
21 | License
22 | -------
23 |
24 | Genode-specific code is provided under Genode's regular open-source license,
25 | which is AGPLv3 + open-source linking exception. This code is also available
26 | under a commercial license offered by Genode Labs.
27 |
28 | For code ported from other projects - e.g., device drivers ported from the
29 | Linux kernel - the license of the originating upstream project applies.
30 |
31 | Please refer to the individual file headers for detailed information.
32 |
--------------------------------------------------------------------------------
/board/rpi/arch:
--------------------------------------------------------------------------------
1 | arm_v6
2 |
--------------------------------------------------------------------------------
/board/rpi/devices:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/board/rpi/image_link_address:
--------------------------------------------------------------------------------
1 | 0x00800000
2 |
--------------------------------------------------------------------------------
/board/rpi3/arch:
--------------------------------------------------------------------------------
1 | arm_v8a
2 |
--------------------------------------------------------------------------------
/board/rpi3/image_link_address:
--------------------------------------------------------------------------------
1 | 0x00800000
2 |
--------------------------------------------------------------------------------
/board/rpi3/qemu_args:
--------------------------------------------------------------------------------
1 | -M raspi3b -m 1024
2 |
--------------------------------------------------------------------------------
/include/rpi_mbox_session/client.h:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Raspberry Pi specific platform session client side
3 | * \author Norman Feske
4 | * \author Tomasz Gajewski
5 | * \date 2013-09-16
6 | */
7 |
8 | /*
9 | * Copyright (C) 2013-2021 Genode Labs GmbH
10 | *
11 | * This file is part of the Genode OS framework, which is distributed
12 | * under the terms of the GNU Affero General Public License version 3.
13 | */
14 |
15 | #ifndef _INCLUDE__RPI_MBOX_SESSION__CLIENT_H_
16 | #define _INCLUDE__RPI_MBOX_SESSION__CLIENT_H_
17 |
18 | #include
19 | #include
20 | #include
21 |
22 | namespace Rpi_mbox { struct Client; }
23 |
24 | struct Rpi_mbox::Client : Genode::Rpc_client
25 | {
26 | explicit Client(Capability session)
27 | : Genode::Rpc_client(session) { }
28 |
29 | void setup_framebuffer(Framebuffer_info &info) override {
30 | call(info); }
31 | };
32 |
33 | #endif /* _INCLUDE__RPI_MBOX_SESSION__CLIENT_H_ */
34 |
--------------------------------------------------------------------------------
/include/rpi_mbox_session/connection.h:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Connection to platform service
3 | * \author Stefan Kalkowski
4 | * \date 2013-04-29
5 | */
6 |
7 | /*
8 | * Copyright (C) 2013-2017 Genode Labs GmbH
9 | *
10 | * This file is part of the Genode OS framework, which is distributed
11 | * under the terms of the GNU Affero General Public License version 3.
12 | */
13 |
14 | #ifndef _INCLUDE__RPI_MBOX_SESSION__CONNECTION_H_
15 | #define _INCLUDE__RPI_MBOX_SESSION__CONNECTION_H_
16 |
17 | #include
18 | #include
19 |
20 | namespace Rpi_mbox { struct Connection; }
21 |
22 |
23 | struct Rpi_mbox::Connection : Genode::Connection, Client
24 | {
25 | Connection(Genode::Env &env)
26 | :
27 | Genode::Connection(env, Label(), Ram_quota { 6*1024 }, Args()),
28 | Client(cap())
29 | { }
30 | };
31 |
32 | #endif /* _INCLUDE__RPI_MBOX_SESSION__CONNECTION_H_ */
33 |
--------------------------------------------------------------------------------
/include/rpi_mbox_session/rpi_mbox_session.h:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Raspberry Pi specific platform session
3 | * \author Norman Feske
4 | * \author Tomasz Gajewski
5 | * \date 2013-09-16
6 | */
7 |
8 | /*
9 | * Copyright (C) 2013-2021 Genode Labs GmbH
10 | *
11 | * This file is part of the Genode OS framework, which is distributed
12 | * under the terms of the GNU Affero General Public License version 3.
13 | */
14 |
15 | #ifndef _INCLUDE__RPI_MBOX_SESSION__RPI_MBOX_SESSION_H_
16 | #define _INCLUDE__RPI_MBOX_SESSION__RPI_MBOX_SESSION_H_
17 |
18 | #include
19 | #include
20 | #include
21 |
22 | namespace Rpi_mbox {
23 | using namespace Genode;
24 | struct Session;
25 | struct Framebuffer_info;
26 | }
27 |
28 |
29 | /**
30 | * Structure used by the protocol between the Videocore GPU and the ARM CPU for
31 | * setting up the framebuffer via the mbox.
32 | */
33 | struct Rpi_mbox::Framebuffer_info
34 | {
35 | uint32_t phys_width;
36 | uint32_t phys_height;
37 | uint32_t virt_width;
38 | uint32_t virt_height;
39 | uint32_t pitch = 0;
40 | uint32_t depth;
41 | uint32_t x_offset = 0;
42 | uint32_t y_offset = 0;
43 | uint32_t addr = 0;
44 | uint32_t size = 0;
45 |
46 | /**
47 | * Default constructor needed to make the object transferable via RPC
48 | */
49 | Framebuffer_info()
50 | :
51 | phys_width(0), phys_height(0), virt_width(0), virt_height(),
52 | depth(0)
53 | { }
54 |
55 | Framebuffer_info(uint32_t width, uint32_t height, uint32_t depth)
56 | :
57 | phys_width(width), phys_height(height),
58 | virt_width(width), virt_height(height),
59 | depth(depth)
60 | { }
61 | };
62 |
63 |
64 | struct Rpi_mbox::Session : Genode::Session
65 | {
66 | /**
67 | * \noapi
68 | */
69 | static const char *service_name() { return "Rpi_mbox"; }
70 |
71 | enum { CAP_QUOTA = 2 };
72 |
73 | /**
74 | * Setup framebuffer
75 | *
76 | * The 'info' argument serves as both input and output parameter. As input,
77 | * it describes the desired properties of the framebuffer. In return, the
78 | * method delivers the values that were actually taken into effect.
79 | */
80 | virtual void setup_framebuffer(Framebuffer_info &info) = 0;
81 |
82 |
83 | /*********************
84 | ** RPC declaration **
85 | *********************/
86 |
87 | GENODE_RPC(Rpc_setup_framebuffer, void, setup_framebuffer, Framebuffer_info &);
88 |
89 | GENODE_RPC_INTERFACE(Rpc_setup_framebuffer);
90 | };
91 |
92 | #endif /* _INCLUDE__RPI_MBOX_SESSION__RPI_MBOX_SESSION_H_ */
93 |
--------------------------------------------------------------------------------
/lib/import/import-rpi_lx_emul.mk:
--------------------------------------------------------------------------------
1 | # check for installation of device-tree compiler
2 | $(call check_tool,dtc)
3 |
4 | LIBS += rpi_linux_generated
5 |
6 | INC_DIR += $(PRG_DIR)
7 |
8 | SRC_C += dummies.c lx_emul.c
9 | SRC_C += $(notdir $(wildcard $(PRG_DIR)/generated_dummies.c))
10 |
11 | # lx_emul/initcall_order.h
12 | INC_DIR += $(REP_DIR)/src/include/spec/arm_v6
13 |
14 | LX_SRC_DIR := $(call select_from_ports,rpi_linux)/src/linux
15 | ifeq ($(wildcard $(LX_SRC_DIR)),)
16 | LX_SRC_DIR := $(call select_from_repositories,src/linux)
17 | endif
18 |
19 | LX_GEN_DIR := $(LIB_CACHE_DIR)/rpi_linux_generated
20 |
21 | include $(call select_from_repositories,lib/import/import-lx_emul_common.inc)
22 |
23 | INC_DIR += $(LX_SRC_DIR)/scripts/dtc/libfdt
24 |
25 | #
26 | # Additional Lx_emul + Lx_kit definitions
27 | #
28 |
29 | SRC_CC += lx_emul/clock.cc
30 | SRC_CC += lx_emul/io_mem.cc
31 | SRC_CC += lx_emul/io_port.cc
32 | SRC_CC += lx_emul/irq.cc
33 | SRC_C += lx_emul/shadow/kernel/dma/mapping.c
34 | SRC_C += lx_emul/shadow/kernel/irq/spurious.c
35 | SRC_C += lx_emul/shadow/kernel/rcu/srcutree.c
36 | SRC_C += lx_emul/shadow/lib/devres.c
37 | SRC_C += lx_emul/shadow/lib/smp_processor_id.c
38 | SRC_C += lx_emul/shadow/mm/memblock.c
39 | SRC_C += lx_emul/shadow/mm/page_alloc.c
40 | SRC_C += lx_emul/shadow/mm/slab_common.c
41 | SRC_C += lx_emul/shadow/mm/slub.c
42 | SRC_CC += lx_kit/device.cc
43 | SRC_CC += lx_kit/memory_dma.cc
44 |
45 | #
46 | # Generate driver-specific device-tree binary data
47 | #
48 | # The rules below use the tool/dts/extract tool to generate a device tree
49 | # containing the driver parameters for a given board.
50 | #
51 | # The resulting dtb file is named -.dtb
52 | #
53 |
54 | DTS_PATH(rpi) := arch/arm/boot/dts/bcm2708-rpi-b.dts
55 |
56 | CUSTOM_TARGET_DEPS += $(addprefix $(INSTALL_DIR)/$(DRIVER)-,$(addsuffix .dtb,$(BOARDS)))
57 |
58 | $(INSTALL_DIR)/%.dtb: %.dtb
59 | $(VERBOSE)cp -f $< $@
60 |
61 | %.dtb: %.dts
62 | $(VERBOSE)dtc -Idts $< > $@
63 |
64 | # dependencies of driver-specifc dts files from board's dts files
65 | $(foreach B,$(BOARDS),$(eval $(DRIVER)-$B.dts: $(LX_SRC_DIR)/${DTS_PATH($B)}))
66 |
67 | # dependencies of driver-specifc dts files from target-description files
68 | $(foreach B,$(BOARDS),$(eval $(DRIVER)-$B.dts: $(MAKEFILE_LIST)))
69 |
70 | $(DRIVER)-%.dts:
71 | $(VERBOSE)$(CROSS_DEV_PREFIX)cpp -I$(LX_SRC_DIR)/include \
72 | -x assembler-with-cpp -MMD -P $(LX_SRC_DIR)/${DTS_PATH($*)} |\
73 | $(BASE_DIR)/../../tool/dts/extract ${DTS_EXTRACT($*)} - |\
74 | grep -v "/omit-if-no-ref/" > $@
75 |
76 | #
77 | # Declare driver target and dtb files as build artifacts
78 | #
79 | BUILD_ARTIFACTS := $(TARGET) $(addprefix $(DRIVER)-,$(addsuffix .dtb,$(BOARDS)))
80 |
--------------------------------------------------------------------------------
/lib/mk/rpi_lx_emul.mk:
--------------------------------------------------------------------------------
1 | # the rpi_lx_emul libray exists only for the import file
2 |
--------------------------------------------------------------------------------
/lib/mk/spec/arm_v6/bootstrap-hw-rpi.mk:
--------------------------------------------------------------------------------
1 | REQUIRES = hw
2 |
3 | REP_INC_DIR += src/bootstrap/board/rpi
4 |
5 | SRC_CC += bootstrap/platform_cpu_memory_area.cc
6 | SRC_CC += board/rpi/platform.cc
7 | SRC_CC += bootstrap/spec/arm/arm_v6_cpu.cc
8 | SRC_S += bootstrap/spec/arm/crt0.s
9 |
10 | vpath board/rpi/platform.cc $(REP_DIR)/src/bootstrap
11 |
12 | CC_MARCH = -march=armv6k+nofp -mfpu=vfp
13 |
14 | ARCH_WIDTH_PATH := spec/32bit
15 |
16 | include $(call select_from_repositories,lib/mk/bootstrap-hw.inc)
17 |
--------------------------------------------------------------------------------
/lib/mk/spec/arm_v6/core-hw-rpi.mk:
--------------------------------------------------------------------------------
1 | #
2 | # \brief Build config for Genodes core process
3 | # \author Norman Feske
4 | # \date 2013-04-05
5 | #
6 |
7 | REQUIRES = hw
8 |
9 | # add include paths
10 | REP_INC_DIR += src/core/board/rpi
11 | REP_INC_DIR += src/core/spec/arm_v6
12 |
13 | # add C++ sources
14 | SRC_CC += kernel/cpu_up.cc
15 | SRC_CC += kernel/mutex.cc
16 | SRC_CC += kernel/vcpu_thread_off.cc
17 | SRC_CC += platform_services.cc
18 | SRC_CC += spec/arm/bcm2835_pic.cc
19 | SRC_CC += spec/arm/system_timer.cc
20 | SRC_CC += spec/arm_v6/perf_counter.cc
21 |
22 | SRC_S += spec/arm/vfpv2.s
23 |
24 | vpath spec/arm/%.cc $(REP_DIR)/src/core
25 |
26 | # include less specific configuration
27 | include $(call select_from_repositories,lib/mk/spec/arm/core-hw.inc)
28 |
--------------------------------------------------------------------------------
/lib/mk/spec/arm_v6/rpi_linux_generated.mk:
--------------------------------------------------------------------------------
1 | CUSTOM_TARGET_DEPS := kernel_build.phony
2 |
3 | LX_DIR := $(call select_from_ports,rpi_linux)/src/linux
4 | PWD := $(shell pwd)
5 |
6 | LX_MK_ARGS = ARCH=arm CROSS_COMPILE=$(CROSS_DEV_PREFIX)
7 |
8 | #
9 | # Linux kernel configuration
10 | #
11 |
12 | # define 'LX_ENABLE' and 'LX_DISABLE'
13 | include $(REP_DIR)/src/rpi_linux/arm_v6/target.inc
14 |
15 | # filter for make output of kernel build system
16 | BUILD_OUTPUT_FILTER = 2>&1 | sed "s/^/ [Linux] /"
17 |
18 | # do not confuse third-party sub-makes
19 | unexport .SHELLFLAGS
20 |
21 | kernel_config.tag:
22 | $(MSG_CONFIG)Linux
23 | $(VERBOSE)$(MAKE) -C $(LX_DIR) O=$(PWD) $(LX_MK_ARGS) tinyconfig $(BUILD_OUTPUT_FILTER)
24 | $(VERBOSE)$(LX_DIR)/scripts/config $(addprefix --enable ,$(LX_ENABLE))
25 | $(VERBOSE)$(LX_DIR)/scripts/config $(addprefix --disable ,$(LX_DISABLE))
26 | $(VERBOSE)$(MAKE) $(LX_MK_ARGS) olddefconfig $(BUILD_OUTPUT_FILTER)
27 | $(VERBOSE)$(MAKE) $(LX_MK_ARGS) prepare $(BUILD_OUTPUT_FILTER)
28 | $(VERBOSE)touch $@
29 |
30 | # update Linux kernel config on makefile changes
31 | kernel_config.tag: $(MAKEFILE_LIST)
32 |
33 | kernel_build.phony: kernel_config.tag
34 |
--------------------------------------------------------------------------------
/lib/mk/spec/arm_v8/bootstrap-hw-rpi3.mk:
--------------------------------------------------------------------------------
1 | REQUIRES = hw
2 |
3 | REP_INC_DIR += src/bootstrap/board/rpi3
4 |
5 | SRC_CC += board/rpi3/platform.cc
6 | SRC_CC += bootstrap/spec/arm_64/cortex_a53_mmu.cc
7 |
8 | vpath board/rpi3/%.cc $(REP_DIR)/src/bootstrap
9 |
10 | include $(call select_from_repositories,lib/mk/spec/arm_v8/bootstrap-hw.inc)
11 |
--------------------------------------------------------------------------------
/lib/mk/spec/arm_v8/core-hw-rpi3.mk:
--------------------------------------------------------------------------------
1 | REQUIRES = hw
2 |
3 | REP_INC_DIR += src/core/board/rpi3
4 |
5 | # add C++ sources
6 | SRC_CC += spec/arm/bcm2835_pic.cc
7 | SRC_CC += spec/arm/bcm2837_pic.cc
8 | SRC_CC += kernel/vcpu_thread_off.cc
9 | SRC_CC += platform_services.cc
10 |
11 | vpath spec/arm/%.cc $(REP_DIR)/src/core
12 |
13 | # include less specific configuration
14 | include $(call select_from_repositories,lib/mk/spec/arm_v8/core-hw.inc)
15 |
--------------------------------------------------------------------------------
/ports/rpi_linux.hash:
--------------------------------------------------------------------------------
1 | 7d0db120b0edc2fb2312c0bfd65465961fbaffc3
2 |
--------------------------------------------------------------------------------
/ports/rpi_linux.port:
--------------------------------------------------------------------------------
1 | LICENSE := GPLv2
2 | VERSION := 6.1.37
3 | DOWNLOADS := rpi_linux.archive
4 |
5 | URL(rpi_linux) := https://github.com/raspberrypi/linux/tarball/bb592ec
6 | NAME(rpi_linux) := rpi_linux_6.1.37.tgz
7 | SHA(rpi_linux) := 7cd2cde79ae998dd35db10e0fd3fe087b86f475d80fe53b53677c2dbaed4fc69
8 | DIR(rpi_linux) := src/linux
9 |
10 | #
11 | # Patches
12 | #
13 | PATCHES += src/driver/usb_host/rpi/sof_irq_genode.patch
14 | PATCHES += src/driver/usb_host/rpi/fiq_fsm_disable.patch
15 | PATCHES += src/driver/usb_host/rpi/nyet_error_genode.patch
16 | PATCHES += src/driver/usb_host/rpi/split_trans_irq.patch
17 | PATCHES += src/driver/usb_host/rpi/clear_tt_buffers.patch
18 |
19 | PATCH_OPT(src/driver/usb_host/rpi/sof_irq_genode.patch) := -p1 -d${DIR(rpi_linux)}
20 | PATCH_OPT(src/driver/usb_host/rpi/fiq_fsm_disable.patch) := -p1 -d${DIR(rpi_linux)}
21 | PATCH_OPT(src/driver/usb_host/rpi/nyet_error_genode.patch) := -p1 -d${DIR(rpi_linux)}
22 | PATCH_OPT(src/driver/usb_host/rpi/split_trans_irq.patch) := -p1 -d${DIR(rpi_linux)}
23 | PATCH_OPT(src/driver/usb_host/rpi/clear_tt_buffers.patch) := -p1 -d${DIR(rpi_linux)}
24 |
--------------------------------------------------------------------------------
/recipes/api/rpi_linux/content.mk:
--------------------------------------------------------------------------------
1 | #
2 | # Content hosted in the dde_linux repository
3 | #
4 |
5 | MIRRORED_FROM_DDE_LINUX := src/lib/lx_emul \
6 | src/lib/lx_kit \
7 | src/include/lx_emul \
8 | src/include/lx_user \
9 | src/include/spec/arm_v6/lx_kit \
10 | src/include/lx_kit \
11 | lib/import/import-lx_emul_common.inc
12 |
13 | content: $(MIRRORED_FROM_DDE_LINUX)
14 | $(MIRRORED_FROM_DDE_LINUX):
15 | mkdir -p $(dir $@); cp -r $(GENODE_DIR)/repos/dde_linux/$@ $(dir $@)
16 |
17 |
18 | #
19 | # Content hosted in the rpi repository
20 | #
21 |
22 | MIRRORED_FROM_REP_DIR := lib/mk/rpi_lx_emul.mk \
23 | lib/mk/spec/arm_v6/rpi_linux_generated.mk \
24 | lib/import/import-rpi_lx_emul.mk \
25 | src/rpi_linux/arm_v6/target.inc \
26 |
27 | content: $(MIRRORED_FROM_REP_DIR)
28 | $(MIRRORED_FROM_REP_DIR):
29 | $(mirror_from_rep_dir)
30 |
31 |
32 | #
33 | # Content from the Linux source tree
34 | #
35 |
36 | PORT_DIR := $(call port_dir,$(REP_DIR)/ports/rpi_linux)
37 | LX_REL_DIR := src/linux
38 | LX_ABS_DIR := $(addsuffix /$(LX_REL_DIR),$(PORT_DIR))
39 |
40 | LX_FILES += $(shell cd $(LX_ABS_DIR); find -name "Kconfig*" -printf "%P\n")
41 |
42 | # add content listed in the repository's source.list or dep.list files
43 | LX_FILE_LISTS := $(shell find -H $(REP_DIR)/src -name dep.list -or -name source.list)
44 | LX_FILES += $(shell cat $(LX_FILE_LISTS))
45 | LX_FILES := $(sort $(LX_FILES))
46 | MIRRORED_FROM_PORT_DIR += $(addprefix $(LX_REL_DIR)/,$(LX_FILES))
47 |
48 | content: $(MIRRORED_FROM_PORT_DIR)
49 | $(MIRRORED_FROM_PORT_DIR):
50 | mkdir -p $(dir $@)
51 | cp -r $(addprefix $(PORT_DIR)/,$@) $@
52 |
53 | content: LICENSE
54 | LICENSE:
55 | cp $(PORT_DIR)/src/linux/COPYING $@
56 |
--------------------------------------------------------------------------------
/recipes/api/rpi_linux/hash:
--------------------------------------------------------------------------------
1 | 2025-05-26 af4476c15fde201534a5100516ce17bd0bfec943
2 |
--------------------------------------------------------------------------------
/recipes/api/rpi_mbox_session/content.mk:
--------------------------------------------------------------------------------
1 | content: include/rpi_mbox_session LICENSE
2 |
3 | include/rpi_mbox_session:
4 | $(mirror_from_rep_dir)
5 |
6 | LICENSE:
7 | cp $(GENODE_DIR)/LICENSE $@
8 |
--------------------------------------------------------------------------------
/recipes/api/rpi_mbox_session/hash:
--------------------------------------------------------------------------------
1 | 2023-04-27 3591e5af5adc3c6252f1ee5f6adbbfabf20622df
2 |
--------------------------------------------------------------------------------
/recipes/pkg/drivers_interactive-rpi/README:
--------------------------------------------------------------------------------
1 |
2 | Device drivers needed to run interactive
3 | scenarios on Raspberry Pi 1
4 |
--------------------------------------------------------------------------------
/recipes/pkg/drivers_interactive-rpi/archives:
--------------------------------------------------------------------------------
1 | _/raw/drivers_interactive-rpi
2 | _/raw/rpi-devices
3 | _/src/event_filter
4 | _/src/report_rom
5 | _/src/rpi_fb
6 | _/src/rpi_platform
7 | _/src/usb_hid
8 | _/src/rpi_usb_host
9 |
--------------------------------------------------------------------------------
/recipes/pkg/drivers_interactive-rpi/hash:
--------------------------------------------------------------------------------
1 | 2025-05-26 61536d1ee825b42f4189c9fbfcc9279f1d647af5
2 |
--------------------------------------------------------------------------------
/recipes/pkg/drivers_nic-rpi/README:
--------------------------------------------------------------------------------
1 |
2 | Device drivers needed for scenarios
3 | using one network interface
4 |
--------------------------------------------------------------------------------
/recipes/pkg/drivers_nic-rpi/archives:
--------------------------------------------------------------------------------
1 | _/src/rpi_platform
2 | _/src/rpi_usb_host
3 | _/src/usb_net
4 | _/raw/drivers_nic-rpi
5 | _/raw/rpi-devices
6 |
--------------------------------------------------------------------------------
/recipes/pkg/drivers_nic-rpi/hash:
--------------------------------------------------------------------------------
1 | 2025-05-26 7f96c3ca275e1b7cc62e5fa93029c59cbf0cd833
2 |
--------------------------------------------------------------------------------
/recipes/pkg/test_usb_host-rpi/README:
--------------------------------------------------------------------------------
1 |
2 | Package for using the USB host driver in test-infrastructure
3 |
--------------------------------------------------------------------------------
/recipes/pkg/test_usb_host-rpi/archives:
--------------------------------------------------------------------------------
1 | _/raw/test_usb_host-rpi
2 | _/raw/rpi-devices
3 | _/src/rpi_usb_host
4 | _/src/rpi_platform
5 |
--------------------------------------------------------------------------------
/recipes/pkg/test_usb_host-rpi/hash:
--------------------------------------------------------------------------------
1 | 2025-05-26 069c06da3cbe9ffbb7dd6e2a878ab076dac1be8b
2 |
--------------------------------------------------------------------------------
/recipes/raw/drivers_interactive-rpi/content.mk:
--------------------------------------------------------------------------------
1 | content: drivers.config fb.config event_filter.config en_us.chargen special.chargen
2 |
3 | drivers.config fb.config event_filter.config:
4 | cp $(REP_DIR)/recipes/raw/drivers_interactive-rpi/$@ $@
5 |
6 | en_us.chargen special.chargen:
7 | cp $(GENODE_DIR)/repos/os/src/server/event_filter/$@ $@
8 |
--------------------------------------------------------------------------------
/recipes/raw/drivers_interactive-rpi/drivers.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/recipes/raw/drivers_interactive-rpi/event_filter.config:
--------------------------------------------------------------------------------
1 |
2 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/recipes/raw/drivers_interactive-rpi/fb.config:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/recipes/raw/drivers_interactive-rpi/hash:
--------------------------------------------------------------------------------
1 | 2025-02-26 a9663c31d147a29f8ef7807572b9c570cb7241e3
2 |
--------------------------------------------------------------------------------
/recipes/raw/drivers_nic-rpi/content.mk:
--------------------------------------------------------------------------------
1 | content: drivers.config
2 |
3 | drivers.config:
4 | cp $(REP_DIR)/recipes/raw/drivers_nic-rpi/$@ $@
5 |
--------------------------------------------------------------------------------
/recipes/raw/drivers_nic-rpi/drivers.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/recipes/raw/drivers_nic-rpi/hash:
--------------------------------------------------------------------------------
1 | 2025-02-26 84a90652de233624b50069f6aab2ad1f45680e78
2 |
--------------------------------------------------------------------------------
/recipes/raw/rpi-devices/content.mk:
--------------------------------------------------------------------------------
1 | content: devices
2 |
3 | devices:
4 | cp $(REP_DIR)/board/rpi/$@ $@
5 |
--------------------------------------------------------------------------------
/recipes/raw/rpi-devices/hash:
--------------------------------------------------------------------------------
1 | 2023-07-13 cfd6cb1f3c4bc875e4d3398ff6bf1dd4f7c81c35
2 |
--------------------------------------------------------------------------------
/recipes/raw/test_usb_host-rpi/content.mk:
--------------------------------------------------------------------------------
1 | content: drivers.config
2 |
3 | drivers.config:
4 | cp $(REP_DIR)/recipes/raw/test_usb_host-rpi/$@ $@
5 |
--------------------------------------------------------------------------------
/recipes/raw/test_usb_host-rpi/drivers.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/recipes/raw/test_usb_host-rpi/hash:
--------------------------------------------------------------------------------
1 | 2025-02-26 d9c96e28d979717894b4711ae17a94dc9db58b85
2 |
--------------------------------------------------------------------------------
/recipes/src/base-hw-rpi/content.mk:
--------------------------------------------------------------------------------
1 | include $(GENODE_DIR)/repos/base-hw/recipes/src/base-hw_content.inc
2 |
--------------------------------------------------------------------------------
/recipes/src/base-hw-rpi/hash:
--------------------------------------------------------------------------------
1 | 2025-05-26 3777b075e937a75645beb12a0cd57a76bc4bc960
2 |
--------------------------------------------------------------------------------
/recipes/src/base-hw-rpi/used_apis:
--------------------------------------------------------------------------------
1 | base-hw
2 | base
3 |
--------------------------------------------------------------------------------
/recipes/src/base-hw-rpi3/content.mk:
--------------------------------------------------------------------------------
1 | include $(GENODE_DIR)/repos/base-hw/recipes/src/base-hw_content.inc
2 |
--------------------------------------------------------------------------------
/recipes/src/base-hw-rpi3/hash:
--------------------------------------------------------------------------------
1 | 2025-05-26 3f5d811bc95982d9b57fb8326f2438fd27fa0033
2 |
--------------------------------------------------------------------------------
/recipes/src/base-hw-rpi3/used_apis:
--------------------------------------------------------------------------------
1 | base-hw
2 | base
3 |
--------------------------------------------------------------------------------
/recipes/src/rpi_fb/content.mk:
--------------------------------------------------------------------------------
1 | SRC_DIR = src/driver/framebuffer/rpi
2 | include $(GENODE_DIR)/repos/base/recipes/src/content.inc
3 |
--------------------------------------------------------------------------------
/recipes/src/rpi_fb/hash:
--------------------------------------------------------------------------------
1 | 2025-05-26 182d344ce1a81c420bbdb6ed0338feaadb72902e
2 |
--------------------------------------------------------------------------------
/recipes/src/rpi_fb/used_apis:
--------------------------------------------------------------------------------
1 | base
2 | os
3 | blit
4 | capture_session
5 | rpi_mbox_session
6 |
--------------------------------------------------------------------------------
/recipes/src/rpi_platform/content.mk:
--------------------------------------------------------------------------------
1 | SRC_DIR = src/driver/platform/rpi
2 | include $(GENODE_DIR)/repos/os/recipes/src/platform/content.inc
3 |
--------------------------------------------------------------------------------
/recipes/src/rpi_platform/hash:
--------------------------------------------------------------------------------
1 | 2025-05-26 1766531049aa8f91706e69f29a083178896858db
2 |
--------------------------------------------------------------------------------
/recipes/src/rpi_platform/used_apis:
--------------------------------------------------------------------------------
1 | base
2 | os
3 | platform_session
4 | report_session
5 | rpi_mbox_session
6 |
--------------------------------------------------------------------------------
/recipes/src/rpi_usb_host/content.mk:
--------------------------------------------------------------------------------
1 | #
2 | # Specific driver portions
3 | #
4 |
5 | MIRROR_FROM_REP_DIR := src/include/spec/arm_v6/lx_emul \
6 | src/driver/usb_host/rpi
7 |
8 | #
9 | # Generic driver poritions from dde_linux and os
10 | #
11 | #
12 | MIRROR_FROM_OS_DIR := src/lib/genode_c_api/usb.cc
13 |
14 | DDE_LINUX_REP_DIR := $(GENODE_DIR)/repos/dde_linux
15 |
16 | content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_OS_DIR)
17 |
18 | $(MIRROR_FROM_REP_DIR):
19 | $(mirror_from_rep_dir)
20 |
21 | $(MIRROR_FROM_OS_DIR):
22 | mkdir -p $(dir $@)
23 | cp -r $(GENODE_DIR)/repos/os/$@ $@
24 |
25 | content: LICENSE
26 | LICENSE:
27 | ( echo "Linux is subject to GNU General Public License version 2, see:"; \
28 | echo "https://www.kernel.org/pub/linux/kernel/COPYING"; ) > $@
29 |
--------------------------------------------------------------------------------
/recipes/src/rpi_usb_host/hash:
--------------------------------------------------------------------------------
1 | 2025-05-26 3fc7c5897323dfde3478db8cf677c3d5400b44f9
2 |
--------------------------------------------------------------------------------
/recipes/src/rpi_usb_host/used_apis:
--------------------------------------------------------------------------------
1 | base
2 | genode_c_api
3 | os
4 | jitterentropy
5 | rpi_linux
6 | platform_session
7 | report_session
8 | timer_session
9 | usb_session
10 |
--------------------------------------------------------------------------------
/run/rpi1_framebuffer.run:
--------------------------------------------------------------------------------
1 | create_boot_directory
2 | import_from_depot [depot_user]/src/[base_src] \
3 | [depot_user]/src/rpi_platform \
4 | [depot_user]/src/rpi_fb \
5 | [depot_user]/src/init \
6 | [depot_user]/raw/rpi-devices
7 |
8 | build { server/event_dump test/framebuffer }
9 |
10 | install_config {
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | }
51 |
52 | build_boot_image [build_artifacts]
53 |
54 | run_genode_until forever
55 |
--------------------------------------------------------------------------------
/src/bootstrap/board/rpi/board.h:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Raspberry PI specific board definitions
3 | * \author Stefan Kalkowski
4 | * \date 2017-02-20
5 | */
6 |
7 | /*
8 | * Copyright (C) 2017 Genode Labs GmbH
9 | *
10 | * This file is part of the Genode OS framework, which is distributed
11 | * under the terms of the GNU Affero General Public License version 3.
12 | */
13 |
14 | #ifndef _SRC__BOOTSTRAP__SPEC__RPI__BOARD_H_
15 | #define _SRC__BOOTSTRAP__SPEC__RPI__BOARD_H_
16 |
17 | #include
18 | #include
19 | #include
20 |
21 | namespace Board { using namespace Hw::Rpi_board; }
22 |
23 |
24 | constexpr unsigned Hw::Page_table::Descriptor_base::_device_tex() { return 0; }
25 |
26 |
27 | constexpr bool Hw::Page_table::Descriptor_base::_smp() { return false; }
28 |
29 |
30 | void Hw::Page_table::_table_changed(unsigned long, unsigned long) { }
31 |
32 | #endif /* _SRC__BOOTSTRAP__SPEC__RPI__BOARD_H_ */
33 |
--------------------------------------------------------------------------------
/src/bootstrap/board/rpi/platform.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Platform implementations specific for base-hw and Raspberry Pi
3 | * \author Norman Feske
4 | * \author Stefan Kalkowski
5 | * \date 2013-04-05
6 | */
7 |
8 | /*
9 | * Copyright (C) 2013-2017 Genode Labs GmbH
10 | *
11 | * This file is part of the Genode OS framework, which is distributed
12 | * under the terms of the GNU Affero General Public License version 3.
13 | */
14 |
15 | #include
16 | #include
17 |
18 | using namespace Hw::Rpi_board;
19 |
20 |
21 | /**
22 | * Leave out the first page (being 0x0) from bootstraps RAM allocator,
23 | * some code does not feel happy with addresses being zero
24 | */
25 | Bootstrap::Platform::Board::Board()
26 | :
27 | early_ram_regions(Memory_region { RAM_0_BASE + 0x1000,
28 | RAM_0_SIZE - 0x1000 }),
29 | late_ram_regions(Memory_region { RAM_0_BASE, 0x1000 }),
30 | core_mmio(Memory_region { PL011_0_MMIO_BASE,
31 | PL011_0_MMIO_SIZE },
32 | Memory_region { SYSTEM_TIMER_MMIO_BASE,
33 | SYSTEM_TIMER_MMIO_SIZE },
34 | Memory_region { IRQ_CONTROLLER_BASE,
35 | IRQ_CONTROLLER_SIZE },
36 | Memory_region { USB_DWC_OTG_BASE,
37 | USB_DWC_OTG_SIZE })
38 | { }
39 |
40 |
41 | unsigned Bootstrap::Platform::enable_mmu()
42 | {
43 | using ::Board::Cpu;
44 |
45 | Cpu::Sctlr::init();
46 |
47 | Cpu::Cpsr::init();
48 |
49 | struct Ctr : Cpu::Ctr
50 | {
51 | struct P : Bitfield<23, 1> { }; /* page mapping restriction on */
52 | };
53 |
54 | /* check for mapping restrictions */
55 | assert(!Ctr::P::get(Cpu::Ctr::read()));
56 |
57 | /* invalidate TLB */
58 | Cpu::Tlbiall::write(0);
59 |
60 | /* address space ID to zero */
61 | Cpu::Cidr::write(0);
62 |
63 | /* do not use domains, but permission bits in table */
64 | Cpu::Dacr::write(Cpu::Dacr::D0::bits(1));
65 |
66 | Cpu::Ttbcr::write(1);
67 |
68 | Genode::addr_t table = (Genode::addr_t)core_pd->table_base;
69 | Cpu::Ttbr::access_t ttbr = Cpu::Ttbr::init(table);
70 | Cpu::Ttbr0::write(ttbr);
71 | Cpu::Ttbr1::write(ttbr);
72 |
73 | struct Sctlr : Cpu::Sctlr
74 | {
75 | struct U : Bitfield<22,1> { }; /* enable unaligned data access */
76 | struct Xp : Bitfield<23,1> { }; /* disable subpage AP bits */
77 | };
78 |
79 | Cpu::Sctlr::access_t sctlr = Cpu::Sctlr::read();
80 | Cpu::Sctlr::C::set(sctlr, 1);
81 | Cpu::Sctlr::I::set(sctlr, 1);
82 | Sctlr::U::set(sctlr, 1);
83 | Sctlr::Xp::set(sctlr, 1);
84 | Cpu::Sctlr::Z::set(sctlr, 1);
85 | Cpu::Sctlr::M::set(sctlr, 1);
86 | Cpu::Sctlr::write(sctlr);
87 |
88 | /* invalidate branch predictor */
89 | Cpu::Bpiall::write(0);
90 |
91 | return 0;
92 | }
93 |
--------------------------------------------------------------------------------
/src/bootstrap/board/rpi3/board.h:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Board driver for bootstrap
3 | * \author Stefan Kalkowski
4 | * \date 2019-05-10
5 | */
6 |
7 | /*
8 | * Copyright (C) 2019 Genode Labs GmbH
9 | *
10 | * This file is part of the Genode OS framework, which is distributed
11 | * under the terms of the GNU Affero General Public License version 3.
12 | */
13 |
14 | #ifndef _BOOTSTRAP__SPEC__RPI3__BOARD_H_
15 | #define _BOOTSTRAP__SPEC__RPI3__BOARD_H_
16 |
17 | #include
18 | #include
19 | #include
20 |
21 | namespace Board {
22 |
23 | using namespace Hw::Rpi3_board;
24 |
25 | struct Cpu : Hw::Arm_64_cpu
26 | {
27 | static void wake_up_all_cpus(void*);
28 | };
29 |
30 | struct Pic { }; /* dummy object */
31 | };
32 |
33 | #endif /* _BOOTSTRAP__SPEC__RPI3__BOARD_H_ */
34 |
--------------------------------------------------------------------------------
/src/bootstrap/board/rpi3/platform.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Platform implementations specific for base-hw and Raspberry Pi3
3 | * \author Stefan Kalkowski
4 | * \date 2019-05-11
5 | */
6 |
7 | /*
8 | * Copyright (C) 2019 Genode Labs GmbH
9 | *
10 | * This file is part of the Genode OS framework, which is distributed
11 | * under the terms of the GNU Affero General Public License version 3.
12 | */
13 |
14 | #include
15 |
16 | /**
17 | * Leave out the first page (being 0x0) from bootstraps RAM allocator,
18 | * some code does not feel happy with addresses being zero
19 | */
20 | Bootstrap::Platform::Board::Board()
21 | :
22 | early_ram_regions(Memory_region { ::Board::RAM_BASE + 0x1000,
23 | ::Board::RAM_SIZE - 0x1000 }),
24 | late_ram_regions(Memory_region { ::Board::RAM_BASE, 0x1000 }),
25 | core_mmio(Memory_region { ::Board::UART_BASE, ::Board::UART_SIZE },
26 | Memory_region { ::Board::LOCAL_IRQ_CONTROLLER_BASE,
27 | ::Board::LOCAL_IRQ_CONTROLLER_SIZE },
28 | Memory_region { ::Board::IRQ_CONTROLLER_BASE,
29 | ::Board::IRQ_CONTROLLER_SIZE },
30 | Memory_region { ::Board::USB_DWC_OTG_BASE,
31 | ::Board::USB_DWC_OTG_SIZE })
32 | { }
33 |
34 |
35 | extern unsigned int _crt0_qemu_start_secondary_cpus;
36 |
37 |
38 | void Board::Cpu::wake_up_all_cpus(void * ip)
39 | {
40 | /* start when in qemu */
41 | _crt0_qemu_start_secondary_cpus = 1;
42 |
43 | /*
44 | * Start on real hardware by setting ip at designated addresses
45 | */
46 |
47 | /**
48 | * Unfortunately GCC12 includes some heuristic, which
49 | * complains about memory address pointer declaration
50 | * like the below ones, if the address is below 4K
51 | */
52 | #pragma GCC diagnostic push
53 | #pragma GCC diagnostic ignored "-Warray-bounds"
54 | *((void * volatile *) 0xe0) = ip; /* cpu 1 */
55 | *((void * volatile *) 0xe8) = ip; /* cpu 2 */
56 | *((void * volatile *) 0xf0) = ip; /* cpu 3 */
57 | #pragma GCC diagnostic pop
58 |
59 | /* send event for both variants */
60 | asm volatile("dsb #15; sev");
61 | }
62 |
--------------------------------------------------------------------------------
/src/core/board/rpi/board.h:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Board driver for core
3 | * \author Martin Stein
4 | * \author Stefan Kalkowski
5 | * \date 2012-04-23
6 | */
7 |
8 | /*
9 | * Copyright (C) 2012-2017 Genode Labs GmbH
10 | *
11 | * This file is part of the Genode OS framework, which is distributed
12 | * under the terms of the GNU Affero General Public License version 3.
13 | */
14 |
15 | #ifndef _CORE__SPEC__RPI__BOARD_H_
16 | #define _CORE__SPEC__RPI__BOARD_H_
17 |
18 | /* base-hw internal includes */
19 | #include
20 |
21 | /* base-hw Core includes */
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | namespace Board {
28 | using namespace Hw::Rpi_board;
29 | class Pic : public Bcm2835_pic
30 | {
31 | using Bcm2835_pic::Bcm2835_pic;
32 | };
33 | };
34 |
35 | #endif /* _CORE__SPEC__RPI__BOARD_H_ */
36 |
--------------------------------------------------------------------------------
/src/core/board/rpi3/board.h:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Board driver for core
3 | * \author Stefan Kalkowski
4 | * \date 2019-05-10
5 | */
6 |
7 | /*
8 | * Copyright (C) 2019 Genode Labs GmbH
9 | *
10 | * This file is part of the Genode OS framework, which is distributed
11 | * under the terms of the GNU Affero General Public License version 3.
12 | */
13 |
14 | #ifndef _CORE__SPEC__RPI3__BOARD_H_
15 | #define _CORE__SPEC__RPI3__BOARD_H_
16 |
17 | /* base-hw internal includes */
18 | #include
19 |
20 | /* base-hw Core includes */
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | namespace Board {
27 |
28 | using namespace Hw::Rpi3_board;
29 | class Pic : public Bcm2837_pic
30 | {
31 | using Bcm2837_pic::Bcm2837_pic;
32 | };
33 |
34 | enum { TIMER_IRQ = 1 };
35 | };
36 |
37 | #endif /* _CORE__SPEC__RPI3__BOARD_H_ */
38 |
--------------------------------------------------------------------------------
/src/core/spec/arm/bcm2835_pic.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Pic implementation specific to Rpi 1
3 | * \author Norman Feske
4 | * \author Stefan Kalkowski
5 | * \date 2016-01-07
6 | */
7 |
8 | /*
9 | * Copyright (C) 2016-2017 Genode Labs GmbH
10 | *
11 | * This file is part of the Genode OS framework, which is distributed
12 | * under the terms of the GNU Affero General Public License version 3.
13 | */
14 |
15 | #include
16 | #include
17 |
18 | using namespace Core;
19 |
20 |
21 | bool Board::Bcm2835_pic::Usb_dwc_otg::_need_trigger_sof(uint32_t host_frame,
22 | uint32_t scheduled_frame)
23 | {
24 | uint32_t const max_frame = 0x3fff;
25 |
26 | if (host_frame < scheduled_frame) {
27 | if (scheduled_frame - host_frame < max_frame / 2)
28 | return false; /* scheduled frame not reached yet */
29 | else
30 | return true; /* scheduled frame passed, host frame wrapped */
31 | } else {
32 | if (host_frame - scheduled_frame < max_frame / 2)
33 | return true; /* scheduled frame passed */
34 | else
35 | return false; /* scheduled frame wrapped, not reached */
36 | }
37 | }
38 |
39 |
40 | Board::Bcm2835_pic::
41 | Usb_dwc_otg::Usb_dwc_otg(Global_interrupt_controller &global_irq_ctrl)
42 | :
43 | Mmio { {(char *)Platform::mmio_to_virt(Board::USB_DWC_OTG_BASE), Board::USB_DWC_OTG_SIZE} },
44 | _global_irq_ctrl { global_irq_ctrl }
45 | {
46 | write(0);
47 | write(false);
48 | write(false);
49 | }
50 |
51 |
52 | bool Board::Bcm2835_pic::Usb_dwc_otg::handle_sof()
53 | {
54 | if (!_is_sof())
55 | return false;
56 |
57 | if (_global_irq_ctrl.increment_and_return_sof_cnt() == 8*20) {
58 | _global_irq_ctrl.reset_sof_cnt();
59 | return false;
60 | }
61 |
62 | if (!read() || read())
63 | return false;
64 |
65 | if (_need_trigger_sof(read(),
66 | read()))
67 | return false;
68 |
69 | write(1);
70 |
71 | return true;
72 | }
73 |
74 |
75 | Board::Bcm2835_pic::Bcm2835_pic(Global_interrupt_controller &global_irq_ctrl,
76 | Byte_range_ptr const &irq_ctrl)
77 | :
78 | Mmio({(char *)Platform::mmio_to_virt(irq_ctrl.start != nullptr ? (Genode::addr_t)irq_ctrl.start : (Genode::addr_t)Board::IRQ_CONTROLLER_BASE),
79 | irq_ctrl.start != nullptr ? irq_ctrl.num_bytes : (Genode::size_t)Board::IRQ_CONTROLLER_SIZE}),
80 | _usb { global_irq_ctrl }
81 | {
82 | mask();
83 | }
84 |
85 |
86 | bool Board::Bcm2835_pic::take_request(unsigned &irq)
87 | {
88 | /* read GPU IRQ status mask */
89 | uint32_t const p1 = read(),
90 | p2 = read();
91 |
92 | /* search for lowest set bit in pending masks */
93 | for (unsigned i = 0; i < NR_OF_IRQ; i++) {
94 |
95 | if (!_is_pending(i, p1, p2))
96 | continue;
97 |
98 | irq = i;
99 |
100 | /* handle SOF interrupts locally, filter from the user land */
101 | if (irq == Board::DWC_IRQ)
102 | if (_usb.handle_sof())
103 | return false;
104 |
105 | return true;
106 | }
107 |
108 | return false;
109 | }
110 |
111 |
112 | void Board::Bcm2835_pic::mask()
113 | {
114 | write(~0);
115 | write(~0);
116 | write(~0);
117 | }
118 |
119 |
120 | void Board::Bcm2835_pic::unmask(unsigned const i, unsigned)
121 | {
122 | if (i < 32) { write(1 << i); }
123 | else { write(1 << (i - 32)); }
124 | }
125 |
126 |
127 | void Board::Bcm2835_pic::mask(unsigned const i)
128 | {
129 | if (i < 32) { write(1 << i); }
130 | else { write(1 << (i - 32)); }
131 | }
132 |
133 |
134 | void Board::Bcm2835_pic::irq_mode(unsigned, unsigned, unsigned) { }
135 |
--------------------------------------------------------------------------------
/src/core/spec/arm/bcm2835_pic.h:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Programmable interrupt controller for core
3 | * \author Norman Feske
4 | * \date 2013-04-05
5 | */
6 |
7 | /*
8 | * Copyright (C) 2013-2017 Genode Labs GmbH
9 | *
10 | * This file is part of the Genode OS framework, which is distributed
11 | * under the terms of the GNU Affero General Public License version 3.
12 | */
13 |
14 | #ifndef _CORE__BCM2835__PIC_H_
15 | #define _CORE__BCM2835__PIC_H_
16 |
17 | /* Genode includes */
18 | #include
19 |
20 | namespace Board {
21 |
22 | class Global_interrupt_controller;
23 | class Bcm2835_pic;
24 | }
25 |
26 |
27 | class Board::Global_interrupt_controller
28 | {
29 | private:
30 |
31 | int _sof_cnt { 0 };
32 |
33 | public:
34 |
35 | void init() { }
36 |
37 | int increment_and_return_sof_cnt() { return ++_sof_cnt; }
38 |
39 | void reset_sof_cnt() { _sof_cnt = 0; }
40 | };
41 |
42 |
43 | class Board::Bcm2835_pic : Genode::Mmio<0x28>
44 | {
45 | public:
46 |
47 | enum {
48 | NR_OF_IRQ = 64,
49 |
50 | /*
51 | * dummy IPI value on non-SMP platform,
52 | * only used in interrupt reservation within generic code
53 | */
54 | IPI,
55 | };
56 |
57 | private:
58 |
59 | struct Irq_pending_basic : Register<0x0, 32>
60 | {
61 | struct Timer : Bitfield<0, 1> { };
62 | struct Gpu : Bitfield<8, 2> { };
63 | };
64 |
65 | struct Irq_pending_gpu_1 : Register<0x04, 32> { };
66 | struct Irq_pending_gpu_2 : Register<0x08, 32> { };
67 | struct Irq_enable_gpu_1 : Register<0x10, 32> { };
68 | struct Irq_enable_gpu_2 : Register<0x14, 32> { };
69 | struct Irq_enable_basic : Register<0x18, 32> { };
70 | struct Irq_disable_gpu_1 : Register<0x1c, 32> { };
71 | struct Irq_disable_gpu_2 : Register<0x20, 32> { };
72 | struct Irq_disable_basic : Register<0x24, 32> { };
73 |
74 | class Usb_dwc_otg : Genode::Mmio<0x40c>
75 | {
76 | private:
77 |
78 | struct Core_irq_status : Register<0x14, 32>
79 | {
80 | struct Sof : Bitfield<3, 1> { };
81 | };
82 |
83 | struct Guid : Register<0x3c, 32>
84 | {
85 | struct Num : Bitfield<0, 14> { };
86 |
87 | /*
88 | * The USB driver set 'Num' to a defined value
89 | */
90 | struct Num_valid : Bitfield<31, 1> { };
91 |
92 | /*
93 | * Filter is not used, overridden by the USB driver
94 | */
95 | struct Kick : Bitfield<30, 1> { };
96 | };
97 |
98 | struct Host_frame_number : Register<0x408, 32>
99 | {
100 | struct Num : Bitfield<0, 14> { };
101 | };
102 |
103 | Global_interrupt_controller &_global_irq_ctrl;
104 |
105 | bool _is_sof() const
106 | {
107 | return read();
108 | }
109 |
110 | static bool _need_trigger_sof(Genode::uint32_t host_frame,
111 | Genode::uint32_t scheduled_frame);
112 |
113 | public:
114 |
115 | Usb_dwc_otg(Global_interrupt_controller &global_irq_ctrl);
116 |
117 | bool handle_sof();
118 | };
119 |
120 | Usb_dwc_otg _usb;
121 |
122 | /**
123 | * Return true if specified interrupt is pending
124 | */
125 | static bool _is_pending(unsigned i, Genode::uint32_t p1,
126 | Genode::uint32_t p2)
127 | {
128 | return i < 32 ? (p1 & (1 << i)) : (p2 & (1 << (i - 32)));
129 | }
130 |
131 | /*
132 | * Noncopyable
133 | */
134 | Bcm2835_pic(Bcm2835_pic const &);
135 | Bcm2835_pic &operator = (Bcm2835_pic const &);
136 |
137 | public:
138 |
139 | Bcm2835_pic(Global_interrupt_controller &global_irq_ctrl,
140 | Genode::Byte_range_ptr const &irq_ctrl = {nullptr, 0});
141 |
142 | bool take_request(unsigned &irq);
143 | void finish_request() { }
144 | void mask();
145 | void unmask(unsigned const i, unsigned);
146 | void mask(unsigned const i);
147 | void irq_mode(unsigned, unsigned, unsigned);
148 |
149 | static constexpr bool fast_interrupts() { return false; }
150 | };
151 |
152 | #endif /* _CORE__BCM2835__PIC_H_ */
153 |
--------------------------------------------------------------------------------
/src/core/spec/arm/bcm2837_pic.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Pic implementation specific to Rpi3
3 | * \author Stefan Kalkowski
4 | * \date 2019-05-27
5 | */
6 |
7 | /*
8 | * Copyright (C) 2019 Genode Labs GmbH
9 | *
10 | * This file is part of the Genode OS framework, which is distributed
11 | * under the terms of the GNU Affero General Public License version 3.
12 | */
13 |
14 | /* base-hw Core includes */
15 | #include
16 | #include
17 |
18 |
19 | Board::Bcm2837_pic::Bcm2837_pic(Global_interrupt_controller &global_irq_ctrl)
20 | :
21 | Mmio({(char *)Core::Platform::mmio_to_virt(Board::LOCAL_IRQ_CONTROLLER_BASE), Board::LOCAL_IRQ_CONTROLLER_SIZE}),
22 | _bcm2835_pic(global_irq_ctrl, {(char *)Board::IRQ_CONTROLLER_BASE, Board::IRQ_CONTROLLER_SIZE})
23 | { }
24 |
25 |
26 | bool Board::Bcm2837_pic::take_request(unsigned & irq)
27 | {
28 | unsigned cpu = Core::Cpu::executing_id();
29 | Core_irq_source<0>::access_t src = 0;
30 | switch (cpu) {
31 | case 0: src = read>(); break;
32 | case 1: src = read>(); break;
33 | case 2: src = read>(); break;
34 | case 3: src = read>(); break;
35 | }
36 |
37 | if ((1 << TIMER_IRQ) & src) {
38 | irq = TIMER_IRQ;
39 | return true;
40 | }
41 |
42 | if (0xf0 & src) {
43 | irq = IPI;
44 | switch (cpu) {
45 | case 0: write>(1); break;
46 | case 1: write>(1); break;
47 | case 2: write>(1); break;
48 | case 3: write>(1); break;
49 | }
50 | return true;
51 | }
52 |
53 | // Gpu interrupt
54 | if (cpu == 0 && Core_irq_source<0>::Gpu::get(src)) {
55 | auto result = _bcm2835_pic.take_request(irq);
56 | return result;
57 | }
58 |
59 | return false;
60 | }
61 |
62 |
63 | void Board::Bcm2837_pic::_timer_irq(unsigned cpu, bool enable)
64 | {
65 | unsigned v = enable ? 1 : 0;
66 | switch (cpu) {
67 | case 0:
68 | write::Cnt_p_ns_irq>(v);
69 | return;
70 | case 1:
71 | write::Cnt_p_ns_irq>(v);
72 | return;
73 | case 2:
74 | write::Cnt_p_ns_irq>(v);
75 | return;
76 | case 3:
77 | write::Cnt_p_ns_irq>(v);
78 | return;
79 | default: ;
80 | }
81 | }
82 |
83 |
84 | void Board::Bcm2837_pic::_ipi(unsigned cpu, bool enable)
85 | {
86 | unsigned v = enable ? 1 : 0;
87 | switch (cpu) {
88 | case 0:
89 | write>(v);
90 | return;
91 | case 1:
92 | write>(v);
93 | return;
94 | case 2:
95 | write>(v);
96 | return;
97 | case 3:
98 | write>(v);
99 | return;
100 | default: ;
101 | }
102 | }
103 |
104 |
105 | void Board::Bcm2837_pic::unmask(unsigned const i, unsigned cpu)
106 | {
107 | switch (i) {
108 | case TIMER_IRQ: _timer_irq(cpu, true); return;
109 | case IPI: _ipi(cpu, true); return;
110 | }
111 | if (cpu == 0) _bcm2835_pic.unmask(i, cpu);
112 | }
113 |
114 |
115 | void Board::Bcm2837_pic::mask(unsigned const i)
116 | {
117 | unsigned cpu = Core::Cpu::executing_id();
118 | switch (i) {
119 | case TIMER_IRQ: _timer_irq(cpu, false); return;
120 | case IPI: _ipi(cpu, false); return;
121 | }
122 | if (cpu == 0) _bcm2835_pic.mask(i);
123 | }
124 |
125 |
126 | void Board::Bcm2837_pic::irq_mode(unsigned, unsigned, unsigned) { }
127 |
128 |
129 | void Board::Bcm2837_pic::send_ipi(unsigned cpu_target)
130 | {
131 | switch (cpu_target) {
132 | case 0: write>(1); return;
133 | case 1: write>(1); return;
134 | case 2: write>(1); return;
135 | case 3: write>(1); return;
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/src/core/spec/arm/bcm2837_pic.h:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Programmable interrupt controller for core
3 | * \author Stefan Kalkowski
4 | * \date 2019-05-27
5 | */
6 |
7 | /*
8 | * Copyright (C) 2019 Genode Labs GmbH
9 | *
10 | * This file is part of the Genode OS framework, which is distributed
11 | * under the terms of the GNU Affero General Public License version 3.
12 | */
13 |
14 | #ifndef _CORE__BCM2837__PIC_H_
15 | #define _CORE__BCM2837__PIC_H_
16 |
17 | #include
18 |
19 | #include
20 |
21 | namespace Board {
22 |
23 | /* Global_interrupt_controller from Bcm2835_pic */
24 | class Bcm2837_pic;
25 | }
26 |
27 |
28 | class Board::Bcm2837_pic : Genode::Mmio<0xc0 + 3 * 0x10 + 4>
29 | {
30 | public:
31 |
32 | enum {
33 | IPI = 0,
34 | NR_OF_IRQ = 64,
35 | };
36 |
37 | private:
38 |
39 | template
40 | struct Core_timer_irq_control : Register<0x40+CPU_NUM*0x4, 32>
41 | {
42 | struct Cnt_p_ns_irq
43 | : Register<0x40+CPU_NUM*0x4, 32>::template Bitfield<1, 1> {};
44 | };
45 |
46 | template
47 | struct Core_mailbox_irq_control : Register<0x50+CPU_NUM*0x4, 32> {};
48 |
49 | template
50 | struct Core_irq_source : Register<0x60+CPU_NUM*0x4, 32> {
51 | struct CntPsIrq : Register<0x60+CPU_NUM*0x4, 32>::template Bitfield<0, 1> { };
52 | struct CntPnIrq : Register<0x60+CPU_NUM*0x4, 32>::template Bitfield<1, 1> { };
53 | struct CntHpIrq : Register<0x60+CPU_NUM*0x4, 32>::template Bitfield<2, 1> { };
54 | struct CntVIrq : Register<0x60+CPU_NUM*0x4, 32>::template Bitfield<3, 1> { };
55 | struct MBox0 : Register<0x60+CPU_NUM*0x4, 32>::template Bitfield<4, 1> { };
56 | struct MBox1 : Register<0x60+CPU_NUM*0x4, 32>::template Bitfield<5, 1> { };
57 | struct MBox2 : Register<0x60+CPU_NUM*0x4, 32>::template Bitfield<6, 1> { };
58 | struct MBox3 : Register<0x60+CPU_NUM*0x4, 32>::template Bitfield<7, 1> { };
59 | struct Gpu : Register<0x60+CPU_NUM*0x4, 32>::template Bitfield<8, 1> { };
60 | struct Pmu : Register<0x60+CPU_NUM*0x4, 32>::template Bitfield<9, 1> { };
61 | struct Axi : Register<0x60+CPU_NUM*0x4, 32>::template Bitfield<10, 1> { };
62 | struct Timer : Register<0x60+CPU_NUM*0x4, 32>::template Bitfield<11, 1> { };
63 | };
64 |
65 | template
66 | struct Core_mailbox_set : Register<0x80+CPU_NUM*0x10, 32> {};
67 |
68 | template
69 | struct Core_mailbox_clear : Register<0xc0+CPU_NUM*0x10, 32> {};
70 |
71 | void _ipi(unsigned cpu, bool enable);
72 | void _timer_irq(unsigned cpu, bool enable);
73 |
74 | Bcm2835_pic _bcm2835_pic;
75 |
76 | /*
77 | * Noncopyable
78 | */
79 | Bcm2837_pic(Bcm2837_pic const &);
80 | Bcm2837_pic &operator = (Bcm2837_pic const &);
81 |
82 | public:
83 |
84 | Bcm2837_pic(Global_interrupt_controller &);
85 |
86 | bool take_request(unsigned &irq);
87 | void finish_request() { }
88 | void unmask(unsigned const i, unsigned);
89 | void mask(unsigned const i);
90 | void irq_mode(unsigned, unsigned, unsigned);
91 | void send_ipi(unsigned);
92 |
93 | static constexpr bool fast_interrupts() { return false; }
94 | };
95 |
96 | #endif /* _CORE__BCM2837__PIC_H_ */
97 |
--------------------------------------------------------------------------------
/src/core/spec/arm/system_timer.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Timer implementation specific to BCM2835 System Timer
3 | * \author Norman Feske
4 | * \author Stefan Kalkowski
5 | * \author Martin Stein
6 | * \date 2016-01-07
7 | */
8 |
9 | /*
10 | * Copyright (C) 2016-2017 Genode Labs GmbH
11 | *
12 | * This file is part of the Genode OS framework, which is distributed
13 | * under the terms of the GNU Affero General Public License version 3.
14 | */
15 |
16 | /* core includes */
17 | #include
18 | #include
19 | #include
20 |
21 | using namespace Core;
22 | using namespace Kernel;
23 | using Device = Board::Timer;
24 |
25 |
26 | Genode::uint64_t Board::Timer::_counter() const
27 | {
28 | uint64_t const high = read();
29 | uint64_t const low = read();
30 |
31 | /* if higher counter value changed in between, re-read everything */
32 | return (high == (time_t)read())
33 | ? (high << 32U) | low : _counter();
34 | }
35 |
36 |
37 | Board::Timer::Timer(unsigned)
38 | :
39 | Mmio({(char *)Platform::mmio_to_virt(Board::SYSTEM_TIMER_MMIO_BASE), Board::SYSTEM_TIMER_MMIO_SIZE})
40 | { }
41 |
42 |
43 | void Timer::_start_one_shot(time_t const ticks)
44 | {
45 | /* ticks is guaranteed to be less than _max_value() resp. 4-byte */
46 | Device::Cnt_low::access_t off = (Device::Cnt_low::access_t)
47 | (ticks < 2 ? 2 : ticks);
48 | _device.write(1);
49 | _device.read();
50 | _device.write(_device.read() + off);
51 | }
52 |
53 |
54 | enum { TICS_PER_US = Board::SYSTEM_TIMER_CLOCK / 1000 / 1000 };
55 |
56 |
57 | time_t Timer::ticks_to_us(time_t const ticks) const {
58 | return ticks / TICS_PER_US; }
59 |
60 |
61 | time_t Timer::us_to_ticks(time_t const us) const {
62 | return us * TICS_PER_US; }
63 |
64 |
65 | time_t Timer::_max_value() const {
66 | return 0xffffffff; }
67 |
68 |
69 | time_t Timer::_duration() const { return _device._counter() - _time; }
70 |
71 |
72 | unsigned Timer::interrupt_id() const { return Board::SYSTEM_TIMER_IRQ; }
73 |
--------------------------------------------------------------------------------
/src/core/spec/arm/system_timer.h:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Timer driver for core
3 | * \author Norman Feske
4 | * \date 2013-04-05
5 | */
6 |
7 | /*
8 | * Copyright (C) 2013-2017 Genode Labs GmbH
9 | *
10 | * This file is part of the Kernel OS framework, which is distributed
11 | * under the terms of the GNU Affero General Public License version 3.
12 | */
13 |
14 | #ifndef _SRC__CORE__BCM2835__SYSTEM_TIMER_H_
15 | #define _SRC__CORE__BCM2835__SYSTEM_TIMER_H_
16 |
17 | /* Kernel includes */
18 | #include
19 |
20 | namespace Board { class Timer; }
21 |
22 |
23 | /**
24 | * Timer driver for core
25 | *
26 | * Timer channel 0 apparently doesn't work on the RPI, so we use channel 1
27 | */
28 | struct Board::Timer : Genode::Mmio<0x14>
29 | {
30 | struct Cnt_ctrl_status : Register<0x0, 32>
31 | {
32 | struct Irq_1 : Bitfield<1, 1> { };
33 | };
34 | struct Cnt_low : Register<0x4, 32> { };
35 | struct Cnt_high : Register<0x8, 32> { };
36 | struct Cnt_compare_1 : Register<0x10, 32> { };
37 |
38 | /* Returns 64-bit counter value out of both 32-bit registers */
39 | Genode::uint64_t _counter() const;
40 |
41 | Timer(unsigned);
42 |
43 | void init();
44 | };
45 |
46 | #endif /* _SRC__CORE__BCM2835__SYSTEM_TIMER_H_ */
47 |
--------------------------------------------------------------------------------
/src/driver/framebuffer/rpi/README:
--------------------------------------------------------------------------------
1 | If you find the red and blue color channels swapped, you may need to specify
2 | the option 'framebuffer_swap=1' in you Raspberry Pi's config.txt.
3 |
--------------------------------------------------------------------------------
/src/driver/framebuffer/rpi/main.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Framebuffer driver for Raspberry Pi
3 | * \author Norman Feske
4 | * \date 2013-09-14
5 | */
6 |
7 | /*
8 | * Copyright (C) 2013-2017 Genode Labs GmbH
9 | *
10 | * This file is part of the Genode OS framework, which is distributed
11 | * under the terms of the GNU Affero General Public License version 3.
12 | */
13 |
14 | /* Genode includes */
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 |
25 | namespace Framebuffer { struct Main; };
26 |
27 | using namespace Genode;
28 |
29 |
30 | /**
31 | * The blit library is not free of potential mis-aligned pointer access,
32 | * which is not a problem with normal memory. But the Rpi framebuffer driver
33 | * uses ordered I/O memory as backend, where mis-aligned memory access is a problem.
34 | * Therefore, we do not use the blit library here, but implement a simple
35 | * blit function ourselves.
36 | */
37 | extern "C" void blit(void const * s, unsigned src_w,
38 | void * d, unsigned dst_w, int w, int h)
39 | {
40 | char const *src = (char const *)s;
41 | char *dst = (char *)d;
42 |
43 | if (w <= 0 || h <= 0) return;
44 |
45 | for (; h--; src += (src_w-w), dst += (dst_w-w))
46 | for (int i = (w >> 2); i--; src += 4, dst += 4)
47 | *(uint32_t *)dst = *(uint32_t const *)src;
48 | }
49 |
50 |
51 | struct Framebuffer::Main
52 | {
53 | using Area = Capture::Area;
54 | using Pixel = Capture::Pixel;
55 |
56 | Env &_env;
57 |
58 | Attached_rom_dataspace _config { _env, "config" };
59 |
60 | Rpi_mbox::Connection _rpi_mbox { _env };
61 |
62 | Area const _size { 1024, 768 };
63 |
64 | Rpi_mbox::Framebuffer_info _fb_info { _size.w, _size.h, 32 };
65 |
66 | bool const _fb_initialized = ( _rpi_mbox.setup_framebuffer(_fb_info), true );
67 |
68 | Attached_io_mem_dataspace _fb_ds { _env, _fb_info.addr, _fb_info.size };
69 |
70 | Capture::Connection _capture { _env };
71 |
72 | Capture::Connection::Screen _captured_screen {
73 | _capture, _env.rm(), { .px = _size,
74 | .mm = { },
75 | .viewport = { { }, _size },
76 | .rotate = { },
77 | .flip = { } } };
78 |
79 | Timer::Connection _timer { _env };
80 |
81 | Signal_handler _timer_handler { _env.ep(), *this, &Main::_handle_timer };
82 |
83 | void _handle_timer()
84 | {
85 | Area const phys_size { _fb_info.phys_width, _fb_info.phys_height };
86 |
87 | Surface surface(_fb_ds.local_addr(), phys_size);
88 |
89 | _captured_screen.apply_to_surface(surface);
90 | }
91 |
92 | Main(Genode::Env &env) : _env(env)
93 | {
94 | log("--- rpi_fb started ---");
95 |
96 | _timer.sigh(_timer_handler);
97 | _timer.trigger_periodic(10*1000);
98 | }
99 | };
100 |
101 |
102 | void Component::construct(Genode::Env &env)
103 | {
104 | static Framebuffer::Main main(env);
105 | }
106 |
--------------------------------------------------------------------------------
/src/driver/framebuffer/rpi/target.mk:
--------------------------------------------------------------------------------
1 | TARGET = rpi_fb
2 | SRC_CC = main.cc
3 | LIBS = base
4 | INC_DIR += $(PRG_DIR)
5 |
--------------------------------------------------------------------------------
/src/driver/platform/rpi/main.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Platform driver for Raspberry Pi
3 | * \author Stefan Kalkowski
4 | * \date 2020-04-12
5 | */
6 |
7 | /*
8 | * Copyright (C) 2020 Genode Labs GmbH
9 | *
10 | * This file is part of the Genode OS framework, which is distributed
11 | * under the terms of the GNU Affero General Public License version 3.
12 | */
13 |
14 | #include
15 | #include
16 | #include
17 | #include
18 |
19 | namespace Driver { struct Main; };
20 |
21 | struct Driver::Main
22 | {
23 | Env & _env;
24 | Attached_rom_dataspace _config_rom { _env, "config" };
25 | Signal_handler _config_handler { _env.ep(), *this,
26 | &Main::_handle_config };
27 | Common _common { _env, _config_rom };
28 |
29 | Constructible _mbox { };
30 | Constructible _mbox_root { };
31 | Constructible _power_domains { };
32 |
33 | void _handle_config();
34 |
35 | Main(Genode::Env & env);
36 | };
37 |
38 |
39 | void Driver::Main::_handle_config()
40 | {
41 | _config_rom.update();
42 | _common.handle_config(_config_rom.xml());
43 | }
44 |
45 |
46 | Driver::Main::Main(Genode::Env & env)
47 | :
48 | _env(env)
49 | {
50 | _config_rom.sigh(_config_handler);
51 | _handle_config();
52 |
53 | /* construct firmware mailbox from device info */
54 | _common.devices().for_each([&] (Device & dev) {
55 | if (dev.type() != "broadcom-mbox")
56 | return;
57 | dev.for_each_io_mem([&] (unsigned, const Device::Io_mem::Range &io_mem_range,
58 | const Driver::Device::Pci_bar&, bool) {
59 | if (!_mbox.constructed()) _mbox.construct(env, io_mem_range); });
60 | });
61 |
62 | if (!_mbox.constructed()) {
63 | error("Failed to find broadcom-mbox device in configuration!");
64 | return;
65 | }
66 |
67 | _power_domains.construct(_common.devices().powers(), *_mbox);
68 | _mbox_root.construct(_env, _common.heap(), *_mbox);
69 |
70 | _env.parent().announce(_env.ep().manage(*_mbox_root));
71 | _common.announce_service();
72 | }
73 |
74 |
75 | void Component::construct(Genode::Env &env) {
76 | static Driver::Main main(env); }
77 |
--------------------------------------------------------------------------------
/src/driver/platform/rpi/mbox.h:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Mbox for communicating between Videocore and ARM
3 | * \author Norman Feske
4 | * \date 2013-09-14
5 | */
6 |
7 | /*
8 | * Copyright (C) 2013-2017 Genode Labs GmbH
9 | *
10 | * This file is part of the Genode OS framework, which is distributed
11 | * under the terms of the GNU Affero General Public License version 3.
12 | */
13 |
14 | #ifndef _DRIVERS__PLATFORM__SPEC__RPI__MBOX_H_
15 | #define _DRIVERS__PLATFORM__SPEC__RPI__MBOX_H_
16 |
17 | /* Genode includes */
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | class Mbox : Genode::Attached_mmio<0xbc>
29 | {
30 | private:
31 |
32 | Genode::Env &_env;
33 |
34 | enum { verbose = false };
35 |
36 | typedef Genode::addr_t addr_t;
37 | typedef Genode::uint32_t uint32_t;
38 | typedef Genode::Dataspace_client Dataspace_client;
39 |
40 | /* according to https://www.raspberrypi.org/forums/viewtopic.php?t=165529
41 | * write and read mailboxes have its own status registers; linux driver
42 | * does that too */
43 | struct Read : Register<0x80, 32> {
44 | struct Channel : Bitfield<0, 4> { };
45 | struct Value : Bitfield<4, 26> { };
46 | struct Cache_policy : Bitfield<30, 2> { };
47 | };
48 |
49 | struct ReadStatus : Register<0x98, 32>
50 | {
51 | struct Empty : Bitfield<30, 1> { };
52 | struct Full : Bitfield<31, 1> { };
53 | };
54 |
55 | struct Write : Register<0xa0, 32>
56 | {
57 | struct Channel : Bitfield<0, 4> { };
58 | struct Value : Bitfield<4, 26> { };
59 | struct Cache_policy : Bitfield<30, 2> { };
60 | };
61 |
62 | struct WriteStatus : Register<0xb8, 32>
63 | {
64 | struct Empty : Bitfield<30, 1> { };
65 | struct Full : Bitfield<31, 1> { };
66 | };
67 |
68 | enum { MSG_BUFFER_SIZE = 0x1000 };
69 | Genode::Attached_ram_dataspace _msg_buffer { _env.ram(), _env.rm(),
70 | MSG_BUFFER_SIZE,
71 | Genode::UNCACHED};
72 |
73 | addr_t const _msg_phys = { _env.pd().dma_addr(_msg_buffer.cap()) };
74 |
75 | struct Delayer : Mmio::Delayer
76 | {
77 | Timer::Connection timer;
78 | void usleep(Genode::uint64_t us) override { timer.usleep(us); }
79 |
80 | Delayer(Genode::Env &env) : timer(env) { }
81 | } _delayer { _env };
82 |
83 | template
84 | MESSAGE &_message()
85 | {
86 | return *_msg_buffer.local_addr();
87 | }
88 |
89 | public:
90 |
91 | using Range = Platform::Device_interface::Range;
92 |
93 | Mbox(Genode::Env &env, Range io_mem)
94 | : Attached_mmio(env, {(char *)io_mem.start, io_mem.size}), _env(env) { }
95 |
96 | /**
97 | * Return reference to typed message buffer
98 | */
99 | template
100 | MESSAGE &message(ARGS... args)
101 | {
102 | return *Genode::construct_at(_msg_buffer.local_addr(), args...);
103 | }
104 |
105 | template
106 | void call()
107 | {
108 | _message().finalize();
109 |
110 | if (verbose)
111 | _message().dump("Input");
112 |
113 | /* flush pending data in the read buffer */
114 | while (!read())
115 | read();
116 |
117 | try { wait_for(Attempts(500), Microseconds(1), _delayer,
118 | WriteStatus::Full::Equal(0)); }
119 | catch (Polling_timeout) {
120 | Genode::error("Mbox: timeout waiting for ready-to-write");
121 | return;
122 | }
123 |
124 | Write::access_t value = 0;
125 | Write::Channel:: set(value, MESSAGE::channel());
126 | Write::Value:: set(value, (uint32_t) _msg_phys >> Write::Value::SHIFT);
127 | Write::Cache_policy::set(value, MESSAGE::cache_policy());
128 | write(value);
129 |
130 | bool response_received = false;
131 | while (!response_received) {
132 | try { wait_for(Attempts(500), Microseconds(1), _delayer,
133 | ReadStatus::Empty::Equal(0)); }
134 | catch (Polling_timeout) {
135 | Genode::error("Mbox: timeout waiting for response");
136 | return;
137 | }
138 | Read::access_t response_value = read();
139 | uint32_t response_channel = Read::Channel::get(response_value);
140 | response_received = (response_channel == MESSAGE::channel());
141 | if (!response_received) {
142 | Genode::warning("Mbox: received response for channel ", response_channel,
143 | " but expected ", MESSAGE::channel(), ". Retrying");
144 | }
145 | }
146 |
147 | if (_message().code == MESSAGE::RESPONSE_ERROR)
148 | Genode::error("Mbox: response error");
149 |
150 | if (verbose)
151 | _message().dump("Output");
152 | }
153 | };
154 |
155 | #endif /* _DRIVERS__PLATFORM__SPEC__RPI__MBOX_H_ */
156 |
--------------------------------------------------------------------------------
/src/driver/platform/rpi/power_domains.h:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Platform driver for Raspberry Pi 1
3 | * \author Stefan Kalkowski
4 | * \date 2021-12-06
5 | */
6 |
7 | /*
8 | * Copyright (C) 2021 Genode Labs GmbH
9 | *
10 | * This file is part of the Genode OS framework, which is distributed
11 | * under the terms of the GNU Affero General Public License version 3.
12 | */
13 |
14 | #include
15 | #include
16 | #include
17 | #include
18 |
19 | namespace Driver { struct Power_domains; }
20 |
21 |
22 | struct Driver::Power_domains
23 | {
24 | struct Domain : Driver::Power
25 | {
26 | Mbox & mbox;
27 | unsigned const id;
28 |
29 | Domain(Powers & powers,
30 | Power::Name name,
31 | Mbox & mbox,
32 | unsigned id)
33 | :
34 | Power(powers, name), mbox(mbox), id(id) {}
35 |
36 | void _on() override
37 | {
38 | auto & msg = mbox.message();
39 | msg.append_no_response(id,
40 | true,
41 | true);
42 | mbox.call();
43 | }
44 |
45 | void _off() override
46 | {
47 | auto & msg = mbox.message();
48 | msg.append_no_response(id,
49 | false,
50 | true);
51 | mbox.call();
52 | }
53 | };
54 |
55 | Powers & powers;
56 | Mbox & mbox;
57 |
58 | Domain sdhci { powers, "sdhci", mbox, 0 };
59 | Domain uart_0 { powers, "uart_0", mbox, 1 };
60 | Domain uart_1 { powers, "uart_1", mbox, 2 };
61 | Domain usb { powers, "usb", mbox, 3 };
62 | Domain i2c_0 { powers, "i2c_0", mbox, 4 };
63 | Domain i2c_1 { powers, "i2c_1", mbox, 5 };
64 | Domain i2c_2 { powers, "i2c_2", mbox, 6 };
65 | Domain spi { powers, "spi", mbox, 7 };
66 | Domain ccp2tx { powers, "ccp2tx", mbox, 8 };
67 |
68 | Power_domains(Powers & powers, Mbox & mbox) : powers(powers), mbox(mbox) {}
69 | };
70 |
--------------------------------------------------------------------------------
/src/driver/platform/rpi/property_command.h:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Command definitions for the property mbox channel
3 | * \author Norman Feske
4 | * \date 2013-09-15
5 | */
6 |
7 | /*
8 | * Copyright (C) 2013-2017 Genode Labs GmbH
9 | *
10 | * This file is part of the Genode OS framework, which is distributed
11 | * under the terms of the GNU Affero General Public License version 3.
12 | */
13 |
14 | #ifndef _PROPERTY_COMMAND_H_
15 | #define _PROPERTY_COMMAND_H_
16 |
17 | /* Genode includes */
18 | #include
19 |
20 | namespace Property_command {
21 |
22 | using namespace Genode;
23 |
24 | struct Get_power_state
25 | {
26 | static uint32_t opcode() { return 0x00020001; };
27 |
28 | struct Request
29 | {
30 | uint32_t const device_id;
31 |
32 | Request(uint32_t device_id) : device_id(device_id) { }
33 | };
34 |
35 | struct Response
36 | {
37 | uint32_t const device_id = 0;
38 | uint32_t const state = 0;
39 | };
40 | };
41 |
42 | struct Set_power_state
43 | {
44 | static uint32_t opcode() { return 0x00028001; };
45 |
46 | struct Request
47 | {
48 | uint32_t const device_id;
49 | uint32_t const state;
50 |
51 | Request(uint32_t device_id, bool enable, bool wait)
52 | :
53 | device_id(device_id),
54 | state(enable | (wait << 1))
55 | { }
56 | };
57 |
58 | struct Response
59 | {
60 | uint32_t const device_id = 0;
61 | uint32_t const state = 0;
62 | };
63 | };
64 |
65 | struct Get_clock_rate
66 | {
67 | static uint32_t opcode() { return 0x00030002; };
68 |
69 | struct Request
70 | {
71 | uint32_t const clock_id;
72 |
73 | Request(uint32_t clock_id) : clock_id(clock_id) { }
74 | };
75 |
76 | struct Response
77 | {
78 | uint32_t const clock_id = 0;
79 | uint32_t const hz = 0;
80 | };
81 | };
82 |
83 | struct Allocate_buffer
84 | {
85 | static uint32_t opcode() { return 0x00040001; };
86 |
87 | struct Request
88 | {
89 | uint32_t const alignment = 0x100;
90 | };
91 |
92 | struct Response
93 | {
94 | uint32_t const address = 0;
95 | uint32_t const size = 0;
96 | };
97 | };
98 |
99 |
100 | struct Release_buffer
101 | {
102 | static uint32_t opcode() { return 0x00048001; };
103 | };
104 |
105 |
106 | struct Get_physical_w_h
107 | {
108 | static uint32_t opcode() { return 0x00040003; };
109 |
110 | struct Request
111 | {
112 | };
113 |
114 | struct Response
115 | {
116 | uint32_t const width = 0;
117 | uint32_t const height = 0;
118 | };
119 | };
120 |
121 |
122 | struct Set_physical_w_h
123 | {
124 | static uint32_t opcode() { return 0x00048003; };
125 |
126 | struct Request
127 | {
128 | uint32_t const width;
129 | uint32_t const height;
130 |
131 | Request(uint32_t width, uint32_t height)
132 | : width(width), height(height) { }
133 | };
134 |
135 | struct Response {};
136 | };
137 |
138 |
139 | struct Set_virtual_w_h
140 | {
141 | static uint32_t opcode() { return 0x00048004; };
142 |
143 | struct Request
144 | {
145 | uint32_t const width;
146 | uint32_t const height;
147 |
148 | Request(uint32_t width, uint32_t height)
149 | : width(width), height(height) { }
150 | };
151 |
152 | struct Response {};
153 | };
154 |
155 |
156 | struct Set_depth
157 | {
158 | static uint32_t opcode() { return 0x00048005; };
159 |
160 | struct Request
161 | {
162 | uint32_t const depth;
163 |
164 | Request(uint32_t depht)
165 | : depth(depht) { }
166 | };
167 |
168 | struct Response {};
169 | };
170 | }
171 |
172 | #endif /* _PROPERTY_COMMAND_H_ */
173 |
--------------------------------------------------------------------------------
/src/driver/platform/rpi/property_message.h:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Marshalling of mbox messages for property channel
3 | * \author Norman Feske
4 | * \date 2013-09-15
5 | */
6 |
7 | /*
8 | * Copyright (C) 2013-2017 Genode Labs GmbH
9 | *
10 | * This file is part of the Genode OS framework, which is distributed
11 | * under the terms of the GNU Affero General Public License version 3.
12 | */
13 |
14 | #ifndef _SRC__DRIVERS__PLATFORM__RPI__PROPERTY_MESSAGE_H_
15 | #define _SRC__DRIVERS__PLATFORM__RPI__PROPERTY_MESSAGE_H_
16 |
17 | /* Genode includes */
18 | #include
19 | #include
20 | #include
21 |
22 | namespace Driver {
23 | using namespace Genode;
24 | struct Property_message;
25 | }
26 |
27 |
28 | /**
29 | * Mailbox message buffer for the property channel
30 | *
31 | * This data structure is overlayed with memory shared with the VC. It
32 | * contains a header, followed by a sequence of so-called command tags, wrapped
33 | * up by a zero as an end marker.
34 | */
35 | struct Driver::Property_message
36 | {
37 | uint32_t buf_size = 0;
38 |
39 | enum Videocore_cache_policy { NON_COHERENT = 0,
40 | COHERENT = 1,
41 | L2_ONLY = 2,
42 | UNCACHED = 3 };
43 |
44 | enum Code { REQUEST = 0,
45 | RESPONSE_SUCCESS = 0x80000000,
46 | RESPONSE_ERROR = 0x80000001 };
47 |
48 | volatile Code code = REQUEST;
49 |
50 | /*
51 | * Start of the buffer that contains a sequence of tags
52 | */
53 | char buffer[0];
54 |
55 | /*
56 | * There must be no member variables after this point
57 | */
58 |
59 | /*
60 | * Each tag consists of a header, a part with request arguments, and a
61 | * part with responses.
62 | */
63 | template
64 | struct Tag
65 | {
66 | uint32_t const opcode;
67 |
68 | /**
69 | * Size of tag buffer
70 | */
71 | uint32_t const buf_size;
72 |
73 | /**
74 | * Size of request part of the tag
75 | *
76 | * The value is never changed locally. Therefore, it is declared as
77 | * const. However, it will be updated by the VC. So we declare it
78 | * volatile, too.
79 | */
80 | uint32_t volatile const len;
81 |
82 | char payload[0];
83 |
84 | /**
85 | * Utility for returning a response size of a tag type
86 | *
87 | * Depending on the presence of a 'TAG::Response' type, we need to
88 | * return the actual size of the response (if the type is present) or
89 | * 0. Both overloads are called with a compliant parameter 0. But only
90 | * if 'T::Response' exists, the first overload is selected.
91 | *
92 | * SFINAE to the rescue!
93 | */
94 | template
95 | static uint32_t response_size(typename T::Response *)
96 | {
97 | return sizeof(typename T::Response);
98 | }
99 |
100 | template
101 | static uint32_t response_size(...)
102 | {
103 | return 0;
104 | }
105 |
106 | template
107 | static uint32_t request_size(typename T::Request *)
108 | {
109 | return sizeof(typename T::Request);
110 | }
111 |
112 | template
113 | static uint32_t request_size(...)
114 | {
115 | return 0;
116 | }
117 |
118 | template
119 | void construct_request(typename T::Request *, ARGS... args)
120 | {
121 | construct_at(payload, args...);
122 | }
123 |
124 | template
125 | void construct_response(typename T::Response *)
126 | {
127 | construct_at(payload);
128 | }
129 |
130 | template
131 | void construct_response(...) { }
132 |
133 | static constexpr uint32_t payload_size()
134 | {
135 | return max(request_size(0), response_size(0));
136 | }
137 |
138 | template
139 | Tag(REQUEST_ARGS... request_args)
140 | :
141 | opcode(TAG::opcode()),
142 | buf_size(payload_size()),
143 | len(request_size(0))
144 | {
145 | /*
146 | * The order is important. If we called 'construct_response' after
147 | * 'construct_request', we would overwrite the request parameters
148 | * with the default response.
149 | */
150 | construct_response(0);
151 | construct_request(0, request_args...);
152 | }
153 | };
154 |
155 | void reset()
156 | {
157 | buf_size = 0;
158 | code = REQUEST;
159 | }
160 |
161 | /**
162 | * \return reference to tag in the message buffer
163 | */
164 | template
165 | typename POLICY::Response const &append(REQUEST_ARGS... request_args)
166 | {
167 | auto *tag = construct_at >(buffer + buf_size, request_args...);
168 |
169 | buf_size += (uint32_t) sizeof(Tag) + Tag::payload_size();
170 |
171 | return *(typename POLICY::Response *)tag->payload;
172 | }
173 |
174 | template
175 | void append_no_response(REQUEST_ARGS... request_args)
176 | {
177 | construct_at >(buffer + buf_size, request_args...);
178 |
179 | buf_size += (uint32_t) sizeof(Tag) + Tag::payload_size();
180 | }
181 |
182 | void finalize()
183 | {
184 | /* append end tag */
185 | *(uint32_t *)(buffer + buf_size) = 0;
186 | buf_size += 3 * sizeof(uint32_t); /* end tag, and header(buf_size and code) */
187 | }
188 |
189 | static unsigned channel() { return 8; }
190 |
191 | static Videocore_cache_policy cache_policy()
192 | {
193 | return UNCACHED;
194 | }
195 |
196 | void dump(char const *label)
197 | {
198 | unsigned const *buf = (unsigned *)this;
199 | log(label, " message:");
200 | for (unsigned i = 0;; i++) {
201 | for (unsigned j = 0; j < 8; j++) {
202 | unsigned const msg_word_idx = i*8 + j;
203 | log(" ", Hex(buf[msg_word_idx]));
204 | if (msg_word_idx*sizeof(unsigned) < buf_size)
205 | continue;
206 | return;
207 | }
208 | }
209 | }
210 | };
211 |
212 | #endif /* _SRC__DRIVERS__PLATFORM__RPI__PROPERTY_MESSAGE_H_ */
213 |
--------------------------------------------------------------------------------
/src/driver/platform/rpi/rpi_mbox_root.h:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Driver for Raspberry Pi specific mbox device
3 | * \author Tomasz Gajewski
4 | * \date 2021-11-13
5 | */
6 |
7 | /*
8 | * Copyright (C) 2021 Genode Labs GmbH
9 | *
10 | * This file is part of the Genode OS framework, which is distributed
11 | * under the terms of the GNU Affero General Public License version 3.
12 | */
13 |
14 | #ifndef _RPI_MBOX_ROOT_H_
15 | #define _RPI_MBOX_ROOT_H_
16 |
17 | /* Genode includes */
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 |
24 | /* rpi api includes */
25 | #include
26 |
27 | /* local includes */
28 | #include
29 | #include
30 | #include
31 |
32 |
33 | namespace Rpi_mbox {
34 | class Session_component;
35 | class Root;
36 | using Driver::Property_message;
37 | }
38 |
39 |
40 | class Rpi_mbox::Session_component : public Genode::Rpc_object
41 | {
42 | private:
43 |
44 | Mbox &_mbox;
45 |
46 | public:
47 |
48 | Session_component(Mbox &mbox) : _mbox(mbox) { }
49 |
50 |
51 | /**********************************
52 | ** Rpi_mbox session interface **
53 | **********************************/
54 |
55 | void setup_framebuffer(Framebuffer_info &info) override
56 | {
57 | {
58 | auto & msg = _mbox.message();
59 | msg.append();
60 | _mbox.call();
61 | }
62 |
63 | auto &msg = _mbox.message();
64 | msg.append(info.phys_width,
65 | info.phys_height);
66 | msg.append(info.virt_width,
67 | info.virt_height);
68 | msg.append(info.depth);
69 | auto const &res = msg.append();
70 | _mbox.call();
71 |
72 | /* FIXME: make a function for this */
73 | /* bus to phys memory translation */
74 | info.addr = res.address & ~0xC0000000;
75 | info.size = res.size;
76 | log("setup_framebuffer ", Genode::Hex(info.addr), ", ",
77 | info.size, ", ", info.phys_width, ", ", info.phys_height);
78 | }
79 | };
80 |
81 |
82 | class Rpi_mbox::Root :
83 | public Genode::Root_component
84 | {
85 | private:
86 |
87 | Mbox& _mbox;
88 |
89 | protected:
90 |
91 | Create_result _create_session(const char *) override {
92 | return *new (md_alloc()) Session_component(_mbox); }
93 |
94 | public:
95 |
96 | Root(Env& env, Allocator& md_alloc, Mbox& mbox)
97 | :
98 | Root_component(env.ep(), md_alloc),
99 | _mbox(mbox) { }
100 | };
101 |
102 | #endif /* _RPI_MBOX_ROOT_H_ */
103 |
--------------------------------------------------------------------------------
/src/driver/platform/rpi/target.mk:
--------------------------------------------------------------------------------
1 | TARGET = rpi_platform
2 | include $(call select_from_repositories,src/driver/platform/target.inc)
3 |
--------------------------------------------------------------------------------
/src/driver/uart/rpi3/target.mk:
--------------------------------------------------------------------------------
1 | TARGET = rpi3_uart
2 | REQUIRES = arm_v8a
3 |
4 | include $(call select_from_repositories,src/driver/uart/target.inc)
5 |
--------------------------------------------------------------------------------
/src/driver/uart/rpi3/uart_driver.h:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief RPI3 UART driver
3 | * \author Christian Helmuth
4 | * \author Stefan Kalkowski
5 | * \author Christian Prochaska
6 | * \date 2011-05-27
7 | */
8 |
9 | /*
10 | * Copyright (C) 2011-2023 Genode Labs GmbH
11 | *
12 | * This file is part of the Genode OS framework, which is distributed
13 | * under the terms of the GNU Affero General Public License version 3.
14 | */
15 |
16 | #ifndef _UART_DRIVER_H_
17 | #define _UART_DRIVER_H_
18 |
19 | /* Genode includes */
20 | #include
21 | #include
22 |
23 | enum { UARTS_NUM = 1 }; /* needed by base class definitions */
24 |
25 | /* local includes */
26 | #include
27 |
28 | class Uart::Driver : private Genode::Attached_io_mem_dataspace,
29 | public Uart::Driver_base
30 | {
31 | private:
32 |
33 | /*
34 | * Noncopyable
35 | */
36 | Driver(Driver const &);
37 | Driver &operator = (Driver const &);
38 |
39 | enum {
40 |
41 | /**
42 | * MMIO regions
43 | */
44 | PL011_PHYS0 = 0x3f201000, /* base for UART 0 */
45 | PL011_SIZE = 0x1000, /* size of each MMIO region */
46 |
47 | /**
48 | * Interrupt lines
49 | */
50 | PL011_IRQ0 = 57, /* UART 0 */
51 |
52 | /**
53 | * UART baud rate configuration (precalculated)
54 | *
55 | * div = 24000000 / 16 / baud rate
56 | * IBRD = floor(div)
57 | * FBRD = floor((div - IBRD) * 64 + 0.5)
58 | */
59 | PL011_IBRD_115200 = 13, PL011_FBRD_115200 = 1,
60 | PL011_IBRD_19200 = 78, PL011_FBRD_19200 = 8,
61 | PL011_IBRD_9600 = 156, PL011_FBRD_9600 = 16,
62 |
63 | BAUD_115200 = 115200
64 | };
65 |
66 | struct Uart {
67 | Genode::addr_t mmio_base;
68 | Genode::size_t mmio_size;
69 | int irq_number;
70 | };
71 |
72 | Uart & _config(unsigned index)
73 | {
74 | using namespace Genode;
75 |
76 | static Uart cfg[UARTS_NUM] = {
77 | { PL011_PHYS0, PL011_SIZE, PL011_IRQ0 },
78 | };
79 | return cfg[index];
80 | }
81 |
82 |
83 | /*
84 | * Constants for flags, registers, etc. only visible in this file are
85 | * named as in the specification documents to relieve correlation
86 | * between implementation and specification.
87 | */
88 |
89 | /**
90 | * Register offsets
91 | *
92 | * Registers are read/writeable unless explicitly stated.
93 | */
94 | enum Register {
95 | UARTDR = 0x000, /* data */
96 | UARTFR = 0x018, /* flags (read-only) */
97 | UARTIBRD = 0x024, /* integer baud rate divisor */
98 | UARTFBRD = 0x028, /* fractional baud rate divisor */
99 | UARTLCR_H = 0x02c, /* line control */
100 | UARTCR = 0x030, /* control */
101 | UARTIMSC = 0x038, /* interrupt mask register */
102 | UARTICR = 0x044, /* interrupt clear register */
103 | };
104 |
105 | /**
106 | * Flags
107 | */
108 | enum Flag {
109 | /* flag register */
110 | UARTFR_BUSY = 0x0008, /* busy on tx */
111 | UARTFR_TXFF = 0x0020, /* tx FIFO full */
112 | UARTFR_RXFE = 0x0010, /* rx FIFO empty */
113 |
114 | /* line control register */
115 | UARTLCR_H_FEN = 0x0010, /* enable FIFOs */
116 | UARTLCR_H_WLEN_8 = 0x0060, /* 8 bit word length */
117 |
118 | /* control register */
119 | UARTCR_UARTEN = 0x0001, /* enable uart */
120 | UARTCR_TXE = 0x0100, /* enable tx */
121 | UARTCR_RXE = 0x0200, /* enable rx */
122 |
123 | /* interrupt mask register */
124 | UARTIMSC_RXIM = 0x10, /* rx interrupt mask */
125 |
126 | /* interrupt clear register */
127 | UARTICR_RXIC = 0x10, /* rx interrupt clear */
128 | };
129 |
130 | Genode::uint32_t volatile *_base;
131 |
132 | Genode::uint32_t _read_reg(Register reg) const {
133 | return _base[reg >> 2]; }
134 |
135 | void _write_reg(Register reg, Genode::uint32_t v) {
136 | _base[reg >> 2] = v; }
137 |
138 | public:
139 |
140 | Driver(Genode::Env &env, unsigned index,
141 | unsigned baud_rate, Char_avail_functor &func)
142 | : Genode::Attached_io_mem_dataspace(env, _config(index).mmio_base,
143 | _config(index).mmio_size),
144 | Driver_base(env, _config(index).irq_number, func),
145 | _base(local_addr())
146 | {
147 | if (baud_rate != BAUD_115200)
148 | Genode::warning("baud_rate ", baud_rate,
149 | " not supported, set to default");
150 |
151 | /* disable and flush uart */
152 | _write_reg(UARTCR, 0);
153 | while (_read_reg(UARTFR) & UARTFR_BUSY) ;
154 | _write_reg(UARTLCR_H, 0);
155 |
156 | /* set baud-rate divisor */
157 | _write_reg(UARTIBRD, PL011_IBRD_115200);
158 | _write_reg(UARTFBRD, PL011_FBRD_115200);
159 |
160 | /* enable FIFOs, 8-bit words */
161 | _write_reg(UARTLCR_H, UARTLCR_H_FEN | UARTLCR_H_WLEN_8);
162 |
163 | /* enable transmission */
164 | _write_reg(UARTCR, UARTCR_TXE);
165 |
166 | /* enable uart */
167 | _write_reg(UARTCR, _read_reg(UARTCR) | UARTCR_UARTEN);
168 |
169 | /* enable rx interrupt */
170 | _write_reg(UARTIMSC, UARTIMSC_RXIM);
171 | }
172 |
173 |
174 | /***************************
175 | ** UART driver interface **
176 | ***************************/
177 |
178 | void handle_irq() override
179 | {
180 | /* inform client about the availability of data */
181 | Driver_base::handle_irq();
182 |
183 | /* acknowledge irq */
184 | _write_reg(UARTICR, UARTICR_RXIC);
185 | }
186 |
187 | void put_char(char c) override
188 | {
189 | /* spin while FIFO full */
190 | while (_read_reg(UARTFR) & UARTFR_TXFF) ;
191 |
192 | _write_reg(UARTDR, c);
193 | }
194 |
195 | bool char_avail() override {
196 | return !(_read_reg(UARTFR) & UARTFR_RXFE); }
197 |
198 | char get_char() override {
199 | return (char)_read_reg(UARTDR); }
200 | };
201 |
202 | #endif /* _UART_DRIVER_H_ */
203 |
--------------------------------------------------------------------------------
/src/driver/usb_host/rpi/README:
--------------------------------------------------------------------------------
1 | USB host controller driver for Raspberry Pi
2 | ===========================================
3 |
4 | Please have a look into the README of the PC USB host controller driver,
5 | which is equivalent with regard to configuration and semantic.
6 | You can find it within Genode's main repository under:
7 | `repos/pc/src/driver/usb_host/pc/README`.
8 |
--------------------------------------------------------------------------------
/src/driver/usb_host/rpi/asm-generic/preempt.h:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Shadow copy of asm-generic/preempt.h
3 | * \author Stefan Kalkowski
4 | * \date 2023-07-10
5 | */
6 |
7 | /*
8 | * Copyright (C) 2023 Genode Labs GmbH
9 | *
10 | * This file is distributed under the terms of the GNU General Public License
11 | * version 2.
12 | */
13 |
14 | #ifndef __ASM_PREEMPT_H
15 | #define __ASM_PREEMPT_H
16 |
17 | #include
18 |
19 | #define PREEMPT_ENABLED (0)
20 |
21 | static __always_inline int preempt_count(void)
22 | {
23 | return 0;
24 | }
25 |
26 | static __always_inline volatile int *preempt_count_ptr(void)
27 | {
28 | return NULL;
29 | }
30 |
31 | static __always_inline void preempt_count_set(int pc)
32 | {
33 | }
34 |
35 | /*
36 | * must be macros to avoid header recursion hell
37 | */
38 | #define init_task_preempt_count(p) do { \
39 | task_thread_info(p)->preempt_count = FORK_PREEMPT_COUNT; \
40 | } while (0)
41 |
42 | #define init_idle_preempt_count(p, cpu) do { \
43 | task_thread_info(p)->preempt_count = PREEMPT_DISABLED; \
44 | } while (0)
45 |
46 | static __always_inline void set_preempt_need_resched(void)
47 | {
48 | }
49 |
50 | static __always_inline void clear_preempt_need_resched(void)
51 | {
52 | }
53 |
54 | static __always_inline bool test_preempt_need_resched(void)
55 | {
56 | return false;
57 | }
58 |
59 | /*
60 | * The various preempt_count add/sub methods
61 | */
62 |
63 | static __always_inline void __preempt_count_add(int val)
64 | {
65 | }
66 |
67 | static __always_inline void __preempt_count_sub(int val)
68 | {
69 | }
70 |
71 | static __always_inline bool __preempt_count_dec_and_test(void)
72 | {
73 | return false;
74 | }
75 |
76 | /*
77 | * Returns true when we need to resched and can (barring IRQ state).
78 | */
79 | static __always_inline bool should_resched(int preempt_offset)
80 | {
81 | return false;
82 | }
83 |
84 | #ifdef CONFIG_PREEMPTION
85 | extern asmlinkage void preempt_schedule(void);
86 | #define __preempt_schedule() preempt_schedule()
87 | extern asmlinkage void preempt_schedule_notrace(void);
88 | #define __preempt_schedule_notrace() preempt_schedule_notrace()
89 | #endif /* CONFIG_PREEMPTION */
90 |
91 | #endif /* __ASM_PREEMPT_H */
92 |
--------------------------------------------------------------------------------
/src/driver/usb_host/rpi/clear_tt_buffers.patch:
--------------------------------------------------------------------------------
1 | commit 844076104395fe052f846b451f8b3cb921098516
2 | Author: Stefan Kalkowski
3 | Date: Wed Jul 12 15:06:21 2023 +0200
4 |
5 | Clear TT buffers in error situations
6 |
7 | Based on the 'dwc2' driver implementation.
8 |
9 | diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
10 | index 783f1305e..dbd683f5e 100644
11 | --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
12 | +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
13 | @@ -215,6 +215,32 @@ static void kill_urbs_in_qh_list(dwc_otg_hcd_t * hcd, dwc_list_link_t * qh_list)
14 | } else {
15 | dwc_otg_hc_halt(hcd->core_if, qh->channel,
16 | DWC_OTG_HC_XFER_URB_DEQUEUE);
17 | + dwc_hc_t *hc = qh->channel;
18 | + if (!hc->xfer_started) {
19 | + /* copied from 'release_channel()' */
20 | + dwc_otg_hc_cleanup(hcd->core_if, hc);
21 | + DWC_CIRCLEQ_INSERT_TAIL(&hcd->free_hc_list, hc, hc_list_entry);
22 | + if (!microframe_schedule) {
23 | + switch (hc->ep_type) {
24 | + case DWC_OTG_EP_TYPE_CONTROL:
25 | + case DWC_OTG_EP_TYPE_BULK:
26 | + hcd->non_periodic_channels--;
27 | + break;
28 | +
29 | + default:
30 | + /*
31 | + * Don't release reservations for periodic channels here.
32 | + * That's done when a periodic transfer is descheduled (i.e.
33 | + * when the QH is removed from the periodic schedule).
34 | + */
35 | + break;
36 | + }
37 | + } else {
38 | + hcd->available_host_channels++;
39 | + fiq_print(FIQDBG_INT, hcd->fiq_state, "AHC = %d ", hcd->available_host_channels);
40 | + }
41 | + }
42 | +
43 | }
44 | qh->channel = NULL;
45 | }
46 | @@ -643,8 +669,60 @@ int dwc_otg_hcd_urb_dequeue(dwc_otg_hcd_t * hcd,
47 | } else {
48 | dwc_otg_hc_halt(hcd->core_if, qh->channel,
49 | DWC_OTG_HC_XFER_URB_DEQUEUE);
50 | +
51 | + dwc_hc_t *hc = qh->channel;
52 | +
53 | + if (hc->do_split) {
54 | + /*
55 | + * Ideally this would be done in
56 | + * 'dwc_otg_hcd_handle_hc_n_intr()',
57 | + * but then the urb is already gone.
58 | + *
59 | + * It can happen that the clearing has already
60 | + * been requested by an interrupt handler,
61 | + * so a check is needed.
62 | + */
63 | + if (!qh->tt_buffer_dirty) {
64 | + qh->tt_buffer_dirty = 1;
65 | + usb_hub_clear_tt_buffer(urb_qtd->urb->priv);
66 | + }
67 | + }
68 | +
69 | + if (!hc->xfer_started) {
70 | + /* copied from 'release_channel()' */
71 | + dwc_otg_hc_cleanup(hcd->core_if, hc);
72 | + DWC_CIRCLEQ_INSERT_TAIL(&hcd->free_hc_list, hc, hc_list_entry);
73 | + if (!microframe_schedule) {
74 | + switch (hc->ep_type) {
75 | + case DWC_OTG_EP_TYPE_CONTROL:
76 | + case DWC_OTG_EP_TYPE_BULK:
77 | + hcd->non_periodic_channels--;
78 | + break;
79 | +
80 | + default:
81 | + /*
82 | + * Don't release reservations for periodic channels here.
83 | + * That's done when a periodic transfer is descheduled (i.e.
84 | + * when the QH is removed from the periodic schedule).
85 | + */
86 | + break;
87 | + }
88 | + } else {
89 | + hcd->available_host_channels++;
90 | + fiq_print(FIQDBG_INT, hcd->fiq_state, "AHC = %d ", hcd->available_host_channels);
91 | + }
92 | + }
93 | }
94 | }
95 | + } else if (urb_qtd->in_process &&
96 | + hcd->flags.b.port_connect_status &&
97 | + urb_qtd->complete_split) {
98 | + /*
99 | + * State between start-split and complete-split and no channel
100 | + * assigned yet.
101 | + */
102 | + qh->tt_buffer_dirty = 1;
103 | + usb_hub_clear_tt_buffer(urb_qtd->urb->priv);
104 | }
105 |
106 | /*
107 | @@ -2346,6 +2424,12 @@ static void process_periodic_channels(dwc_otg_hcd_t * hcd)
108 | fiq_fsm_queue_isoc_transaction(hcd, qh);
109 | } else {
110 |
111 | + /* Make sure EP's TT buffer is clean before queueing qtds */
112 | + if (qh->tt_buffer_dirty) {
113 | + qh_ptr = qh_ptr->next;
114 | + continue;
115 | + }
116 | +
117 | /*
118 | * Set a flag if we're queueing high-bandwidth in slave mode.
119 | * The flag prevents any halts to get into the request queue in
120 | @@ -2476,6 +2560,10 @@ static void process_non_periodic_channels(dwc_otg_hcd_t * hcd)
121 | qh = DWC_LIST_ENTRY(hcd->non_periodic_qh_ptr, dwc_otg_qh_t,
122 | qh_list_entry);
123 |
124 | + /* Make sure EP's TT buffer is clean before queueing qtds */
125 | + if (qh->tt_buffer_dirty)
126 | + goto next;
127 | +
128 | if(fiq_fsm_enable && fiq_fsm_transaction_suitable(hcd, qh)) {
129 | fiq_fsm_queue_split_transaction(hcd, qh);
130 | } else {
131 | @@ -2489,6 +2577,7 @@ static void process_non_periodic_channels(dwc_otg_hcd_t * hcd)
132 | break;
133 | }
134 | }
135 | +next:
136 | /* Advance to next QH, skipping start-of-list entry. */
137 | hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
138 | if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active) {
139 | diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.h b/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
140 | index 0aea10408..0cc14f3cd 100644
141 | --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
142 | +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
143 | @@ -34,6 +34,9 @@
144 | #ifndef __DWC_HCD_H__
145 | #define __DWC_HCD_H__
146 |
147 | +#include
148 | +#include
149 | +
150 | #include "dwc_otg_os_dep.h"
151 | #include "usb.h"
152 | #include "dwc_otg_hcd_if.h"
153 | @@ -380,6 +383,8 @@ typedef struct dwc_otg_qh {
154 | uint16_t frame_usecs[8];
155 |
156 | uint32_t skip_count;
157 | +
158 | + unsigned tt_buffer_dirty:1;
159 | } dwc_otg_qh_t;
160 |
161 | DWC_CIRCLEQ_HEAD(hc_list, dwc_hc);
162 | @@ -624,6 +629,24 @@ static inline struct device *dwc_otg_hcd_to_dev(struct dwc_otg_hcd *hcd)
163 | return &hcd->otg_dev->os_dep.platformdev->dev;
164 | }
165 |
166 | +struct wrapper_priv_data {
167 | + dwc_otg_hcd_t *dwc_otg_hcd;
168 | +};
169 | +
170 | +/** Gets the dwc_otg_hcd from a struct usb_hcd */
171 | +static inline dwc_otg_hcd_t *hcd_to_dwc_otg_hcd(struct usb_hcd *hcd)
172 | +{
173 | + struct wrapper_priv_data *p;
174 | + p = (struct wrapper_priv_data *)(hcd->hcd_priv);
175 | + return p->dwc_otg_hcd;
176 | +}
177 | +
178 | +/** Gets the struct usb_hcd that contains a dwc_otg_hcd_t. */
179 | +static inline struct usb_hcd *dwc_otg_hcd_to_hcd(dwc_otg_hcd_t * dwc_otg_hcd)
180 | +{
181 | + return dwc_otg_hcd_get_priv_data(dwc_otg_hcd);
182 | +}
183 | +
184 | /** @name Transaction Execution Functions */
185 | /** @{ */
186 | extern dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t
187 | diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
188 | index 099d2da63..a2a09fdfe 100644
189 | --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
190 | +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
191 | @@ -36,6 +36,9 @@
192 | #include "dwc_otg_regs.h"
193 |
194 | #include
195 | +#include
196 | +#include
197 | +
198 | #ifdef CONFIG_ARM
199 | #include
200 | #endif
201 | @@ -294,6 +297,44 @@ static inline void track_missed_sofs(uint16_t curr_frame_number)
202 | }
203 | #endif
204 |
205 | +static void dwc_otg_hcd_handle_tt_clear(dwc_otg_hcd_t *hcd,
206 | + dwc_hc_t *hc,
207 | + dwc_otg_qtd_t *qtd)
208 | +{
209 | + struct usb_device *root_hub = dwc_otg_hcd_to_hcd(hcd)->self.root_hub;
210 | + struct urb *usb_urb;
211 | +
212 | + if (!hc->qh)
213 | + return;
214 | +
215 | + if (hc->qh->dev_speed == USB_SPEED_HIGH)
216 | + return;
217 | +
218 | + if (!qtd->urb)
219 | + return;
220 | +
221 | + usb_urb = qtd->urb->priv;
222 | + if (!usb_urb || !usb_urb->dev || !usb_urb->dev->tt)
223 | + return;
224 | +
225 | + /*
226 | + * The root hub doesn't really have a TT, but Linux thinks it
227 | + * does because how could you have a "high speed hub" that
228 | + * directly talks directly to low speed devices without a TT?
229 | + * It's all lies. Lies, I tell you.
230 | + */
231 | + if (usb_urb->dev->tt->hub == root_hub)
232 | + return;
233 | +
234 | + if (qtd->urb->status != -EPIPE && qtd->urb->status != -EREMOTEIO) {
235 | + hc->qh->tt_buffer_dirty = 1;
236 | + if (usb_hub_clear_tt_buffer(usb_urb))
237 | + /* Clear failed; let's hope things work anyway */
238 | + hc->qh->tt_buffer_dirty = 0;
239 | + }
240 | +}
241 | +
242 | +
243 | /**
244 | * Handles the start-of-frame interrupt in host mode. Non-periodic
245 | * transactions may be queued to the DWC_otg controller for the current
246 | @@ -1394,6 +1435,8 @@ static int32_t handle_hc_stall_intr(dwc_otg_hcd_t * hcd,
247 | DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
248 | "STALL Received--\n", hc->hc_num);
249 |
250 | + dwc_otg_hcd_handle_tt_clear(hcd, hc, qtd);
251 | +
252 | if (hcd->core_if->dma_desc_enable) {
253 | dwc_otg_hcd_complete_xfer_ddma(hcd, hc, hc_regs, DWC_OTG_HC_XFER_STALL);
254 | goto handle_stall_done;
255 | @@ -1794,6 +1837,8 @@ static int32_t handle_hc_babble_intr(dwc_otg_hcd_t * hcd,
256 | DWC_DEBUGPL(DBG_HCDI, "--Host Channel %d Interrupt: "
257 | "Babble Error--\n", hc->hc_num);
258 |
259 | + dwc_otg_hcd_handle_tt_clear(hcd, hc, qtd);
260 | +
261 | if (hcd->core_if->dma_desc_enable) {
262 | dwc_otg_hcd_complete_xfer_ddma(hcd, hc, hc_regs,
263 | DWC_OTG_HC_XFER_BABBLE_ERR);
264 | @@ -1836,6 +1881,8 @@ static int32_t handle_hc_ahberr_intr(dwc_otg_hcd_t * hcd,
265 | DWC_DEBUGPL(DBG_HCDI, "--Host Channel %d Interrupt: "
266 | "AHB Error--\n", hc->hc_num);
267 |
268 | + dwc_otg_hcd_handle_tt_clear(hcd, hc, qtd);
269 | +
270 | hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
271 | hcsplt.d32 = DWC_READ_REG32(&hc_regs->hcsplt);
272 | hctsiz.d32 = DWC_READ_REG32(&hc_regs->hctsiz);
273 | @@ -1928,6 +1975,8 @@ static int32_t handle_hc_xacterr_intr(dwc_otg_hcd_t * hcd,
274 | DWC_DEBUGPL(DBG_HCDI, "--Host Channel %d Interrupt: "
275 | "Transaction Error--\n", hc->hc_num);
276 |
277 | + dwc_otg_hcd_handle_tt_clear(hcd, hc, qtd);
278 | +
279 | if (hcd->core_if->dma_desc_enable) {
280 | dwc_otg_hcd_complete_xfer_ddma(hcd, hc, hc_regs,
281 | DWC_OTG_HC_XFER_XACT_ERR);
282 | @@ -1991,6 +2040,8 @@ static int32_t handle_hc_frmovrun_intr(dwc_otg_hcd_t * hcd,
283 | DWC_DEBUGPL(DBG_HCDI, "--Host Channel %d Interrupt: "
284 | "Frame Overrun--\n", hc->hc_num);
285 |
286 | + dwc_otg_hcd_handle_tt_clear(hcd, hc, qtd);
287 | +
288 | switch (dwc_otg_hcd_get_pipe_type(&qtd->urb->pipe_info)) {
289 | case UE_CONTROL:
290 | case UE_BULK:
291 | @@ -2028,6 +2079,8 @@ static int32_t handle_hc_datatglerr_intr(dwc_otg_hcd_t * hcd,
292 | "Data Toggle Error on %s transfer--\n",
293 | hc->hc_num, (hc->ep_is_in ? "IN" : "OUT"));
294 |
295 | + dwc_otg_hcd_handle_tt_clear(hcd, hc, qtd);
296 | +
297 | /* Data toggles on split transactions cause the hc to halt.
298 | * restart transfer */
299 | if(hc->qh->do_split)
300 | diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
301 | index ca646860a..425d2c051 100644
302 | --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
303 | +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
304 | @@ -124,9 +124,8 @@ extern int hub_control(struct usb_hcd *hcd,
305 | u16 typeReq,
306 | u16 wValue, u16 wIndex, char *buf, u16 wLength);
307 |
308 | -struct wrapper_priv_data {
309 | - dwc_otg_hcd_t *dwc_otg_hcd;
310 | -};
311 | +static void dwc_otg_hcd_clear_tt_buffer_complete(struct usb_hcd *hcd,
312 | + struct usb_host_endpoint *ep);
313 |
314 | /** @} */
315 |
316 | @@ -156,24 +155,11 @@ static struct hc_driver dwc_otg_hc_driver = {
317 |
318 | .hub_status_data = hub_status_data,
319 | .hub_control = hub_control,
320 | + .clear_tt_buffer_complete = dwc_otg_hcd_clear_tt_buffer_complete,
321 | //.bus_suspend =
322 | //.bus_resume =
323 | };
324 |
325 | -/** Gets the dwc_otg_hcd from a struct usb_hcd */
326 | -static inline dwc_otg_hcd_t *hcd_to_dwc_otg_hcd(struct usb_hcd *hcd)
327 | -{
328 | - struct wrapper_priv_data *p;
329 | - p = (struct wrapper_priv_data *)(hcd->hcd_priv);
330 | - return p->dwc_otg_hcd;
331 | -}
332 | -
333 | -/** Gets the struct usb_hcd that contains a dwc_otg_hcd_t. */
334 | -static inline struct usb_hcd *dwc_otg_hcd_to_hcd(dwc_otg_hcd_t * dwc_otg_hcd)
335 | -{
336 | - return dwc_otg_hcd_get_priv_data(dwc_otg_hcd);
337 | -}
338 | -
339 | /** Gets the usb_host_endpoint associated with an URB. */
340 | inline struct usb_host_endpoint *dwc_urb_to_endpoint(struct urb *urb)
341 | {
342 | @@ -1081,4 +1067,25 @@ int hub_control(struct usb_hcd *hcd,
343 | return retval;
344 | }
345 |
346 | +/* Handles hub TT buffer clear completions */
347 | +static void dwc_otg_hcd_clear_tt_buffer_complete(struct usb_hcd *hcd,
348 | + struct usb_host_endpoint *ep)
349 | +{
350 | + dwc_otg_hcd_t *dwc_hcd = hcd_to_dwc_otg_hcd(hcd);
351 | + dwc_otg_qh_t *qh;
352 | + unsigned long flags;
353 | +
354 | + qh = ep->hcpriv;
355 | + if (!qh)
356 | + return;
357 | +
358 | + DWC_SPINLOCK_IRQSAVE(dwc_hcd->lock, &flags);
359 | + qh->tt_buffer_dirty = 0;
360 | +
361 | + if (dwc_hcd->flags.b.port_connect_status)
362 | + dwc_otg_hcd_queue_transactions(dwc_hcd, DWC_OTG_TRANSACTION_ALL);
363 | +
364 | + DWC_SPINUNLOCK_IRQRESTORE(dwc_hcd->lock, flags);
365 | +}
366 | +
367 | #endif /* DWC_DEVICE_ONLY */
368 |
--------------------------------------------------------------------------------
/src/driver/usb_host/rpi/dummies.c:
--------------------------------------------------------------------------------
1 | /*
2 | * \brief Dummy definitions of Linux Kernel functions - handled manually
3 | * \author Stefan Kalkowski
4 | * \date 2021-08-31
5 | */
6 |
7 | /*
8 | * Copyright (C) 2021 Genode Labs GmbH
9 | *
10 | * This file is distributed under the terms of the GNU General Public License
11 | * version 2.
12 | */
13 |
14 | #include
15 |
16 | #include
17 |
18 | char __start_rodata[] = {};
19 | char __end_rodata[] = {};
20 |
21 |
22 | #include
23 |
24 | void synchronize_srcu(struct srcu_struct * ssp)
25 | {
26 | lx_emul_trace(__func__);
27 | }
28 |
29 |
30 | #include
31 |
32 | struct pt_regs * __irq_regs = NULL;
33 |
34 |
35 | #include
36 | #include
37 |
38 | const struct of_device_id __reservedmem_of_table[] = {};
39 |
40 |
41 | #include
42 |
43 | void account_process_tick(struct task_struct * p,int user_tick)
44 | {
45 | lx_emul_trace(__func__);
46 | }
47 |
48 |
49 | extern void arch_trigger_cpumask_backtrace(const cpumask_t * mask,bool exclude_self);
50 | void arch_trigger_cpumask_backtrace(const cpumask_t * mask,bool exclude_self)
51 | {
52 | lx_emul_trace_and_stop(__func__);
53 | }
54 |
55 |
56 | #include
57 |
58 | noinstr void ct_irq_enter(void)
59 | {
60 | lx_emul_trace(__func__);
61 | }
62 |
63 |
64 | #include
65 |
66 | noinstr void ct_irq_exit(void)
67 | {
68 | lx_emul_trace(__func__);
69 | }
70 |
71 |
72 | #include
73 |
74 | const struct trace_print_flags vmaflag_names[] = { {0,NULL}};
75 |
76 |
77 | #include
78 |
79 | const struct trace_print_flags pageflag_names[] = { {0,NULL}};
80 |
81 |
82 | #include
83 |
84 | const struct trace_print_flags gfpflag_names[] = { {0,NULL}};
85 |
86 |
87 | #include
88 |
89 | int __cpuhp_setup_state(enum cpuhp_state state,const char * name,bool invoke,int (* startup)(unsigned int cpu),int (* teardown)(unsigned int cpu),bool multi_instance)
90 | {
91 | lx_emul_trace(__func__);
92 | return 0;
93 | }
94 |
95 |
96 | #include
97 |
98 | void __init net_ns_init(void)
99 | {
100 | lx_emul_trace(__func__);
101 | }
102 |
103 |
104 | #include
105 |
106 | void ignore_signals(struct task_struct * t)
107 | {
108 | lx_emul_trace(__func__);
109 | }
110 |
111 |
112 | #include
113 |
114 | int sysfs_create_dir_ns(struct kobject * kobj,const void * ns)
115 | {
116 | lx_emul_trace(__func__);
117 | return 0;
118 | }
119 |
120 |
121 | #include
122 |
123 | int sysfs_create_groups(struct kobject * kobj,const struct attribute_group ** groups)
124 | {
125 | lx_emul_trace(__func__);
126 | return 0;
127 | }
128 |
129 |
130 | #include
131 |
132 | void kernfs_get(struct kernfs_node * kn)
133 | {
134 | lx_emul_trace(__func__);
135 | }
136 |
137 |
138 | #include
139 |
140 | int kobject_uevent(struct kobject * kobj,enum kobject_action action)
141 | {
142 | lx_emul_trace(__func__);
143 | return 0;
144 | }
145 |
146 |
147 | #include
148 |
149 | struct kernfs_node * kernfs_find_and_get_ns(struct kernfs_node * parent,const char * name,const void * ns)
150 | {
151 | lx_emul_trace(__func__);
152 | return NULL;
153 | }
154 |
155 |
156 | #include
157 |
158 | int sysfs_create_bin_file(struct kobject * kobj,const struct bin_attribute * attr)
159 | {
160 | lx_emul_trace(__func__);
161 | return 0;
162 | }
163 |
164 |
165 | #include
166 |
167 | struct proc_dir_entry * proc_symlink(const char * name,struct proc_dir_entry * parent,const char * dest)
168 | {
169 | lx_emul_trace(__func__);
170 | return NULL;
171 | }
172 |
173 |
174 | extern void software_node_notify(struct device * dev);
175 | void software_node_notify(struct device * dev)
176 | {
177 | lx_emul_trace(__func__);
178 | }
179 |
180 |
181 | #include
182 |
183 | int sysfs_create_file_ns(struct kobject * kobj,const struct attribute * attr,const void * ns)
184 | {
185 | lx_emul_trace(__func__);
186 | return 0;
187 | }
188 |
189 |
190 | #include
191 |
192 | int sysfs_create_link(struct kobject * kobj,struct kobject * target,const char * name)
193 | {
194 | lx_emul_trace(__func__);
195 | return 0;
196 | }
197 |
198 |
199 | #include
200 |
201 | struct logic_pio_hwaddr * find_io_range_by_fwnode(struct fwnode_handle * fwnode)
202 | {
203 | lx_emul_trace(__func__);
204 | return NULL;
205 | }
206 |
207 |
208 | #include
209 |
210 | bool parse_option_str(const char * str,const char * option)
211 | {
212 | lx_emul_trace(__func__);
213 | return false;
214 | }
215 |
216 |
217 | #include
218 |
219 | int __register_chrdev(unsigned int major,unsigned int baseminor,unsigned int count,const char * name,const struct file_operations * fops)
220 | {
221 | lx_emul_trace(__func__);
222 | return 0;
223 | }
224 |
225 |
226 | #include
227 |
228 | int register_chrdev_region(dev_t from,unsigned count,const char * name)
229 | {
230 | lx_emul_trace(__func__);
231 | return 0;
232 | }
233 |
234 |
235 | #include
236 |
237 | int cdev_add(struct cdev * p,dev_t dev,unsigned count)
238 | {
239 | lx_emul_trace(__func__);
240 | return 0;
241 | }
242 |
243 |
244 | #include
245 |
246 | int pinctrl_bind_pins(struct device * dev)
247 | {
248 | lx_emul_trace(__func__);
249 | return 0;
250 | }
251 |
252 |
253 | #include
254 |
255 | void arch_setup_dma_ops(struct device * dev,u64 dma_base,u64 size,const struct iommu_ops * iommu,bool coherent)
256 | {
257 | lx_emul_trace(__func__);
258 | }
259 |
260 |
261 | #include
262 |
263 | int of_clk_set_defaults(struct device_node * node,bool clk_supplier)
264 | {
265 | lx_emul_trace(__func__);
266 | return 0;
267 | }
268 |
269 |
270 | #include
271 |
272 | struct gpio_desc * __must_check devm_gpiod_get_optional(struct device * dev,const char * con_id,enum gpiod_flags flags)
273 | {
274 | lx_emul_trace(__func__);
275 | return NULL;
276 | }
277 |
278 |
279 | #include
280 |
281 | struct regulator * devm_regulator_get(struct device * dev,const char * id)
282 | {
283 | lx_emul_trace(__func__);
284 | return NULL;
285 | }
286 |
287 |
288 | #include
289 |
290 | struct regulator * devm_regulator_get_exclusive(struct device * dev,const char * id)
291 | {
292 | lx_emul_trace(__func__);
293 | return NULL;
294 | }
295 |
296 |
297 | #include
298 |
299 | int pinctrl_init_done(struct device * dev)
300 | {
301 | lx_emul_trace(__func__);
302 | return 0;
303 | }
304 |
305 |
306 | #include
307 |
308 | void sysfs_remove_file_ns(struct kobject * kobj,const struct attribute * attr,const void * ns)
309 | {
310 | lx_emul_trace(__func__);
311 | }
312 |
313 |
314 | #include
315 |
316 | struct ctl_table_header * register_sysctl(const char * path,struct ctl_table * table)
317 | {
318 | lx_emul_trace(__func__);
319 | return NULL;
320 | }
321 |
322 |
323 | #include
324 |
325 | void register_syscore_ops(struct syscore_ops * ops)
326 | {
327 | lx_emul_trace(__func__);
328 | }
329 |
330 |
331 | #include
332 |
333 | struct proc_dir_entry { int dummy; };
334 | struct proc_dir_entry * proc_create_seq_private(const char * name,umode_t mode,struct proc_dir_entry * parent,const struct seq_operations * ops,unsigned int state_size,void * data)
335 | {
336 | static struct proc_dir_entry ret;
337 | lx_emul_trace(__func__);
338 | return &ret;
339 | }
340 |
341 |
342 | #include
343 |
344 | int sysfs_add_file_to_group(struct kobject * kobj,const struct attribute * attr,const char * group)
345 | {
346 | lx_emul_trace(__func__);
347 | return 0;
348 | }
349 |
350 |
351 | #include
352 |
353 | void __init __register_sysctl_init(const char * path,struct ctl_table * table,const char * table_name)
354 | {
355 | lx_emul_trace(__func__);
356 | }
357 |
358 |
359 | #include
360 |
361 | void sysfs_remove_link(struct kobject * kobj,const char * name)
362 | {
363 | lx_emul_trace(__func__);
364 | }
365 |
366 |
367 | #include
368 |
369 | void sysfs_delete_link(struct kobject * kobj,struct kobject * targ,const char * name)
370 | {
371 | lx_emul_trace(__func__);
372 | }
373 |
374 |
375 | #include
376 |
377 | void sysfs_remove_groups(struct kobject * kobj,const struct attribute_group ** groups)
378 | {
379 | lx_emul_trace(__func__);
380 | }
381 |
382 |
383 | extern void software_node_notify_remove(struct device * dev);
384 | void software_node_notify_remove(struct device * dev)
385 | {
386 | lx_emul_trace(__func__);
387 | }
388 |
389 |
390 | #include
391 |
392 | void sysfs_remove_dir(struct kobject * kobj)
393 | {
394 | lx_emul_trace(__func__);
395 | }
396 |
397 |
398 | #include
399 |
400 | void kernfs_put(struct kernfs_node * kn)
401 | {
402 | lx_emul_trace(__func__);
403 | }
404 |
405 |
406 | #include
407 |
408 | void arch_teardown_dma_ops(struct device * dev)
409 | {
410 | lx_emul_trace(__func__);
411 | }
412 |
413 |
414 | #include
415 |
416 | struct regulator * devm_regulator_get_optional(struct device * dev,const char * id)
417 | {
418 | lx_emul_trace(__func__);
419 | return NULL;
420 | }
421 |
422 |
423 | #include
424 |
425 | struct pinctrl * devm_pinctrl_get(struct device * dev)
426 | {
427 | lx_emul_trace(__func__);
428 | return NULL;
429 | }
430 |
431 |
432 | #include
433 |
434 | struct pinctrl_state * pinctrl_lookup_state(struct pinctrl * p,const char * name)
435 | {
436 | lx_emul_trace(__func__);
437 | return NULL;
438 | }
439 |
440 |
441 | #include
442 |
443 | int insert_resource(struct resource * parent,struct resource * new)
444 | {
445 | lx_emul_trace(__func__);
446 | return 0;
447 | }
448 |
449 |
450 | #include
451 |
452 | void rcu_sched_clock_irq(int user)
453 | {
454 | lx_emul_trace(__func__);
455 | }
456 |
457 |
458 | #include
459 |
460 | void run_posix_cpu_timers(void)
461 | {
462 | lx_emul_trace(__func__);
463 | }
464 |
465 |
466 | #include
467 |
468 | void add_device_randomness(const void * buf,size_t len)
469 | {
470 | lx_emul_trace(__func__);
471 | }
472 |
473 |
474 | extern int devtmpfs_create_node(struct device * dev);
475 | int devtmpfs_create_node(struct device * dev)
476 | {
477 | lx_emul_trace(__func__);
478 | return 0;
479 | }
480 |
481 |
482 | #include
483 |
484 | int sysfs_create_group(struct kobject * kobj,const struct attribute_group * grp)
485 | {
486 | lx_emul_trace(__func__);
487 | return 0;
488 | }
489 |
490 |
491 | extern void register_irq_proc(unsigned int irq,struct irq_desc * desc);
492 | void register_irq_proc(unsigned int irq,struct irq_desc * desc)
493 | {
494 | lx_emul_trace(__func__);
495 | }
496 |
497 |
498 | extern void register_handler_proc(unsigned int irq,struct irqaction * action);
499 | void register_handler_proc(unsigned int irq,struct irqaction * action)
500 | {
501 | lx_emul_trace(__func__);
502 | }
503 |
504 |
505 | #include
506 |
507 | void add_interrupt_randomness(int irq)
508 | {
509 | lx_emul_trace(__func__);
510 | }
511 |
512 |
513 | #include
514 |
515 | bool is_vmalloc_addr(const void * x)
516 | {
517 | lx_emul_trace(__func__);
518 | return false;
519 | }
520 |
521 |
522 | #include
523 |
524 | struct timespec64 current_time(struct inode * inode)
525 | {
526 | struct timespec64 ret = { 0 };
527 | lx_emul_trace(__func__);
528 | return ret;
529 | }
530 |
531 |
532 | #include
533 |
534 | void put_pid(struct pid * pid)
535 | {
536 | lx_emul_trace(__func__);
537 | }
538 |
539 |
540 | #include
541 |
542 | void __put_cred(struct cred * cred)
543 | {
544 | lx_emul_trace(__func__);
545 | }
546 |
547 |
548 | #include
549 |
550 | void sysfs_remove_bin_file(struct kobject * kobj,const struct bin_attribute * attr)
551 | {
552 | lx_emul_trace(__func__);
553 | }
554 |
555 |
556 | extern int devtmpfs_delete_node(struct device * dev);
557 | int devtmpfs_delete_node(struct device * dev)
558 | {
559 | lx_emul_trace(__func__);
560 | return 0;
561 | }
562 |
563 |
564 | #include
565 |
566 | void skb_init()
567 | {
568 | lx_emul_trace(__func__);
569 | }
570 |
571 |
572 | void tick_broadcast(const struct cpumask * mask)
573 | {
574 | lx_emul_trace_and_stop(__func__);
575 | }
576 |
577 |
578 | #include
579 |
580 | void config_group_init(struct config_group * group)
581 | {
582 | lx_emul_trace(__func__);
583 | }
584 |
585 |
586 | struct gserial;
587 | struct usb_ep;
588 |
589 | extern struct usb_request * gs_alloc_req(struct usb_ep * ep,unsigned len,gfp_t kmalloc_flags);
590 | struct usb_request * gs_alloc_req(struct usb_ep * ep,unsigned len,gfp_t kmalloc_flags)
591 | {
592 | lx_emul_trace_and_stop(__func__);
593 | }
594 |
595 |
596 | extern void gs_free_req(struct usb_ep * ep,struct usb_request * req);
597 | void gs_free_req(struct usb_ep * ep,struct usb_request * req)
598 | {
599 | lx_emul_trace_and_stop(__func__);
600 | }
601 |
602 |
603 | extern int gserial_connect(struct gserial * gser,u8 port_num);
604 | int gserial_connect(struct gserial * gser,u8 port_num)
605 | {
606 | lx_emul_trace_and_stop(__func__);
607 | }
608 |
609 |
610 | extern void gserial_disconnect(struct gserial * gser);
611 | void gserial_disconnect(struct gserial * gser)
612 | {
613 | lx_emul_trace_and_stop(__func__);
614 | }
615 |
616 |
617 | extern void gserial_resume(struct gserial * gser);
618 | void gserial_resume(struct gserial * gser)
619 | {
620 | lx_emul_trace_and_stop(__func__);
621 | }
622 |
623 |
624 | extern void gserial_suspend(struct gserial * gser);
625 | void gserial_suspend(struct gserial * gser)
626 | {
627 | lx_emul_trace_and_stop(__func__);
628 | }
629 |
630 |
631 | #include
632 |
633 | int configfs_register_subsystem(struct configfs_subsystem * subsys)
634 | {
635 | lx_emul_trace(__func__);
636 | return 0;
637 | }
638 |
639 |
640 | #include