From 9eb804d5531c18e0b06b22a572c9428ccdeff60e Mon Sep 17 00:00:00 2001 From: Charles Steinkuehler Date: Thu, 3 Mar 2022 18:41:10 +0000 Subject: [PATCH] Use mailbox to get hwrev Since we're already using the mailbox interface, use it to get the hardware revision instead of parsing /proc/cpuinfo or the device tree Signed-off-by: Charles Steinkuehler --- mailbox.c | 20 ++++++++++++++ mailbox.h | 1 + rpihw.c | 79 +++++++++---------------------------------------------- rpihw.h | 2 +- ws2811.c | 26 +++++++++--------- 5 files changed, 47 insertions(+), 81 deletions(-) diff --git a/mailbox.c b/mailbox.c index a9bf802a..7f50a1c6 100644 --- a/mailbox.c +++ b/mailbox.c @@ -106,6 +106,26 @@ static int mbox_property(int file_desc, void *buf) { return ret_val; } +uint32_t get_hwver(int file_desc) { + int i=0; + uint32_t p[32]; + + p[i++] = 0; // size + p[i++] = 0x00000000; // process request + + p[i++] = 0x10002; // (the tag id) + p[i++] = 4; // (size of the buffer) + p[i++] = 0; // (size of the data) + p[i++] = 0; // (buffer) + + p[i++] = 0x00000000; // end tag + p[0] = i*sizeof *p; // actual size + + mbox_property(file_desc, p); + + return p[5]; +} + uint32_t mem_alloc(int file_desc, uint32_t size, uint32_t align, uint32_t flags) { int i=0; uint32_t p[32]; diff --git a/mailbox.h b/mailbox.h index e5b5563b..4677a4ed 100644 --- a/mailbox.h +++ b/mailbox.h @@ -37,6 +37,7 @@ int mbox_open(void); void mbox_close(int file_desc); unsigned get_version(int file_desc); +uint32_t get_hwver(int file_desc); unsigned mem_alloc(int file_desc, unsigned size, unsigned align, unsigned flags); unsigned mem_free(int file_desc, unsigned handle); unsigned mem_lock(int file_desc, unsigned handle); diff --git a/rpihw.c b/rpihw.c index 9e9db800..a49deb38 100644 --- a/rpihw.c +++ b/rpihw.c @@ -33,8 +33,8 @@ #include #include #include -#include +#include "mailbox.h" #include "rpihw.h" @@ -503,86 +503,31 @@ static const rpi_hw_t rpi_hw_info[] = { }; -const rpi_hw_t *rpi_hw_detect(void) +const rpi_hw_t *rpi_hw_detect(int file_desc) { const rpi_hw_t *result = NULL; uint32_t rev; unsigned i; -#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; - } - size_t read = fread(&rev, 1, sizeof(uint32_t), f); - if (read != sizeof(uint32_t)) - goto done; - #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - rev = bswap_32(rev); // linux,revision appears to be in big endian - #endif + rev = get_hwver(file_desc); + + // Take out warranty and manufacturer bits + rev &= ~(RPI_WARRANTY_MASK | RPI_MANUFACTURER_MASK); for (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]; - - if (!f) - { - return NULL; - } + // Take out warranty and manufacturer bits + hwver &= ~(RPI_WARRANTY_MASK | RPI_MANUFACTURER_MASK); - while (fgets(line, LINE_WIDTH_MAX - 1, f)) - { - if (strstr(line, HW_VER_STRING)) + if (rev == hwver) { - char *substr; - - substr = strstr(line, ": "); - if (!substr) - { - continue; - } - - errno = 0; - rev = strtoul(&substr[1], NULL, 16); // Base 16 - if (errno) - { - continue; - } - - for (i = 0; i < (sizeof(rpi_hw_info) / sizeof(rpi_hw_info[0])); i++) - { - uint32_t hwver = rpi_hw_info[i].hwver; - - // 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]; - - goto done; - } - } + result = &rpi_hw_info[i]; + printf("%08x: %s\n", rpi_hw_info[i].hwver, rpi_hw_info[i].desc); + break; } } -#endif -done: - fclose(f); return result; } - diff --git a/rpihw.h b/rpihw.h index 906ca5a6..4f941f9e 100644 --- a/rpihw.h +++ b/rpihw.h @@ -46,7 +46,7 @@ typedef struct { } rpi_hw_t; -const rpi_hw_t *rpi_hw_detect(void); +const rpi_hw_t *rpi_hw_detect(int file_desc); #endif /* __RPIHW_H__ */ diff --git a/ws2811.c b/ws2811.c index 6482796c..f4794ff5 100644 --- a/ws2811.c +++ b/ws2811.c @@ -897,13 +897,6 @@ ws2811_return_t ws2811_init(ws2811_t *ws2811) const rpi_hw_t *rpi_hw; int chan; - ws2811->rpi_hw = rpi_hw_detect(); - if (!ws2811->rpi_hw) - { - return WS2811_ERROR_HW_NOT_SUPPORTED; - } - rpi_hw = ws2811->rpi_hw; - ws2811->device = malloc(sizeof(*ws2811->device)); if (!ws2811->device) { @@ -912,6 +905,19 @@ ws2811_return_t ws2811_init(ws2811_t *ws2811) memset(ws2811->device, 0, sizeof(*ws2811->device)); device = ws2811->device; + device->mbox.handle = mbox_open(); + if (device->mbox.handle == -1) + { + return WS2811_ERROR_MAILBOX_DEVICE; + } + + ws2811->rpi_hw = rpi_hw_detect(device->mbox.handle); + if (!ws2811->rpi_hw) + { + return WS2811_ERROR_HW_NOT_SUPPORTED; + } + rpi_hw = ws2811->rpi_hw; + if (check_hwver_and_gpionum(ws2811) < 0) { return WS2811_ERROR_ILLEGAL_GPIO; @@ -938,12 +944,6 @@ ws2811_return_t ws2811_init(ws2811_t *ws2811) // Round up to page size multiple device->mbox.size = (device->mbox.size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); - device->mbox.handle = mbox_open(); - if (device->mbox.handle == -1) - { - return WS2811_ERROR_MAILBOX_DEVICE; - } - device->mbox.mem_ref = mem_alloc(device->mbox.handle, device->mbox.size, PAGE_SIZE, rpi_hw->videocore_base == 0x40000000 ? 0xC : 0x4); if (device->mbox.mem_ref == 0)