Skip to content

Instantly share code, notes, and snippets.

@xerpi
Created April 24, 2015 15:47
Show Gist options
  • Save xerpi/35ad190e2080b3b6d3e7 to your computer and use it in GitHub Desktop.
Save xerpi/35ad190e2080b3b6d3e7 to your computer and use it in GitHub Desktop.
MPCore-PMR-Reader
/*
* MPCore Private Memory Region "reader" by xerpi
* You have to provide a MPCore Private Memory Region dump
*/
#include <stdio.h>
#include <stdint.h>
#define NELEMS(x) (sizeof(x) / sizeof(x[0]))
#define MPCORE_PMR_SIZE (0x2000)
struct mpcore_pmr_register {
uint32_t offset;
const char *const name;
};
struct mpcore_pmr_peripheral {
uint32_t offset;
const char *const name;
struct mpcore_pmr_register registers[];
};
const struct mpcore_pmr_peripheral scu_peripheral = {
0x0000,
"SCU",
{
{0x00, "Control Register"},
{0x04, "Configuration Register"},
{0x08, "SCU CPU Status"},
{0x0C, "Invalidate all"},
{0x10, "Performance Monitor"},
{0x14, "Monitor Counter Events 0"},
{0x18, "Monitor Counter Events 1"},
{0x1C, "Monitor Counter 0"},
{0x20, "Monitor Counter 1"},
{0x24, "Monitor Counter 2"},
{0x28, "Monitor Counter 3"},
{0x2C, "Monitor Counter 4"},
{0x30, "Monitor Counter 5"},
{0x34, "Monitor Counter 6"},
{0x38, "Monitor Counter 7"},
{0, NULL}
}
};
const struct mpcore_pmr_peripheral CPU_interrupt_interfaces_peripheral = {
0x0100,
"CPU interrupt interfaces (identified by CPU transaction ID)",
{
{0x00, "Control Register"},
{0x04, "Priority Mask Register"},
{0x08, "Binary Point Register"},
{0x0C, "Interrupt Acknowledge Register"},
{0x10, "End of Interrupt Register"},
{0x14, "Running Priority Register"},
{0x18, "Highest Pending Interrupt Register"},
{0, NULL}
}
};
const struct mpcore_pmr_peripheral CPU0_interrupt_interface_peripheral = {
0x0200,
"CPU 0 interrupt interface (aliased for debug purposes)",
{
{0x00, "Control Register"},
{0x04, "Priority Mask Register"},
{0x08, "Binary Point Register"},
{0x0C, "Interrupt Acknowledge Register"},
{0x10, "End of Interrupt Register"},
{0x14, "Running Priority Register"},
{0x18, "Highest Pending Interrupt Register"},
{0, NULL}
}
};
const struct mpcore_pmr_peripheral CPU1_interrupt_interface_peripheral = {
0x0300,
"CPU 1 interrupt interface (aliased for debug purposes)",
{
{0x00, "Control Register"},
{0x04, "Priority Mask Register"},
{0x08, "Binary Point Register"},
{0x0C, "Interrupt Acknowledge Register"},
{0x10, "End of Interrupt Register"},
{0x14, "Running Priority Register"},
{0x18, "Highest Pending Interrupt Register"},
{0, NULL}
}
};
const struct mpcore_pmr_peripheral CPU2_interrupt_interface_peripheral = {
0x0400,
"CPU 2 interrupt interface (aliased for debug purposes)",
{
{0x00, "Control Register"},
{0x04, "Priority Mask Register"},
{0x08, "Binary Point Register"},
{0x0C, "Interrupt Acknowledge Register"},
{0x10, "End of Interrupt Register"},
{0x14, "Running Priority Register"},
{0x18, "Highest Pending Interrupt Register"},
{0, NULL}
}
};
const struct mpcore_pmr_peripheral CPU3_interrupt_interface_peripheral = {
0x0500,
"CPU 3 interrupt interface (aliased for debug purposes)",
{
{0x00, "Control Register"},
{0x04, "Priority Mask Register"},
{0x08, "Binary Point Register"},
{0x0C, "Interrupt Acknowledge Register"},
{0x10, "End of Interrupt Register"},
{0x14, "Running Priority Register"},
{0x18, "Highest Pending Interrupt Register"},
{0, NULL}
}
};
const struct mpcore_pmr_peripheral CPU_timer_and_watchdog_peripheral = {
0x0600,
"CPU timer and watchdog (identified by CPU transaction ID)",
{
{0x00, "Timer Load Register"},
{0x04, "Timer Counter Register"},
{0x08, "Timer Control Register"},
{0x0C, "Timer Interrupt Status Register"},
{0x20, "Watchdog Load Register"},
{0x24, "Watchdog Counter Register"},
{0x28, "Watchdog Control Register"},
{0x2C, "Watchdog Interrupt Status Register"},
{0x30, "Watchdog Reset Sent Register"},
{0x34, "Watchdog Disable Register"},
{0, NULL}
}
};
const struct mpcore_pmr_peripheral CPU0_timer_and_watchdog_peripheral = {
0x0700,
"CPU0 timer and watchdog",
{
{0x00, "Timer Load Register"},
{0x04, "Timer Counter Register"},
{0x08, "Timer Control Register"},
{0x0C, "Timer Interrupt Status Register"},
{0x20, "Watchdog Load Register"},
{0x24, "Watchdog Counter Register"},
{0x28, "Watchdog Control Register"},
{0x2C, "Watchdog Interrupt Status Register"},
{0x30, "Watchdog Reset Sent Register"},
{0x34, "Watchdog Disable Register"},
{0, NULL}
}
};
const struct mpcore_pmr_peripheral CPU1_timer_and_watchdog_peripheral = {
0x0800,
"CPU1 timer and watchdog",
{
{0x00, "Timer Load Register"},
{0x04, "Timer Counter Register"},
{0x08, "Timer Control Register"},
{0x0C, "Timer Interrupt Status Register"},
{0x20, "Watchdog Load Register"},
{0x24, "Watchdog Counter Register"},
{0x28, "Watchdog Control Register"},
{0x2C, "Watchdog Interrupt Status Register"},
{0x30, "Watchdog Reset Sent Register"},
{0x34, "Watchdog Disable Register"},
{0, NULL}
}
};
const struct mpcore_pmr_peripheral CPU2_timer_and_watchdog_peripheral = {
0x0900,
"CPU2 timer and watchdog",
{
{0x00, "Timer Load Register"},
{0x04, "Timer Counter Register"},
{0x08, "Timer Control Register"},
{0x0C, "Timer Interrupt Status Register"},
{0x20, "Watchdog Load Register"},
{0x24, "Watchdog Counter Register"},
{0x28, "Watchdog Control Register"},
{0x2C, "Watchdog Interrupt Status Register"},
{0x30, "Watchdog Reset Sent Register"},
{0x34, "Watchdog Disable Register"},
{0, NULL}
}
};
const struct mpcore_pmr_peripheral CPU3_timer_and_watchdog_peripheral = {
0x0A00,
"CPU3 timer and watchdog",
{
{0x00, "Timer Load Register"},
{0x04, "Timer Counter Register"},
{0x08, "Timer Control Register"},
{0x0C, "Timer Interrupt Status Register"},
{0x20, "Watchdog Load Register"},
{0x24, "Watchdog Counter Register"},
{0x28, "Watchdog Control Register"},
{0x2C, "Watchdog Interrupt Status Register"},
{0x30, "Watchdog Reset Sent Register"},
{0x34, "Watchdog Disable Register"},
{0, NULL}
}
};
const struct mpcore_pmr_peripheral global_interrupt_distributor_peripheral = {
0x1000,
"Global Interrupt distributor",
{
{0x00, "Interrupt Distributor Control Register"},
{0x04, "Interrupt Controller Type Register"},
{0x100, "Interrupt Enable set Registers ID0-ID31"},
{0x180, "Interrupt Enable clear Registers ID0-ID31"},
{0x200, "Interrupt Pending set Registers"},
{0x280, "Interrupt Pending clear Registers"},
{0x300, "Interrupt Active Bit Registers"},
{0x400, "Interrupt Priority Registers"},
{0x800, "Interrupt CPU targets Registers"},
{0xC00, "Interrupt Configuration Registers, ID0-ID15"},
{0xC04, "Interrupt Configuration Registers, ID29-ID31"},
{0xD00, "Interrupt Line Level Registers ID0-ID31"},
{0xF00, "Software Interrupt Register"},
{0xFE0, "Peripheral Identification Register 0"},
{0xFE4, "Peripheral Identification Register 1"},
{0xFE8, "Peripheral Identification Register 2"},
{0xFEC, "Peripheral Identification Register 3"},
{0xFF0, "PrimeCell Identification Register 0"},
{0xFF4, "PrimeCell Identification Register 1"},
{0xFF8, "PrimeCell Identification Register 2"},
{0xFFC, "PrimeCell Identification Register 3"},
{0, NULL}
}
};
const struct mpcore_pmr_peripheral *const peripheral_array[] = {
&scu_peripheral,
&CPU_interrupt_interfaces_peripheral,
&CPU0_interrupt_interface_peripheral,
&CPU1_interrupt_interface_peripheral,
&CPU2_interrupt_interface_peripheral,
&CPU3_interrupt_interface_peripheral,
&CPU_timer_and_watchdog_peripheral,
&CPU0_timer_and_watchdog_peripheral,
&CPU1_timer_and_watchdog_peripheral,
&CPU2_timer_and_watchdog_peripheral,
&CPU3_timer_and_watchdog_peripheral,
&global_interrupt_distributor_peripheral
};
int main(int argc, char *argv[])
{
if (argc < 2) {
printf("Usage: mpcore-pmr-reader file.bin\n");
return -1;
}
FILE *fp = fopen(argv[1], "rb");
if (fp == NULL) {
printf("Error opening \"%s\"\n", argv[1]);
return -1;
}
unsigned char buffer[MPCORE_PMR_SIZE];
size_t n = fread(buffer, 1, MPCORE_PMR_SIZE, fp);
if (n != MPCORE_PMR_SIZE) {
printf("Error reading from \"%s\"\n", argv[1]);
fclose(fp);
return -1;
}
fclose(fp);
int i;
for (i = 0; i < NELEMS(peripheral_array); i++) {
printf("%s - base offset: 0x%04X\n",
peripheral_array[i]->name,
peripheral_array[i]->offset);
int j = 0;
while ((peripheral_array[i]->registers[j].offset != 0) ||
(peripheral_array[i]->registers[j].name != NULL)) {
printf("\t0x%08X - %s\n",
*(uint32_t *)(
(uintptr_t)buffer +
peripheral_array[i]->offset +
peripheral_array[i]->registers[j].offset),
peripheral_array[i]->registers[j].name
);
j++;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment