Created
April 24, 2015 15:47
-
-
Save xerpi/35ad190e2080b3b6d3e7 to your computer and use it in GitHub Desktop.
MPCore-PMR-Reader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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