From b889192bbb5169d93d35c2564813c7ea4d5fde41 Mon Sep 17 00:00:00 2001 From: wimrijnders Date: Thu, 12 Jul 2018 11:53:48 +0200 Subject: [PATCH 01/13] BUGFIX: Enable QPU when accessing Register Map Accessing the register map won't work in the VideoCore is powered up. This adds code to `detectPlatform` to ensure that VideoCore is enabled before reading the registers. In addition: - Adjusted some code for better debugging. Notably, a call to `perror` has been added in `MailBox.cpp`. - Left in debug printf's where useful. There are commented out in general. - Added RegisterMap::enabled(), which checks if registers are accessible. The latter is actually a useful method to determine if the VideoCore is running. --- Lib/VideoCore/Mailbox.cpp | 6 +++++- Lib/VideoCore/RegisterMap.cpp | 36 +++++++++++++++++++++++++++++++++-- Lib/VideoCore/RegisterMap.h | 5 +++-- Tools/detectPlatform.cpp | 12 ++++++++++++ 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/Lib/VideoCore/Mailbox.cpp b/Lib/VideoCore/Mailbox.cpp index ba12e1a..aa9ae27 100644 --- a/Lib/VideoCore/Mailbox.cpp +++ b/Lib/VideoCore/Mailbox.cpp @@ -42,6 +42,8 @@ namespace QPULib { void *mapmem(unsigned base, unsigned size) { + //printf("mapmem requested base: 0x%x, size: %d\n", base, size); + int mem_fd; unsigned offset = base % PAGE_SIZE; base = base - offset; @@ -63,7 +65,9 @@ void *mapmem(unsigned base, unsigned size) #endif // DEBUG if (mem == MAP_FAILED) { - printf("mmap error %p\n", mem); + printf("mmap error value %p: ", mem); + fflush(stdout); + perror(nullptr); // Prints error message on stdout exit (-1); } close(mem_fd); diff --git a/Lib/VideoCore/RegisterMap.cpp b/Lib/VideoCore/RegisterMap.cpp index 6050e11..8ef5cf0 100644 --- a/Lib/VideoCore/RegisterMap.cpp +++ b/Lib/VideoCore/RegisterMap.cpp @@ -35,7 +35,6 @@ RegisterMap::RegisterMap() { RegisterMap::~RegisterMap() { - // printf("Closing down register map\n"); unmapmem((void *) m_addr, m_size); bcm_host_deinit(); } @@ -45,6 +44,14 @@ RegisterMap::~RegisterMap() { * @brief Get the 32-bit value at the given offset in the map */ uint32_t RegisterMap::read(int offset) const { +#ifdef DEBUG + // Do a spot check on the loaded memory + if (m_addr[V3D_BASE] == 0XDEADBEEF) { + printf("RegisterMap can not read QPU registers, the VideoCore is not enabled.\n"); + exit(-1); + } +#endif + return m_addr[V3D_BASE + offset]; } @@ -55,7 +62,28 @@ uint32_t RegisterMap::read(int offset) const { * This avoids having to use `instance()->` for every read access. */ uint32_t RegisterMap::readRegister(int offset) { - return instance()->read(V3D_IDENT1); + //printf("Called readRegister, m_instance: %p\n", m_instance.get()); + return instance()->read(offset); +} + + +/** + * @brief Check if the register map is accessible. + * + * This depends on the VideoCore being enabled. Enabling and disabling + * is done with mailbox call `qpu_enable()`. + * + * This method can thus be used to detect if the VideoCore is running. + * + * @return true if register map accessible, false otherwise + */ +bool RegisterMap::enabled() { + // Detect the signature in register 0 + uint32_t reg = readRegister(V3D_IDENT0); + char *p = (char *) ® + //printf("Reg 0: '%c%c%c'\n", p[0], p[1], p[2]); + + return (p[0] == 'V' && p[1] == '3' && p[2] == 'D'); } @@ -73,10 +101,14 @@ int RegisterMap::numQPUPerSlice() { RegisterMap *RegisterMap::instance() { + //printf("Called instance(), m_instance: %p\n", m_instance.get()); + if (m_instance.get() == nullptr) { + //printf("RegisterMap initializing singleton\n"); m_instance.reset(new RegisterMap); } + // printf("m_instance post: %p\n", m_instance.get()); return m_instance.get(); } diff --git a/Lib/VideoCore/RegisterMap.h b/Lib/VideoCore/RegisterMap.h index 5c293f2..0dad1e7 100644 --- a/Lib/VideoCore/RegisterMap.h +++ b/Lib/VideoCore/RegisterMap.h @@ -24,8 +24,9 @@ class RegisterMap { ~RegisterMap(); - static int numSlices(); - static int numQPUPerSlice(); + static bool enabled(); + static int numSlices(); + static int numQPUPerSlice(); private: RegisterMap(); diff --git a/Tools/detectPlatform.cpp b/Tools/detectPlatform.cpp index 28cd8e6..f0721e8 100644 --- a/Tools/detectPlatform.cpp +++ b/Tools/detectPlatform.cpp @@ -57,12 +57,24 @@ int main(int argc, char *argv[]) { unsigned revision = get_version(mb); printf("Hardware revision: %04x\n", revision); + bool wasEnabled = RegisterMap::enabled(); + if (!wasEnabled) { + // VideoCore needs to be enabled, otherwise the registers can't be accessed. + //printf("VideoCore not running, enabling for this app\n"); + qpu_enable(mb, 1); + } + if (geteuid() == 0) { // Only do this as root (sudo) printf("Number of slices: %d\n", RegisterMap::numSlices()); printf("Number of QPU's per slice: %d\n", RegisterMap::numQPUPerSlice()); } else { printf("You can see more if you use sudo\n"); } + + if (!wasEnabled) { + //printf("Disabling the VideoCore again\n"); + qpu_enable(mb, 0); + } #endif // QPU_MODE return 0; From 847c7b106f758b03e73ab8e8f3499a0e23715bad Mon Sep 17 00:00:00 2001 From: wimrijnders Date: Sun, 15 Jul 2018 11:13:20 +0200 Subject: [PATCH 02/13] Set define for bcm-headers; further refinement of start/stop videcore --- Lib/VideoCore/RegisterMap.cpp | 33 +++++++++++++++++++++++++++++---- Tools/detectPlatform.cpp | 20 +++++++++++++------- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/Lib/VideoCore/RegisterMap.cpp b/Lib/VideoCore/RegisterMap.cpp index 8ef5cf0..42e9875 100644 --- a/Lib/VideoCore/RegisterMap.cpp +++ b/Lib/VideoCore/RegisterMap.cpp @@ -5,7 +5,22 @@ #include #include #include + +// This ugly part is to ensure '__linux__' is set for older versions +// for the bcm-include. +#if !defined(__linux__) +#define LINUX_PREVIOUSLY_UNDEFINED +#define __linux__ +#endif + #include + +#if defined(LINUX_PREVIOUSLY_UNDEFINED) +#define __linux__ +#undef LINUX_PREVIOUSLY_UNDEFINED +#endif +// End ugly part + #include "Mailbox.h" // for mapmem() namespace QPULib { @@ -47,8 +62,7 @@ uint32_t RegisterMap::read(int offset) const { #ifdef DEBUG // Do a spot check on the loaded memory if (m_addr[V3D_BASE] == 0XDEADBEEF) { - printf("RegisterMap can not read QPU registers, the VideoCore is not enabled.\n"); - exit(-1); + printf("WARNING: RegisterMap can not read QPU registers, the VideoCore is not enabled.\n"); } #endif @@ -81,9 +95,20 @@ bool RegisterMap::enabled() { // Detect the signature in register 0 uint32_t reg = readRegister(V3D_IDENT0); char *p = (char *) ® - //printf("Reg 0: '%c%c%c'\n", p[0], p[1], p[2]); +#ifdef DEBUG + printf("Reg 0: '%c%c%c'\n", p[0], p[1], p[2]); +#endif + + bool canRead = (p[0] == 'V' && p[1] == '3' && p[2] == 'D'); + +#ifdef PROB_NOT_REQUIRED + if (!canRead) { + // Reset singleton for a next attempt + m_instance.reset(nullptr); + } +#endif // PROB_NOT_REQUIRED - return (p[0] == 'V' && p[1] == '3' && p[2] == 'D'); + return canRead; } diff --git a/Tools/detectPlatform.cpp b/Tools/detectPlatform.cpp index f0721e8..692ae7f 100644 --- a/Tools/detectPlatform.cpp +++ b/Tools/detectPlatform.cpp @@ -57,14 +57,20 @@ int main(int argc, char *argv[]) { unsigned revision = get_version(mb); printf("Hardware revision: %04x\n", revision); - bool wasEnabled = RegisterMap::enabled(); - if (!wasEnabled) { - // VideoCore needs to be enabled, otherwise the registers can't be accessed. - //printf("VideoCore not running, enabling for this app\n"); - qpu_enable(mb, 1); - } - + bool wasEnabled = true; // Default to prevent final call to qpu_enable() if (geteuid() == 0) { // Only do this as root (sudo) + wasEnabled = RegisterMap::enabled(); + if (!wasEnabled) { + // VideoCore needs to be enabled, otherwise the registers can't be accessed. + //printf("VideoCore not running, enabling for this app\n"); + qpu_enable(mb, 1); + + // Videocore apparently needs some time on initial startup + // After first, it starts up fast. + // Would be better if we could detect the very first call + sleep(3); + } + printf("Number of slices: %d\n", RegisterMap::numSlices()); printf("Number of QPU's per slice: %d\n", RegisterMap::numQPUPerSlice()); } else { From 275e32529c44714a68d8bb389cda526b60e86760 Mon Sep 17 00:00:00 2001 From: wimrijnders Date: Mon, 16 Jul 2018 22:41:53 +0200 Subject: [PATCH 03/13] Added some commenting, fixed facepalm-typo --- Lib/VideoCore/RegisterMap.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Lib/VideoCore/RegisterMap.cpp b/Lib/VideoCore/RegisterMap.cpp index 42e9875..01f0c35 100644 --- a/Lib/VideoCore/RegisterMap.cpp +++ b/Lib/VideoCore/RegisterMap.cpp @@ -6,8 +6,14 @@ #include #include +// // This ugly part is to ensure '__linux__' is set for older versions -// for the bcm-include. +// for the bcm-include.i +// +// Apparently, old distro's have a gcc version +// which does not support the __linux__ directive, which is required +// to include certain header files for the Pi. +// #if !defined(__linux__) #define LINUX_PREVIOUSLY_UNDEFINED #define __linux__ @@ -16,7 +22,7 @@ #include #if defined(LINUX_PREVIOUSLY_UNDEFINED) -#define __linux__ +#undef __linux__ #undef LINUX_PREVIOUSLY_UNDEFINED #endif // End ugly part From 33c79d7951ba3e9b3a7f6b31193caf4fea18a9e2 Mon Sep 17 00:00:00 2001 From: wimrijnders Date: Mon, 16 Jul 2018 22:48:30 +0200 Subject: [PATCH 04/13] typo fix --- Lib/VideoCore/RegisterMap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/VideoCore/RegisterMap.cpp b/Lib/VideoCore/RegisterMap.cpp index 01f0c35..abed718 100644 --- a/Lib/VideoCore/RegisterMap.cpp +++ b/Lib/VideoCore/RegisterMap.cpp @@ -8,7 +8,7 @@ // // This ugly part is to ensure '__linux__' is set for older versions -// for the bcm-include.i +// for the bcm-include. // // Apparently, old distro's have a gcc version // which does not support the __linux__ directive, which is required From 56381e3c47c91895630a53fbf5478bd9c685f562 Mon Sep 17 00:00:00 2001 From: wimrijnders Date: Wed, 18 Jul 2018 09:24:00 +0200 Subject: [PATCH 05/13] Dependency fix in Makefile, better checking of define's used in bcm headers --- Lib/VideoCore/RegisterMap.cpp | 44 +++++++++++++++++++++++++---------- Makefile | 2 +- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/Lib/VideoCore/RegisterMap.cpp b/Lib/VideoCore/RegisterMap.cpp index abed718..e50c6ed 100644 --- a/Lib/VideoCore/RegisterMap.cpp +++ b/Lib/VideoCore/RegisterMap.cpp @@ -5,29 +5,49 @@ #include #include #include +#include "Mailbox.h" // mapmem() // -// This ugly part is to ensure '__linux__' is set for older versions -// for the bcm-include. +// This ugly part is to ensure: // -// Apparently, old distro's have a gcc version -// which does not support the __linux__ directive, which is required -// to include certain header files for the Pi. +// - '__unix__' *is* set +// - '__ANDROID__' is *not* set // -#if !defined(__linux__) -#define LINUX_PREVIOUSLY_UNDEFINED -#define __linux__ +// ... for older versions of the bcm-include. +// +// Apparently, old distro's have a gcc version which assumes +// th presence/absence of these directives, which may prevent +// including certain system header files for the Pi. +// +#pragma message "__unix__ is NOT defined" +#if !defined(__unix__) +#pragma message "__unix__ is NOT defined" +#define UNIX_PREVIOUSLY_UNDEFINED +#define __unix__ +#endif + +#if defined(__ANDROID__) +#pragma message "__ANDROID__ is defined" +#define ANDROID_PREVIOUSLY_DEFINED +#undef __ANDROID__ #endif #include -#if defined(LINUX_PREVIOUSLY_UNDEFINED) -#undef __linux__ -#undef LINUX_PREVIOUSLY_UNDEFINED +#if defined(ANDROID_PREVIOUSLY_DEFINED) +#define __ANDROID__ +#undef ANDROID_PREVIOUSLY_DEFINED #endif + +#if defined(UNIX_PREVIOUSLY_UNDEFINED) +#undef __unix__ +#undef UNIX_PREVIOUSLY_UNDEFINED +#endif + +// // End ugly part +// -#include "Mailbox.h" // for mapmem() namespace QPULib { diff --git a/Makefile b/Makefile index 7a92cbc..0a144c5 100644 --- a/Makefile +++ b/Makefile @@ -229,7 +229,7 @@ $(OBJ_DIR)/bin/runTests: $(UNIT_TESTS) $(EXAMPLES_OBJ) | $(QPU_LIB) @echo Compiling unit tests @$(CXX) $(CXX_FLAGS) -Wno-psabi $^ -L$(OBJ_DIR) -lQPULib $(LIBS) -o $@ -test : $(OBJ_DIR)/bin/runTests | AutoTest +test : $(OBJ_DIR)/bin/runTests | AutoTest detectPlatform @echo Running unit tests with '$(RUN_TESTS)' @$(RUN_TESTS) From b4e1b599179e3f4999520a6b491dd38641ed4677 Mon Sep 17 00:00:00 2001 From: wimrijnders Date: Wed, 18 Jul 2018 09:25:17 +0200 Subject: [PATCH 06/13] Typo --- Lib/VideoCore/RegisterMap.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/VideoCore/RegisterMap.cpp b/Lib/VideoCore/RegisterMap.cpp index e50c6ed..0f195dd 100644 --- a/Lib/VideoCore/RegisterMap.cpp +++ b/Lib/VideoCore/RegisterMap.cpp @@ -19,7 +19,6 @@ // th presence/absence of these directives, which may prevent // including certain system header files for the Pi. // -#pragma message "__unix__ is NOT defined" #if !defined(__unix__) #pragma message "__unix__ is NOT defined" #define UNIX_PREVIOUSLY_UNDEFINED From cac6e7f015ad2bc13bf06af7d321b49fecf0693e Mon Sep 17 00:00:00 2001 From: wimrijnders Date: Thu, 19 Jul 2018 23:14:09 +0200 Subject: [PATCH 07/13] Better fix for old Pi compile errors with bcm_host --- Lib/VideoCore/RegisterMap.cpp | 69 ++++++++++++++++++++--------------- Makefile | 20 +++++++++- 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/Lib/VideoCore/RegisterMap.cpp b/Lib/VideoCore/RegisterMap.cpp index 0f195dd..0e9a9b8 100644 --- a/Lib/VideoCore/RegisterMap.cpp +++ b/Lib/VideoCore/RegisterMap.cpp @@ -7,45 +7,54 @@ #include #include "Mailbox.h" // mapmem() +#ifdef OLD_PI +#pragma message "This is an old pi!" // -// This ugly part is to ensure: +// For old Pi's, calls bcm_host_get_peripheral_address() and +// bcm_host_get_peripheral_size() don't exist, so we need +// to supply them ourselves. // -// - '__unix__' *is* set -// - '__ANDROID__' is *not* set -// -// ... for older versions of the bcm-include. -// -// Apparently, old distro's have a gcc version which assumes -// th presence/absence of these directives, which may prevent -// including certain system header files for the Pi. -// -#if !defined(__unix__) -#pragma message "__unix__ is NOT defined" -#define UNIX_PREVIOUSLY_UNDEFINED -#define __unix__ -#endif -#if defined(__ANDROID__) -#pragma message "__ANDROID__ is defined" -#define ANDROID_PREVIOUSLY_DEFINED -#undef __ANDROID__ -#endif -#include +/** + * This returns the ARM-side physical address where peripherals are mapped. + * + * Values: + * + * - 0x20000000 - Pi Zero, Zero W, and the first generation of the Pi and Compute Module + * - 0x3f000000 - Pi 2, Pi 3 and Compute Module 3 + * + * NOTE: We only return the second value for now, to get QPULib to compile on an old Pi 2 distro. + * Other values may be added as needed. + */ +unsigned bcm_host_get_peripheral_address() { + return 0x3f000000; +} -#if defined(ANDROID_PREVIOUSLY_DEFINED) -#define __ANDROID__ -#undef ANDROID_PREVIOUSLY_DEFINED -#endif -#if defined(UNIX_PREVIOUSLY_UNDEFINED) -#undef __unix__ -#undef UNIX_PREVIOUSLY_UNDEFINED -#endif +// following is the same for all Pi models +unsigned bcm_host_get_peripheral_size() { return 0x01000000; } // -// End ugly part +// This is the only things we need from bcm_host.h, we declare +// them explicitly to avoid dragging in all the stuff that throws compile errors. // +#ifdef __cplusplus +extern "C" { +#endif + +void bcm_host_init(void); +void bcm_host_deinit(void); + +#ifdef __cplusplus +} +#endif +// End things we need from bcm_host.h, we declare + +#else // OLD_PI +// Following works for newer distro's +#include +#endif // OLD_PI namespace QPULib { diff --git a/Makefile b/Makefile index 0a144c5..6f917a7 100644 --- a/Makefile +++ b/Makefile @@ -40,9 +40,25 @@ else $(info Building on a Pi platform) endif - CXX_FLAGS += -DQPU_MODE -I /opt/vc/include - OBJ_DIR := $(OBJ_DIR)-qpu + CXX_FLAGS += -DQPU_MODE LIBS := -L /opt/vc/lib -l bcm_host + + OBJ_DIR := $(OBJ_DIR)-qpu + + +# +# Detect if Pi has bcm_host support (new) or not (old) +# If old, pass in -DOLD_PI to compilation +# +OLD_PI := $(shell grep bcm_host_get_peripheral_address /opt/vc/include/bcm_host.h && echo "no" || echo "yes") +ifeq ($(OLD_PI), yes) +$(info old pi) +CXX_FLAGS+= -DOLD_PI +else +$(info new pi) + CXX_FLAGS += -I /opt/vc/include +endif + else CXX_FLAGS += -DEMULATION_MODE endif From 628ec3f5d83c12867abafbc492d8f8a4dfba3948 Mon Sep 17 00:00:00 2001 From: wimrijnders Date: Thu, 19 Jul 2018 23:22:29 +0200 Subject: [PATCH 08/13] small fixes, typo's --- Lib/VideoCore/RegisterMap.cpp | 6 +++--- Makefile | 6 ++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Lib/VideoCore/RegisterMap.cpp b/Lib/VideoCore/RegisterMap.cpp index 0e9a9b8..12e89bc 100644 --- a/Lib/VideoCore/RegisterMap.cpp +++ b/Lib/VideoCore/RegisterMap.cpp @@ -8,7 +8,7 @@ #include "Mailbox.h" // mapmem() #ifdef OLD_PI -#pragma message "This is an old pi!" +//#pragma message "This is an old pi!" // // For old Pi's, calls bcm_host_get_peripheral_address() and // bcm_host_get_peripheral_size() don't exist, so we need @@ -36,7 +36,7 @@ unsigned bcm_host_get_peripheral_address() { unsigned bcm_host_get_peripheral_size() { return 0x01000000; } // -// This is the only things we need from bcm_host.h, we declare +// These are the only things we need from bcm_host.h, we declare // them explicitly to avoid dragging in all the stuff that throws compile errors. // #ifdef __cplusplus @@ -49,7 +49,7 @@ void bcm_host_deinit(void); #ifdef __cplusplus } #endif -// End things we need from bcm_host.h, we declare +// End things we need from bcm_host.h #else // OLD_PI // Following works for newer distro's diff --git a/Makefile b/Makefile index 6f917a7..d4902fb 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,6 @@ ifeq ($(QPU), 1) # Check platform before building. Can't be indented, otherwise make complains. RET := $(shell Tools/detectPlatform.sh 1>/dev/null && echo "yes" || echo "no") -#$(info info: '$(RET)') ifneq ($(RET), yes) $(error QPU-mode specified on a non-Pi platform; aborting) else @@ -45,17 +44,16 @@ endif OBJ_DIR := $(OBJ_DIR)-qpu - # # Detect if Pi has bcm_host support (new) or not (old) # If old, pass in -DOLD_PI to compilation # OLD_PI := $(shell grep bcm_host_get_peripheral_address /opt/vc/include/bcm_host.h && echo "no" || echo "yes") ifeq ($(OLD_PI), yes) -$(info old pi) +#$(info old pi) CXX_FLAGS+= -DOLD_PI else -$(info new pi) +#$(info new pi) CXX_FLAGS += -I /opt/vc/include endif From 77b8081c092c1da2562d60db8ae30eaab482795a Mon Sep 17 00:00:00 2001 From: wimrijnders Date: Sun, 22 Jul 2018 22:36:35 +0200 Subject: [PATCH 09/13] Don't use bcm headerrs by default --- Lib/VideoCore/RegisterMap.cpp | 10 +++++----- Makefile | 13 +++++++------ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Lib/VideoCore/RegisterMap.cpp b/Lib/VideoCore/RegisterMap.cpp index 12e89bc..266f290 100644 --- a/Lib/VideoCore/RegisterMap.cpp +++ b/Lib/VideoCore/RegisterMap.cpp @@ -7,7 +7,10 @@ #include #include "Mailbox.h" // mapmem() -#ifdef OLD_PI +#ifdef USE_BCM_HEADERS +// Following works for newer distro's +#include +#else // USE_BCM_HEADERS //#pragma message "This is an old pi!" // // For old Pi's, calls bcm_host_get_peripheral_address() and @@ -51,10 +54,7 @@ void bcm_host_deinit(void); #endif // End things we need from bcm_host.h -#else // OLD_PI -// Following works for newer distro's -#include -#endif // OLD_PI +#endif // USE_BCM_HEADERS namespace QPULib { diff --git a/Makefile b/Makefile index daad60b..24936f2 100644 --- a/Makefile +++ b/Makefile @@ -48,13 +48,14 @@ endif # Detect if Pi has bcm_host support (new) or not (old) # If old, pass in -DOLD_PI to compilation # -OLD_PI := $(shell grep bcm_host_get_peripheral_address /opt/vc/include/bcm_host.h && echo "no" || echo "yes") -ifeq ($(OLD_PI), yes) -#$(info old pi) -CXX_FLAGS+= -DOLD_PI +#USE_BCM_HEADERS:= $(shell grep bcm_host_get_peripheral_address /opt/vc/include/bcm_host.h && echo "no" || echo "yes") +USE_BCM_HEADERS:=no +ifeq ($(USE_BCM_HEADERS), no) +$(info not using bcm headers) else -#$(info new pi) - CXX_FLAGS += -I /opt/vc/include +$(info using bcm headers) +CXX_FLAGS+= -DUSE_BCM_HEADERS +CXX_FLAGS += -I /opt/vc/include endif else From c3ea4f297aa4c7239038d70f72a78e880bc924f6 Mon Sep 17 00:00:00 2001 From: wimrijnders Date: Sun, 22 Jul 2018 23:11:46 +0200 Subject: [PATCH 10/13] Replaced inline init with ctor initializer list for RegisterMap --- Lib/VideoCore/RegisterMap.cpp | 2 +- Lib/VideoCore/RegisterMap.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/VideoCore/RegisterMap.cpp b/Lib/VideoCore/RegisterMap.cpp index 266f290..d2dbac9 100644 --- a/Lib/VideoCore/RegisterMap.cpp +++ b/Lib/VideoCore/RegisterMap.cpp @@ -69,7 +69,7 @@ enum { std::unique_ptr RegisterMap::m_instance; -RegisterMap::RegisterMap() { +RegisterMap::RegisterMap() : m_addr(nullptr) { bcm_host_init(); unsigned addr = bcm_host_get_peripheral_address(); m_size = bcm_host_get_peripheral_size(); diff --git a/Lib/VideoCore/RegisterMap.h b/Lib/VideoCore/RegisterMap.h index 0dad1e7..50b17fc 100644 --- a/Lib/VideoCore/RegisterMap.h +++ b/Lib/VideoCore/RegisterMap.h @@ -31,7 +31,7 @@ class RegisterMap { private: RegisterMap(); - volatile uint32_t *m_addr{nullptr}; + volatile uint32_t *m_addr; unsigned m_size{0}; static std::unique_ptr m_instance; From e3351a99ef098d53fb3a658f1206da1e35deb69c Mon Sep 17 00:00:00 2001 From: wimrijnders Date: Mon, 23 Jul 2018 09:32:43 +0200 Subject: [PATCH 11/13] Initialization of other instance var to ctor init list --- Lib/VideoCore/RegisterMap.cpp | 2 +- Lib/VideoCore/RegisterMap.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/VideoCore/RegisterMap.cpp b/Lib/VideoCore/RegisterMap.cpp index d2dbac9..aa8a72c 100644 --- a/Lib/VideoCore/RegisterMap.cpp +++ b/Lib/VideoCore/RegisterMap.cpp @@ -69,7 +69,7 @@ enum { std::unique_ptr RegisterMap::m_instance; -RegisterMap::RegisterMap() : m_addr(nullptr) { +RegisterMap::RegisterMap() : m_addr(nullptr), m_size(0) { bcm_host_init(); unsigned addr = bcm_host_get_peripheral_address(); m_size = bcm_host_get_peripheral_size(); diff --git a/Lib/VideoCore/RegisterMap.h b/Lib/VideoCore/RegisterMap.h index 50b17fc..b976e9b 100644 --- a/Lib/VideoCore/RegisterMap.h +++ b/Lib/VideoCore/RegisterMap.h @@ -32,7 +32,7 @@ class RegisterMap { RegisterMap(); volatile uint32_t *m_addr; - unsigned m_size{0}; + unsigned m_size; static std::unique_ptr m_instance; From 87280693bb8af5236d9ff28eeacc346eb6b7a2a1 Mon Sep 17 00:00:00 2001 From: wimrijnders Date: Tue, 24 Jul 2018 07:43:42 +0200 Subject: [PATCH 12/13] Added exhaustive checking on hardware revision for peripheral address --- Lib/VideoCore/RegisterMap.cpp | 64 ++++++++++++++++++++++++++++++++--- Makefile | 21 +++++++++--- 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/Lib/VideoCore/RegisterMap.cpp b/Lib/VideoCore/RegisterMap.cpp index aa8a72c..e831ada 100644 --- a/Lib/VideoCore/RegisterMap.cpp +++ b/Lib/VideoCore/RegisterMap.cpp @@ -3,8 +3,9 @@ #include "RegisterMap.h" #include #include -#include #include +#include // needed for 'old' compilers, no harm done for new +#include // idem #include "Mailbox.h" // mapmem() #ifdef USE_BCM_HEADERS @@ -20,18 +21,71 @@ /** - * This returns the ARM-side physical address where peripherals are mapped. + * @brief This returns the ARM-side physical address where peripherals are mapped. * * Values: * * - 0x20000000 - Pi Zero, Zero W, and the first generation of the Pi and Compute Module * - 0x3f000000 - Pi 2, Pi 3 and Compute Module 3 * - * NOTE: We only return the second value for now, to get QPULib to compile on an old Pi 2 distro. - * Other values may be added as needed. + * Source: https://www.elinux.org/RPi_HardwareHistory + * + * At time of writing (20180723), the list of handled revisions is complete. + * New values may be added as new models appear. */ unsigned bcm_host_get_peripheral_address() { - return 0x3f000000; + unsigned md = QPULib::mbox_open(); + unsigned revision = QPULib::get_version(md); + QPULib::mbox_close(md); + printf("bcm_host_get_peripheral_address revision: %x\n", revision); + + switch(revision) { + case 0x0007: // A + case 0x0008: + case 0x0009: + case 0x0012: // A+ + case 0x0015: + case 0x900021: + case 0x0002: // B + case 0x0003: + case 0x0004: + case 0x0005: + case 0x0006: + case 0x000d: + case 0x000e: + case 0x000f: + case 0x0010: // B+ + case 0x0013: + case 0x900032: + case 0x0011: // Compute Module 1 + case 0x0014: + case 0x900092: // Zero + case 0x900093: + case 0x920093: + case 0x9000c1: // Zero W + return 0x20000000; + + case 0xa01040: // 2 Model B + case 0xa01041: + case 0xa21041: + case 0xa22042: + case 0xa02082: // 3 Model B + case 0xa22082: + case 0xa32082: + case 0xa020d3: // 3 Model B+ + case 0xa020a0: // Compute Module 3 (and CM3 Lite) + return 0x3f000000; + + default: +#ifdef DEBUG + printf("bcm_host_get_peripheral_address unknown hardware revision %x\n", revision); + exit(-1); +#else + // All newer models have this address, so let's assume it + // for new revision numbers. + return 0x3f000000; +#endif + } } diff --git a/Makefile b/Makefile index 24936f2..dd508a4 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,26 @@ # -# There are four builds possible, with output directories: +# NOTES +# ===== +# +# * There are four builds possible, with output directories: # # obj - using emulator # obj-debug - output debug info, using emulator # obj-qpu - using hardware # obj-debug-qpu - output debug info, using hardware # -# To compile for debugging, add flag '-g' to CXX_FLAGS. # -########################################################### +# * To compile for debugging, add flag '-g' to CXX_FLAGS. +# +# +# * USE_BCM_HEADERS is set to 'no' by default here. This +# is to allow a proper build on old distro's (e.g. Raspbian wheezy). +# +# For newer distro's it is recommended to comment this out and use the +# longer assignment to USE_BCM_HEADERS. This works on 'Raspian stretch`, +# for 'jessie' it's unknown. +# +########################################################################### # Root directory of QPULib repository ROOT = Lib @@ -46,7 +58,6 @@ endif # # Detect if Pi has bcm_host support (new) or not (old) -# If old, pass in -DOLD_PI to compilation # #USE_BCM_HEADERS:= $(shell grep bcm_host_get_peripheral_address /opt/vc/include/bcm_host.h && echo "no" || echo "yes") USE_BCM_HEADERS:=no @@ -55,7 +66,7 @@ $(info not using bcm headers) else $(info using bcm headers) CXX_FLAGS+= -DUSE_BCM_HEADERS -CXX_FLAGS += -I /opt/vc/include +CXX_FLAGS+= -I /opt/vc/include endif else From d815813fe3c5bba61dbb3b3a044e42a07208c756 Mon Sep 17 00:00:00 2001 From: wimrijnders Date: Tue, 24 Jul 2018 09:11:57 +0200 Subject: [PATCH 13/13] Added stdio.h again to RegisterMap --- Lib/VideoCore/RegisterMap.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/VideoCore/RegisterMap.cpp b/Lib/VideoCore/RegisterMap.cpp index e831ada..9f46bee 100644 --- a/Lib/VideoCore/RegisterMap.cpp +++ b/Lib/VideoCore/RegisterMap.cpp @@ -6,6 +6,7 @@ #include #include // needed for 'old' compilers, no harm done for new #include // idem +#include // idem #include "Mailbox.h" // mapmem() #ifdef USE_BCM_HEADERS