From 8863b65325b1669dcf46310d5d4e8a57fa9d0823 Mon Sep 17 00:00:00 2001 From: James Lu Date: Sun, 26 Aug 2018 19:38:53 -0700 Subject: [PATCH 4/5] Read CPU revision from /proc/device-tree on arm64 (closes #289) --- rpihw.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/rpihw.c b/rpihw.c index a0df569..d825970 100644 --- a/rpihw.c +++ b/rpihw.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "rpihw.h" @@ -324,9 +325,34 @@ static const rpi_hw_t rpi_hw_info[] = { const rpi_hw_t *rpi_hw_detect(void) { + const rpi_hw_t *result = NULL; +#ifdef __aarch64__ + // On ARM64, read revision from /proc/device-tree as it is not shown in + // /proc/cpuinfo + FILE *f = fopen("/proc/device-tree/system/linux,revision", "r"); + if (!f) + { + return NULL; + } + uint32_t rev; + fread(&rev, sizeof(uint32_t), 1, f); + #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + rev = bswap_32(rev); // linux,revision appears to be in big endian + #endif + + for (unsigned i = 0; i < (sizeof(rpi_hw_info) / sizeof(rpi_hw_info[0])); i++) + { + uint32_t hwver = rpi_hw_info[i].hwver; + if (rev == hwver) + { + result = &rpi_hw_info[i]; + + goto done; + } + } +#else FILE *f = fopen("/proc/cpuinfo", "r"); char line[LINE_WIDTH_MAX]; - const rpi_hw_t *result = NULL; if (!f) { @@ -361,7 +387,7 @@ const rpi_hw_t *rpi_hw_detect(void) // Take out warranty and manufacturer bits hwver &= ~(RPI_WARRANTY_MASK | RPI_MANUFACTURER_MASK); rev &= ~(RPI_WARRANTY_MASK | RPI_MANUFACTURER_MASK); - + if (rev == hwver) { result = &rpi_hw_info[i]; @@ -371,7 +397,7 @@ const rpi_hw_t *rpi_hw_detect(void) } } } - +#endif done: fclose(f); -- 2.19.1