Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added generic RPI cpu detection based on the revision string. #183

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
57 changes: 55 additions & 2 deletions rpihw.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,30 @@
#define VIDEOCORE_BASE_RPI 0x40000000
#define VIDEOCORE_BASE_RPI2 0xc0000000

#define RPI_SCHEME_SHIFT 23
#define RPI_SCHEME_MASK (0x1 << 23)
#define RPI_CPU_SHIFT 12
#define RPI_CPU_MASK (0xf << 12)

#define RPI_MANUFACTURER_MASK (0xf << 16)
#define RPI_WARRANTY_MASK (0x3 << 24)

static rpi_hw_t rpi_hw_bcm2835 = {
.hwver = 0x00,
.type = RPI_HWVER_TYPE_PI1,
.periph_base = PERIPH_BASE_RPI,
.videocore_base = VIDEOCORE_BASE_RPI,
.desc = "Default bcm2835",
};

static rpi_hw_t rpi_hw_bcm2836 = {
.hwver = 0x00,
.type = RPI_HWVER_TYPE_PI2,
.periph_base = PERIPH_BASE_RPI2,
.videocore_base = VIDEOCORE_BASE_RPI2,
.desc = "Default bcm2836/7",
};

static const rpi_hw_t rpi_hw_info[] = {
//
// Model B Rev 1.0
Expand Down Expand Up @@ -311,6 +332,7 @@ static const rpi_hw_t rpi_hw_info[] = {
const rpi_hw_t *rpi_hw_detect(void)
{
FILE *f = fopen("/proc/cpuinfo", "r");
// FILE *f = fopen("/tmp/cpuinfo", "r");
char line[LINE_WIDTH_MAX];
const rpi_hw_t *result = NULL;

Expand All @@ -324,6 +346,9 @@ const rpi_hw_t *rpi_hw_detect(void)
if (strstr(line, HW_VER_STRING))
{
uint32_t rev;
uint32_t rpi_rev;
uint8_t rpi_cpu;

char *substr;
unsigned i;

Expand All @@ -334,19 +359,20 @@ const rpi_hw_t *rpi_hw_detect(void)
}

errno = 0;
rev = strtoul(&substr[1], NULL, 16); // Base 16
rpi_rev = strtoul(&substr[1], NULL, 16); // Base 16
if (errno)
{
continue;
}
rpi_cpu = (rpi_rev & RPI_CPU_MASK) >> RPI_CPU_SHIFT;

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);
rev = rpi_rev & ~(RPI_WARRANTY_MASK | RPI_MANUFACTURER_MASK);

if (rev == hwver)
{
Expand All @@ -355,12 +381,39 @@ const rpi_hw_t *rpi_hw_detect(void)
goto done;
}
}


// none of the fixed models were matched, use the logic from :
// https://gist.github.com/petarov/61bc90a8b0d27c8f7e846ff81871dfa7
if (rpi_rev & RPI_SCHEME_MASK)
{
if ( (rpi_cpu == 1) || (rpi_cpu == 2) )
{
rpi_hw_bcm2836.hwver = rpi_rev;
result = &rpi_hw_bcm2836;
goto done;
}
if (rpi_cpu == 0)
{
rpi_hw_bcm2835.hwver = rpi_rev;
result = &rpi_hw_bcm2835;
goto done;
}
}
else if (rpi_rev <= 0x15)
{
rpi_hw_bcm2835.hwver = rpi_rev;
result = &rpi_hw_bcm2835;
goto done;
}
}
}


done:
fclose(f);

//if (result) printf ("matched board %s, revision %x, periph base 0x%x\n", result->desc, result->hwver, result->periph_base);
return result;
}