PKGBUILDs/rpi_ws281x/git/0004-Read-CPU-revision-from...

80 lines
2.0 KiB
Diff

From 8863b65325b1669dcf46310d5d4e8a57fa9d0823 Mon Sep 17 00:00:00 2001
From: James Lu <james@overdrivenetworks.com>
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 <string.h>
#include <stdlib.h>
#include <errno.h>
+#include <byteswap.h>
#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