diff options
-rw-r--r-- | cpu/mpc83xx/cpu_init.c | 136 | ||||
-rw-r--r-- | cpu/mpc83xx/start.S | 11 | ||||
-rw-r--r-- | include/asm-ppc/global_data.h | 4 |
3 files changed, 150 insertions, 1 deletions
diff --git a/cpu/mpc83xx/cpu_init.c b/cpu/mpc83xx/cpu_init.c index 4514dbb..ff01cf1 100644 --- a/cpu/mpc83xx/cpu_init.c +++ b/cpu/mpc83xx/cpu_init.c @@ -167,6 +167,10 @@ void cpu_init_f (volatile immap_t * im) gd->reset_status = im->reset.rsr; im->reset.rsr = ~(RSR_RES); + /* AER - Arbiter Event Register - store status */ + gd->arbiter_event_attributes = im->arbiter.aeatr; + gd->arbiter_event_address = im->arbiter.aeadr; + /* * RMR - Reset Mode Register * contains checkstop reset enable (4.6.1.4) @@ -303,6 +307,130 @@ int cpu_init_r (void) } /* + * Print out the bus arbiter event + */ +#if defined(CONFIG_DISPLAY_AER_FULL) +static int print_83xx_arb_event(int force) +{ + static char* event[] = { + "Address Time Out", + "Data Time Out", + "Address Only Transfer Type", + "External Control Word Transfer Type", + "Reserved Transfer Type", + "Transfer Error", + "reserved", + "reserved" + }; + static char* master[] = { + "e300 Core Data Transaction", + "reserved", + "e300 Core Instruction Fetch", + "reserved", + "TSEC1", + "TSEC2", + "USB MPH", + "USB DR", + "Encryption Core", + "I2C Boot Sequencer", + "JTAG", + "reserved", + "eSDHC", + "PCI1", + "PCI2", + "DMA", + "QUICC Engine 00", + "QUICC Engine 01", + "QUICC Engine 10", + "QUICC Engine 11", + "reserved", + "reserved", + "reserved", + "reserved", + "SATA1", + "SATA2", + "SATA3", + "SATA4", + "reserved", + "PCI Express 1", + "PCI Express 2", + "TDM-DMAC" + }; + static char *transfer[] = { + "Address-only, Clean Block", + "Address-only, lwarx reservation set", + "Single-beat or Burst write", + "reserved", + "Address-only, Flush Block", + "reserved", + "Burst write", + "reserved", + "Address-only, sync", + "Address-only, tlbsync", + "Single-beat or Burst read", + "Single-beat or Burst read", + "Address-only, Kill Block", + "Address-only, icbi", + "Burst read", + "reserved", + "Address-only, eieio", + "reserved", + "Single-beat write", + "reserved", + "ecowx - Illegal single-beat write", + "reserved", + "reserved", + "reserved", + "Address-only, TLB Invalidate", + "reserved", + "Single-beat or Burst read", + "reserved", + "eciwx - Illegal single-beat read", + "reserved", + "Burst read", + "reserved" + }; + + int etype = (gd->arbiter_event_attributes & AEATR_EVENT) + >> AEATR_EVENT_SHIFT; + int mstr_id = (gd->arbiter_event_attributes & AEATR_MSTR_ID) + >> AEATR_MSTR_ID_SHIFT; + int tbst = (gd->arbiter_event_attributes & AEATR_TBST) + >> AEATR_TBST_SHIFT; + int tsize = (gd->arbiter_event_attributes & AEATR_TSIZE) + >> AEATR_TSIZE_SHIFT; + int ttype = (gd->arbiter_event_attributes & AEATR_TTYPE) + >> AEATR_TTYPE_SHIFT; + + if (!force && !gd->arbiter_event_address) + return 0; + + puts("Arbiter Event Status:\n"); + printf(" Event Address: 0x%08lX\n", gd->arbiter_event_address); + printf(" Event Type: 0x%1x = %s\n", etype, event[etype]); + printf(" Master ID: 0x%02x = %s\n", mstr_id, master[mstr_id]); + printf(" Transfer Size: 0x%1x = %d bytes\n", (tbst<<3) | tsize, + tbst ? (tsize ? tsize : 8) : 16 + 8 * tsize); + printf(" Transfer Type: 0x%02x = %s\n", ttype, transfer[ttype]); + + return gd->arbiter_event_address; +} + +#elif defined(CONFIG_DISPLAY_AER_BRIEF) + +static int print_83xx_arb_event(int force) +{ + if (!force && !gd->arbiter_event_address) + return 0; + + printf("Arbiter Event Status: AEATR=0x%08lX, AEADR=0x%08lX\n", + gd->arbiter_event_attributes, gd->arbiter_event_address); + + return gd->arbiter_event_address; +} +#endif /* CONFIG_DISPLAY_AER_xxxx */ + +/* * Figure out the cause of the reset */ int prt_83xx_rsr(void) @@ -334,6 +462,12 @@ int prt_83xx_rsr(void) printf("%s%s", sep, bits[i].desc); sep = ", "; } - puts("\n\n"); + puts("\n"); + +#if defined(CONFIG_DISPLAY_AER_FULL) || defined(CONFIG_DISPLAY_AER_BRIEF) + print_83xx_arb_event(rsr & RSR_BMRS); +#endif + puts("\n"); + return 0; } diff --git a/cpu/mpc83xx/start.S b/cpu/mpc83xx/start.S index 75ad36c..e452bfb 100644 --- a/cpu/mpc83xx/start.S +++ b/cpu/mpc83xx/start.S @@ -483,6 +483,17 @@ init_e300_core: /* time t 10 */ 1: #endif /* CONFIG_WATCHDOG */ +#if defined(CONFIG_MASK_AER_AO) + /* Write the Arbiter Event Enable to mask Address Only traps. */ + /* This prevents the dcbz instruction from being trapped when */ + /* HID0_ABE Address Broadcast Enable is set and the MEMORY */ + /* COHERENCY bit is set in the WIMG bits, which is often */ + /* needed for PCI operation. */ + lwz r4, 0x0808(r3) + rlwinm r0, r4, 0, ~AER_AO + stw r0, 0x0808(r3) +#endif /* CONFIG_MASK_AER_AO */ + /* Initialize the Hardware Implementation-dependent Registers */ /* HID0 also contains cache control */ /*------------------------------------------------------*/ diff --git a/include/asm-ppc/global_data.h b/include/asm-ppc/global_data.h index c09b07d..a9366c3 100644 --- a/include/asm-ppc/global_data.h +++ b/include/asm-ppc/global_data.h @@ -122,6 +122,10 @@ typedef struct global_data { phys_size_t ram_size; /* RAM size */ unsigned long reloc_off; /* Relocation Offset */ unsigned long reset_status; /* reset status register at boot */ +#if defined(CONFIG_MPC83XX) + unsigned long arbiter_event_attributes; + unsigned long arbiter_event_address; +#endif unsigned long env_addr; /* Address of Environment struct */ unsigned long env_valid; /* Checksum of Environment valid? */ unsigned long have_console; /* serial_init() was called */ |