summaryrefslogtreecommitdiff
path: root/cpu/ppc4xx
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/ppc4xx')
-rw-r--r--cpu/ppc4xx/405gp_pci.c30
-rw-r--r--cpu/ppc4xx/44x_spd_ddr.c36
-rw-r--r--cpu/ppc4xx/44x_spd_ddr2.c82
-rw-r--r--cpu/ppc4xx/config.mk10
-rw-r--r--cpu/ppc4xx/cpu_init.c4
-rw-r--r--cpu/ppc4xx/gpio.c42
-rw-r--r--cpu/ppc4xx/start.S447
-rw-r--r--cpu/ppc4xx/tlb.c85
-rwxr-xr-x[-rw-r--r--]cpu/ppc4xx/traps.c176
9 files changed, 567 insertions, 345 deletions
diff --git a/cpu/ppc4xx/405gp_pci.c b/cpu/ppc4xx/405gp_pci.c
index 8bf03e1..2837929 100644
--- a/cpu/ppc4xx/405gp_pci.c
+++ b/cpu/ppc4xx/405gp_pci.c
@@ -77,11 +77,21 @@
#include <asm/processor.h>
#include <pci.h>
+#ifdef CONFIG_PCI
+
DECLARE_GLOBAL_DATA_PTR;
-#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
+/*
+ * Board-specific pci initialization
+ * Platform code can reimplement pci_pre_init() if needed
+ */
+int __pci_pre_init(struct pci_controller *hose)
+{
+ return 1;
+}
+int pci_pre_init(struct pci_controller *hose) __attribute__((weak, alias("__pci_pre_init")));
-#ifdef CONFIG_PCI
+#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
#if defined(CONFIG_PMC405)
ushort pmc405_pci_subsys_deviceid(void);
@@ -191,6 +201,13 @@ void pci_405gp_init(struct pci_controller *hose)
if (hose->pci_fb)
pciauto_region_init(hose->pci_fb);
+ /* Let board change/modify hose & do initial checks */
+ if (pci_pre_init (hose) == 0) {
+ printf("PCI: Board-specific initialization failed.\n");
+ printf("PCI: Configuration aborted.\n");
+ return;
+ }
+
pci_register_hose(hose);
/*--------------------------------------------------------------------------+
@@ -416,14 +433,12 @@ void pci_init_board(void)
#endif
-#endif /* CONFIG_PCI */
-
#endif /* CONFIG_405GP */
/*-----------------------------------------------------------------------------+
* CONFIG_440
*-----------------------------------------------------------------------------*/
-#if defined(CONFIG_440) && defined(CONFIG_PCI)
+#if defined(CONFIG_440)
static struct pci_controller ppc440_hose = {0};
@@ -496,14 +511,12 @@ void pci_440_init (struct pci_controller *hose)
pci_setup_indirect(hose, PCIX0_CFGADR, PCIX0_CFGDATA);
-#if defined(CFG_PCI_PRE_INIT)
/* Let board change/modify hose & do initial checks */
if (pci_pre_init (hose) == 0) {
printf("PCI: Board-specific initialization failed.\n");
printf("PCI: Configuration aborted.\n");
return;
}
-#endif
pci_register_hose( hose );
@@ -575,4 +588,5 @@ void pci_init_board(void)
#endif
}
-#endif /* CONFIG_440 & CONFIG_PCI */
+#endif /* CONFIG_440 */
+#endif /* CONFIG_PCI */
diff --git a/cpu/ppc4xx/44x_spd_ddr.c b/cpu/ppc4xx/44x_spd_ddr.c
index c500d3f..8c18d0f 100644
--- a/cpu/ppc4xx/44x_spd_ddr.c
+++ b/cpu/ppc4xx/44x_spd_ddr.c
@@ -70,6 +70,15 @@
#define ONE_BILLION 1000000000
+/*
+ * Board-specific Platform code can reimplement spd_ddr_init_hang () if needed
+ */
+void __spd_ddr_init_hang (void)
+{
+ hang ();
+}
+void spd_ddr_init_hang (void) __attribute__((weak, alias("__spd_ddr_init_hang")));
+
/*-----------------------------------------------------------------------------
| Memory Controller Options 0
+-----------------------------------------------------------------------------*/
@@ -262,7 +271,7 @@ typedef struct bank_param BANKPARMS;
#ifdef CFG_SIMULATE_SPD_EEPROM
extern unsigned char cfg_simulate_spd_eeprom[128];
#endif
-void program_tlb(u32 start, u32 size, u32 tlb_word2_i_value);
+void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value);
static unsigned char spd_read(uchar chip, uint addr);
static void get_spd_info(unsigned long *dimm_populated,
@@ -373,7 +382,7 @@ long int spd_sdram(void) {
#ifdef CONFIG_PROG_SDRAM_TLB /* this define should eventually be removed */
/* and program tlb entries for this size (dynamic) */
- program_tlb(0, total_size, MY_TLB_WORD2_I_ENABLE);
+ program_tlb(0, 0, total_size, MY_TLB_WORD2_I_ENABLE);
#endif
/*
@@ -467,7 +476,7 @@ static void get_spd_info(unsigned long *dimm_populated,
if (dimm_found == FALSE) {
printf("ERROR - No memory installed. Install a DDR-SDRAM DIMM.\n\n");
- hang();
+ spd_ddr_init_hang ();
}
}
@@ -490,7 +499,7 @@ static void check_mem_type(unsigned long *dimm_populated,
dimm_num);
printf("Only DDR SDRAM DIMMs are supported.\n");
printf("Replace the DIMM module with a supported DIMM.\n\n");
- hang();
+ spd_ddr_init_hang ();
break;
}
}
@@ -510,7 +519,7 @@ static void check_volt_type(unsigned long *dimm_populated,
if (voltage_type != 0x04) {
printf("ERROR: DIMM %lu with unsupported voltage level.\n",
dimm_num);
- hang();
+ spd_ddr_init_hang ();
} else {
debug("DIMM %lu voltage level supported.\n", dimm_num);
}
@@ -581,7 +590,7 @@ static void program_cfg0(unsigned long *dimm_populated,
printf("WARNING: DIMM with datawidth of %lu bits.\n",
data_width);
printf("Only DIMMs with 32 or 64 bit datawidths supported.\n");
- hang();
+ spd_ddr_init_hang ();
}
break;
}
@@ -769,7 +778,7 @@ static void program_tr0(unsigned long *dimm_populated,
if ((tcyc_reg & 0x0F) >= 10) {
printf("ERROR: Tcyc incorrect for DIMM in slot %lu\n",
dimm_num);
- hang();
+ spd_ddr_init_hang ();
}
cycle_time_ns_x_10[cas_index] =
@@ -849,7 +858,7 @@ static void program_tr0(unsigned long *dimm_populated,
printf("ERROR: No supported CAS latency with the installed DIMMs.\n");
printf("Only CAS latencies of 2.0, 2.5, and 3.0 are supported.\n");
printf("Make sure the PLB speed is within the supported range.\n");
- hang();
+ spd_ddr_init_hang ();
}
/*
@@ -1008,6 +1017,7 @@ static int short_mem_test(void)
*/
for (i = 0; i < NUMMEMTESTS; i++) {
for (j = 0; j < NUMMEMWORDS; j++) {
+//printf("bank enabled base:%x\n", &membase[j]);
membase[j] = test[i][j];
ppcDcbf((unsigned long)&(membase[j]));
}
@@ -1160,7 +1170,7 @@ static void program_tr1(void)
*/
if (window_found == FALSE) {
printf("ERROR: Cannot determine a common read delay.\n");
- hang();
+ spd_ddr_init_hang ();
}
/*
@@ -1310,7 +1320,7 @@ static unsigned long program_bxcr(unsigned long *dimm_populated,
printf("ERROR: Unsupported value for the banksize: %d.\n",
bank_size_id);
printf("Replace the DIMM module with a supported DIMM.\n\n");
- hang();
+ spd_ddr_init_hang ();
}
switch (num_col_addr) {
@@ -1332,7 +1342,7 @@ static unsigned long program_bxcr(unsigned long *dimm_populated,
printf("ERROR: Unsupported value for number of "
"column addresses: %d.\n", num_col_addr);
printf("Replace the DIMM module with a supported DIMM.\n\n");
- hang();
+ spd_ddr_init_hang ();
}
/*
@@ -1340,14 +1350,14 @@ static unsigned long program_bxcr(unsigned long *dimm_populated,
*/
cr |= SDRAM_BXCR_SDBE;
- for (i = 0; i < num_banks; i++) {
+ for (i = 0; i < num_banks; i++) {
bank_parms[ctrl_bank_num[dimm_num]+i].bank_size_bytes =
(4 << 20) * bank_size_id;
bank_parms[ctrl_bank_num[dimm_num]+i].cr = cr;
debug("DIMM%d-bank %d (SDRAM0_B%dCR): bank_size_bytes=%d\n",
dimm_num, i, ctrl_bank_num[dimm_num]+i,
bank_parms[ctrl_bank_num[dimm_num]+i].bank_size_bytes);
- }
+ }
}
}
diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c
index 48b9ee2..5fef27b 100644
--- a/cpu/ppc4xx/44x_spd_ddr2.c
+++ b/cpu/ppc4xx/44x_spd_ddr2.c
@@ -58,8 +58,8 @@
#define SDRAM_DDR2 2
#define SDRAM_NONE 0
-#define MAXDIMMS 2
-#define MAXRANKS 4
+#define MAXDIMMS 2
+#define MAXRANKS 4
#define MAXBXCF 4
#define MAX_SPD_BYTES 256 /* Max number of bytes on the DIMM's SPD EEPROM */
@@ -129,6 +129,16 @@
#define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE /* disable caching on SDRAM */
#endif
+/*
+ * Board-specific Platform code can reimplement spd_ddr_init_hang () if needed
+ */
+void __spd_ddr_init_hang (void)
+{
+ hang ();
+}
+void spd_ddr_init_hang (void) __attribute__((weak, alias("__spd_ddr_init_hang")));
+
+
/* Private Structure Definitions */
/* enum only to ease code for cas latency setting */
@@ -144,7 +154,7 @@ typedef enum ddr_cas_id {
* Prototypes
*-----------------------------------------------------------------------------*/
static unsigned long sdram_memsize(void);
-void program_tlb(u32 start, u32 size, u32 tlb_word2_i_value);
+void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value);
static void get_spd_info(unsigned long *dimm_populated,
unsigned char *iic0_dimm_addr,
unsigned long num_dimm_banks);
@@ -528,7 +538,7 @@ long int initdram(int board_type)
dram_size = sdram_memsize();
/* and program tlb entries for this size (dynamic) */
- program_tlb(0, dram_size, MY_TLB_WORD2_I_ENABLE);
+ program_tlb(0, 0, dram_size, MY_TLB_WORD2_I_ENABLE);
/*------------------------------------------------------------------
* DQS calibration.
@@ -582,7 +592,7 @@ static void get_spd_info(unsigned long *dimm_populated,
if (dimm_found == FALSE) {
printf("ERROR - No memory installed. Install a DDR-SDRAM DIMM.\n\n");
- hang();
+ spd_ddr_init_hang ();
}
}
@@ -629,42 +639,42 @@ static void check_mem_type(unsigned long *dimm_populated,
"slot %d.\n", (unsigned int)dimm_num);
printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");
printf("Replace the DIMM module with a supported DIMM.\n\n");
- hang();
+ spd_ddr_init_hang ();
break;
case 2:
printf("ERROR: EDO DIMM detected in slot %d.\n",
(unsigned int)dimm_num);
printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");
printf("Replace the DIMM module with a supported DIMM.\n\n");
- hang();
+ spd_ddr_init_hang ();
break;
case 3:
printf("ERROR: Pipelined Nibble DIMM detected in slot %d.\n",
(unsigned int)dimm_num);
printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");
printf("Replace the DIMM module with a supported DIMM.\n\n");
- hang();
+ spd_ddr_init_hang ();
break;
case 4:
printf("ERROR: SDRAM DIMM detected in slot %d.\n",
(unsigned int)dimm_num);
printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");
printf("Replace the DIMM module with a supported DIMM.\n\n");
- hang();
+ spd_ddr_init_hang ();
break;
case 5:
printf("ERROR: Multiplexed ROM DIMM detected in slot %d.\n",
(unsigned int)dimm_num);
printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");
printf("Replace the DIMM module with a supported DIMM.\n\n");
- hang();
+ spd_ddr_init_hang ();
break;
case 6:
printf("ERROR: SGRAM DIMM detected in slot %d.\n",
(unsigned int)dimm_num);
printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n");
printf("Replace the DIMM module with a supported DIMM.\n\n");
- hang();
+ spd_ddr_init_hang ();
break;
case 7:
debug("DIMM slot %d: DDR1 SDRAM detected\n", dimm_num);
@@ -679,7 +689,7 @@ static void check_mem_type(unsigned long *dimm_populated,
(unsigned int)dimm_num);
printf("Only DDR1 and DDR2 SDRAM DIMMs are supported.\n");
printf("Replace the DIMM module with a supported DIMM.\n\n");
- hang();
+ spd_ddr_init_hang ();
break;
}
}
@@ -689,7 +699,7 @@ static void check_mem_type(unsigned long *dimm_populated,
&& (dimm_populated[dimm_num] != SDRAM_NONE)
&& (dimm_populated[dimm_num-1] != dimm_populated[dimm_num])) {
printf("ERROR: DIMM's DDR1 and DDR2 type can not be mixed.\n");
- hang();
+ spd_ddr_init_hang ();
}
}
}
@@ -764,7 +774,7 @@ static void check_frequency(unsigned long *dimm_populated,
(unsigned int)(calc_cycle_time*10));
printf("Replace the DIMM, or change DDR frequency via "
"strapping bits.\n\n");
- hang();
+ spd_ddr_init_hang ();
}
}
}
@@ -796,7 +806,7 @@ static void check_rank_number(unsigned long *dimm_populated,
"slot %d is not supported.\n", dimm_rank, dimm_num);
printf("Only %d ranks are supported for all DIMM.\n", MAXRANKS);
printf("Replace the DIMM module with a supported DIMM.\n\n");
- hang();
+ spd_ddr_init_hang ();
} else
total_rank += dimm_rank;
}
@@ -805,7 +815,7 @@ static void check_rank_number(unsigned long *dimm_populated,
"for all slots.\n", (unsigned int)total_rank);
printf("Only %d ranks are supported for all DIMM.\n", MAXRANKS);
printf("Remove one of the DIMM modules.\n\n");
- hang();
+ spd_ddr_init_hang ();
}
}
}
@@ -830,28 +840,28 @@ static void check_voltage_type(unsigned long *dimm_populated,
printf("This DIMM is 5.0 Volt/TTL.\n");
printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",
(unsigned int)dimm_num);
- hang();
+ spd_ddr_init_hang ();
break;
case 0x01:
printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n");
printf("This DIMM is LVTTL.\n");
printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",
(unsigned int)dimm_num);
- hang();
+ spd_ddr_init_hang ();
break;
case 0x02:
printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n");
printf("This DIMM is 1.5 Volt.\n");
printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",
(unsigned int)dimm_num);
- hang();
+ spd_ddr_init_hang ();
break;
case 0x03:
printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n");
printf("This DIMM is 3.3 Volt/TTL.\n");
printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",
(unsigned int)dimm_num);
- hang();
+ spd_ddr_init_hang ();
break;
case 0x04:
/* 2.5 Voltage only for DDR1 */
@@ -863,7 +873,7 @@ static void check_voltage_type(unsigned long *dimm_populated,
printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n");
printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n",
(unsigned int)dimm_num);
- hang();
+ spd_ddr_init_hang ();
break;
}
}
@@ -1006,13 +1016,13 @@ static void program_copt1(unsigned long *dimm_populated,
if ((dimm_populated[0] != SDRAM_NONE) && (dimm_populated[1] != SDRAM_NONE)) {
if (buf0 != buf1) {
printf("ERROR: DIMM's buffered/unbuffered, registered, clocking don't match.\n");
- hang();
+ spd_ddr_init_hang ();
}
}
if ((dimm_64bit == TRUE) && (dimm_32bit == TRUE)) {
printf("ERROR: Cannot mix 32 bit and 64 bit DDR-SDRAM DIMMs together.\n");
- hang();
+ spd_ddr_init_hang ();
}
else if ((dimm_64bit == TRUE) && (dimm_32bit == FALSE)) {
mcopt1 |= SDRAM_MCOPT1_DMWD_64;
@@ -1020,7 +1030,7 @@ static void program_copt1(unsigned long *dimm_populated,
mcopt1 |= SDRAM_MCOPT1_DMWD_32;
} else {
printf("ERROR: Please install only 32 or 64 bit DDR-SDRAM DIMMs.\n\n");
- hang();
+ spd_ddr_init_hang ();
}
if (ecc_enabled == TRUE)
@@ -1209,7 +1219,7 @@ static void program_initplr(unsigned long *dimm_populated,
break;
default:
printf("ERROR: ucode error on selected_cas value %d", selected_cas);
- hang();
+ spd_ddr_init_hang ();
break;
}
@@ -1241,7 +1251,7 @@ static void program_initplr(unsigned long *dimm_populated,
break;
default:
printf("ERROR: write recovery not support (%d)", write_recovery);
- hang();
+ spd_ddr_init_hang ();
break;
}
#else
@@ -1259,7 +1269,7 @@ static void program_initplr(unsigned long *dimm_populated,
ods = ODS_REDUCED;
} else {
printf("ERROR: Unsupported number of DIMM's (%d)", total_dimm);
- hang();
+ spd_ddr_init_hang ();
}
mr = CMD_EMR | SELECT_MR | BURST_LEN_4 | wr | cas;
@@ -1284,7 +1294,7 @@ static void program_initplr(unsigned long *dimm_populated,
mtsdram(SDRAM_INITPLR13, 0x80800000 | emr); /* EMR OCD Exit */
} else {
printf("ERROR: ucode error as unknown DDR type in program_initplr");
- hang();
+ spd_ddr_init_hang ();
}
}
@@ -1389,7 +1399,7 @@ static void program_mode(unsigned long *dimm_populated,
} else {
printf("ERROR: SPD reported Tcyc is incorrect for DIMM "
"in slot %d\n", (unsigned int)dimm_num);
- hang();
+ spd_ddr_init_hang ();
}
} else {
/* Convert from hex to decimal */
@@ -1526,7 +1536,7 @@ static void program_mode(unsigned long *dimm_populated,
printf("ERROR: Cannot find a supported CAS latency with the installed DIMMs.\n");
printf("Only DIMMs DDR1 with CAS latencies of 2.0, 2.5, and 3.0 are supported.\n");
printf("Make sure the PLB speed is within the supported range of the DIMMs.\n\n");
- hang();
+ spd_ddr_init_hang ();
}
} else { /* DDR2 */
debug("cas_3_0_available=%d\n", cas_3_0_available);
@@ -1549,7 +1559,7 @@ static void program_mode(unsigned long *dimm_populated,
cas_3_0_available, cas_4_0_available, cas_5_0_available);
printf("sdram_freq=%d cycle3=%d cycle4=%d cycle5=%d\n\n",
sdram_freq, cycle_3_0_clk, cycle_4_0_clk, cycle_5_0_clk);
- hang();
+ spd_ddr_init_hang ();
}
}
@@ -1658,7 +1668,7 @@ static void program_rtr(unsigned long *dimm_populated,
printf("ERROR: DIMM %d unsupported refresh rate/type.\n",
(unsigned int)dimm_num);
printf("Replace the DIMM module with a supported DIMM.\n\n");
- hang();
+ spd_ddr_init_hang ();
break;
}
@@ -2066,7 +2076,7 @@ static void program_bxcf(unsigned long *dimm_populated,
printf("ERROR: Unsupported value for number of "
"column addresses: %d.\n", (unsigned int)num_col_addr);
printf("Replace the DIMM module with a supported DIMM.\n\n");
- hang();
+ spd_ddr_init_hang ();
}
}
@@ -2148,7 +2158,7 @@ static void program_memory_queue(unsigned long *dimm_populated,
printf("ERROR: Unsupported value for the banksize: %d.\n",
(unsigned int)rank_size_id);
printf("Replace the DIMM module with a supported DIMM.\n\n");
- hang();
+ spd_ddr_init_hang ();
}
if ((dimm_populated[dimm_num] != SDRAM_NONE) && (dimm_num == 1))
@@ -2693,7 +2703,7 @@ calibration_loop:
printf("\nERROR: Cannot determine a common read delay for the "
"DIMM(s) installed.\n");
debug("%s[%d] ERROR : \n", __FUNCTION__,__LINE__);
- hang();
+ spd_ddr_init_hang ();
}
blank_string(strlen(str));
@@ -2849,7 +2859,7 @@ static void test(void)
if (window_found == FALSE) {
printf("ERROR: Cannot determine a common read delay for the "
"DIMM(s) installed.\n");
- hang();
+ spd_ddr_init_hang ();
}
/*------------------------------------------------------------------
diff --git a/cpu/ppc4xx/config.mk b/cpu/ppc4xx/config.mk
index 119e061..4fd5108 100644
--- a/cpu/ppc4xx/config.mk
+++ b/cpu/ppc4xx/config.mk
@@ -22,5 +22,13 @@
#
PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi -fno-strict-aliasing
+PLATFORM_CPPFLAGS += -DCONFIG_4xx -ffixed-r2 -ffixed-r29 -mstring -msoft-float
-PLATFORM_CPPFLAGS += -DCONFIG_4xx -ffixed-r2 -ffixed-r29 -mstring -Wa,-m405 -mcpu=405 -msoft-float
+cfg=$(shell grep configs $(OBJTREE)/include/config.h | sed 's/.*<\(configs.*\)>/\1/')
+is440=$(shell grep CONFIG_440 $(TOPDIR)/include/$(cfg))
+
+ifneq (,$(findstring CONFIG_440,$(is440)))
+PLATFORM_CPPFLAGS += -Wa,-m440 -mcpu=440
+else
+PLATFORM_CPPFLAGS += -Wa,-m405 -mcpu=405
+endif
diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c
index 66e8637..351da36 100644
--- a/cpu/ppc4xx/cpu_init.c
+++ b/cpu/ppc4xx/cpu_init.c
@@ -153,7 +153,7 @@ cpu_init_f (void)
*/
asm volatile(" bl 0f" ::: "lr");
asm volatile("0: mflr 3" ::: "r3");
- asm volatile(" addi 4, 0, 14" ::: "r4");
+ asm volatile(" addi 4, 0, 14" ::: "r4");
asm volatile(" mtctr 4" ::: "ctr");
asm volatile("1: icbt 0, 3");
asm volatile(" addi 3, 3, 32" ::: "r3");
@@ -211,6 +211,8 @@ cpu_init_f (void)
val = mfspr(tcr);
#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
val |= 0xb8000000; /* generate system reset after 1.34 seconds */
+#elif defined(CONFIG_440EPX)
+ val |= 0xb0000000; /* generate system reset after 1.34 seconds */
#else
val |= 0xf0000000; /* generate system reset after 2.684 seconds */
#endif
diff --git a/cpu/ppc4xx/gpio.c b/cpu/ppc4xx/gpio.c
index dd84e58..5235203 100644
--- a/cpu/ppc4xx/gpio.c
+++ b/cpu/ppc4xx/gpio.c
@@ -103,6 +103,18 @@ void gpio_write_bit(int pin, int val)
out32(GPIO0_OR + offs, in32(GPIO0_OR + offs) & ~GPIO_VAL(pin));
}
+int gpio_read_out_bit(int pin)
+{
+ u32 offs = 0;
+
+ if (pin >= GPIO_MAX) {
+ offs = 0x100;
+ pin -= GPIO_MAX;
+ }
+
+ return (in32(GPIO0_OR + offs) & GPIO_VAL(pin) ? 1 : 0);
+}
+
#if defined(CFG_440_GPIO_TABLE)
void gpio_set_chip_configuration(void)
{
@@ -157,12 +169,38 @@ void gpio_set_chip_configuration(void)
switch (gpio_tab[gpio_core][i].alt_nb) {
case GPIO_SEL:
if (gpio_core == GPIO0) {
- reg = in32(GPIO0_TCR) | (0x80000000 >> (j));
+ /*
+ * Setup output value
+ * 1 -> high level
+ * 0 -> low level
+ * else -> don't touch
+ */
+ reg = in32(GPIO0_OR);
+ if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1)
+ reg |= (0x80000000 >> (i));
+ else if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_0)
+ reg &= ~(0x80000000 >> (i));
+ out32(GPIO0_OR, reg);
+
+ reg = in32(GPIO0_TCR) | (0x80000000 >> (i));
out32(GPIO0_TCR, reg);
}
if (gpio_core == GPIO1) {
- reg = in32(GPIO1_TCR) | (0x80000000 >> (j));
+ /*
+ * Setup output value
+ * 1 -> high level
+ * 0 -> low level
+ * else -> don't touch
+ */
+ reg = in32(GPIO0_OR);
+ if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1)
+ reg |= (0x80000000 >> (i));
+ else if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_0)
+ reg &= ~(0x80000000 >> (i));
+ out32(GPIO0_OR, reg);
+
+ reg = in32(GPIO1_TCR) | (0x80000000 >> (i));
out32(GPIO1_TCR, reg);
}
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index 78d0042..8ecaaea 100644
--- a/cpu/ppc4xx/start.S
+++ b/cpu/ppc4xx/start.S
@@ -22,26 +22,27 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
-/*------------------------------------------------------------------------------+ */
-/* */
-/* This source code has been made available to you by IBM on an AS-IS */
-/* basis. Anyone receiving this source is licensed under IBM */
-/* copyrights to use it in any way he or she deems fit, including */
-/* copying it, modifying it, compiling it, and redistributing it either */
-/* with or without modifications. No license under IBM patents or */
-/* patent applications is to be implied by the copyright license. */
-/* */
-/* Any user of this software should understand that IBM cannot provide */
-/* technical support for this software and will not be responsible for */
-/* any consequences resulting from the use of this software. */
-/* */
-/* Any person who transfers this source code or any derivative work */
-/* must include the IBM copyright notice, this paragraph, and the */
-/* preceding two paragraphs in the transferred software. */
-/* */
-/* COPYRIGHT I B M CORPORATION 1995 */
-/* LICENSED MATERIAL - PROGRAM PROPERTY OF I B M */
-/*------------------------------------------------------------------------------- */
+/*------------------------------------------------------------------------------+
+ *
+ * This source code has been made available to you by IBM on an AS-IS
+ * basis. Anyone receiving this source is licensed under IBM
+ * copyrights to use it in any way he or she deems fit, including
+ * copying it, modifying it, compiling it, and redistributing it either
+ * with or without modifications. No license under IBM patents or
+ * patent applications is to be implied by the copyright license.
+ *
+ * Any user of this software should understand that IBM cannot provide
+ * technical support for this software and will not be responsible for
+ * any consequences resulting from the use of this software.
+ *
+ * Any person who transfers this source code or any derivative work
+ * must include the IBM copyright notice, this paragraph, and the
+ * preceding two paragraphs in the transferred software.
+ *
+ * COPYRIGHT I B M CORPORATION 1995
+ * LICENSED MATERIAL - PROGRAM PROPERTY OF I B M
+ *-------------------------------------------------------------------------------
+ */
/* U-Boot - Startup Code for AMCC 4xx PowerPC based Embedded Boards
*
@@ -59,7 +60,6 @@
* address and (s)dram will be positioned at address 0
*/
#include <config.h>
-#include <mpc8xx.h>
#include <ppc4xx.h>
#include <version.h>
@@ -110,11 +110,11 @@
# endif
#endif /* CFG_INIT_DCACHE_CS */
-#define function_prolog(func_name) .text; \
+#define function_prolog(func_name) .text; \
.align 2; \
.globl func_name; \
func_name:
-#define function_epilog(func_name) .type func_name,@function; \
+#define function_epilog(func_name) .type func_name,@function; \
.size func_name,.-func_name
/* We don't want the MMU yet.
@@ -294,11 +294,13 @@ skip_debug_init:
mtspr ivor7,r1 /* Floating point unavailable */
li r1,0x0c00
mtspr ivor8,r1 /* System call */
- li r1,0x1000
- mtspr ivor10,r1 /* Decrementer (PIT for 440) */
- li r1,0x1400
- mtspr ivor13,r1 /* Data TLB error */
+ li r1,0x0a00
+ mtspr ivor9,r1 /* Auxiliary Processor unavailable */
+ li r1,0x0900
+ mtspr ivor10,r1 /* Decrementer */
li r1,0x1300
+ mtspr ivor13,r1 /* Data TLB error */
+ li r1,0x1400
mtspr ivor14,r1 /* Instr TLB error */
li r1,0x2000
mtspr ivor15,r1 /* Debug */
@@ -503,11 +505,81 @@ version_string:
.ascii " (", __DATE__, " - ", __TIME__, ")"
.ascii CONFIG_IDENT_STRING, "\0"
-/*
- * Maybe this should be moved somewhere else because the current
- * location (0x100) is where the CriticalInput Execption should be.
- */
. = EXC_OFF_SYS_RESET
+ .globl _start_of_vectors
+_start_of_vectors:
+
+/* Critical input. */
+ CRIT_EXCEPTION(0x100, CritcalInput, UnknownException)
+
+#ifdef CONFIG_440
+/* Machine check */
+ MCK_EXCEPTION(0x200, MachineCheck, MachineCheckException)
+#else
+ CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
+#endif /* CONFIG_440 */
+
+/* Data Storage exception. */
+ STD_EXCEPTION(0x300, DataStorage, UnknownException)
+
+/* Instruction Storage exception. */
+ STD_EXCEPTION(0x400, InstStorage, UnknownException)
+
+/* External Interrupt exception. */
+ STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
+
+/* Alignment exception. */
+ . = 0x600
+Alignment:
+ EXCEPTION_PROLOG(SRR0, SRR1)
+ mfspr r4,DAR
+ stw r4,_DAR(r21)
+ mfspr r5,DSISR
+ stw r5,_DSISR(r21)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
+ lwz r6,GOT(transfer_to_handler)
+ mtlr r6
+ blrl
+.L_Alignment:
+ .long AlignmentException - _start + _START_OFFSET
+ .long int_return - _start + _START_OFFSET
+
+/* Program check exception */
+ . = 0x700
+ProgramCheck:
+ EXCEPTION_PROLOG(SRR0, SRR1)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
+ lwz r6,GOT(transfer_to_handler)
+ mtlr r6
+ blrl
+.L_ProgramCheck:
+ .long ProgramCheckException - _start + _START_OFFSET
+ .long int_return - _start + _START_OFFSET
+
+#ifdef CONFIG_440
+ STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
+ STD_EXCEPTION(0x900, Decrementer, DecrementerPITException)
+ STD_EXCEPTION(0xa00, APU, UnknownException)
+#endif
+ STD_EXCEPTION(0xc00, SystemCall, UnknownException)
+
+#ifdef CONFIG_440
+ STD_EXCEPTION(0x1300, DataTLBError, UnknownException)
+ STD_EXCEPTION(0x1400, InstructionTLBError, UnknownException)
+#else
+ STD_EXCEPTION(0x1000, PIT, DecrementerPITException)
+ STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
+ STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
+#endif
+ CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
+
+ .globl _end_of_vectors
+_end_of_vectors:
+ . = _START_OFFSET
#endif
.globl _start
_start:
@@ -817,21 +889,21 @@ _start:
*/
lis r3,CFG_OCM_DATA_ADDR@h /* OCM location */
ori r3,r3,CFG_OCM_DATA_ADDR@l
- ori r3,r3,0x8270 /* 32K Offset, 16K for Bank 1, R/W/Enable */
+ ori r3,r3,0x0270 /* 16K for Bank 1, R/W/Enable */
mtdcr ocmplb3cr1,r3 /* Set PLB Access */
ori r3,r3,0x4000 /* Add 0x4000 for bank 2 */
mtdcr ocmplb3cr2,r3 /* Set PLB Access */
isync
- lis r3,CFG_OCM_DATA_ADDR@h /* OCM location */
+ lis r3,CFG_OCM_DATA_ADDR@h /* OCM location */
ori r3,r3,CFG_OCM_DATA_ADDR@l
- ori r3,r3,0x0270 /* 16K for Bank 1, R/W/Enable */
- mtdcr ocmdscr1, r3 /* Set Data Side */
- mtdcr ocmiscr1, r3 /* Set Instruction Side */
+ ori r3,r3,0x0270 /* 16K for Bank 1, R/W/Enable */
+ mtdcr ocmdscr1, r3 /* Set Data Side */
+ mtdcr ocmiscr1, r3 /* Set Instruction Side */
ori r3,r3,0x4000 /* Add 0x4000 for bank 2 */
- mtdcr ocmdscr2, r3 /* Set Data Side */
- mtdcr ocmiscr2, r3 /* Set Instruction Side */
- addis r3,0,0x0800 /* OCM Data Parity Disable - 1 Wait State */
+ mtdcr ocmdscr2, r3 /* Set Data Side */
+ mtdcr ocmiscr2, r3 /* Set Instruction Side */
+ addis r3,0,0x0800 /* OCM Data Parity Disable - 1 Wait State */
mtdcr ocmdsisdpc,r3
isync
@@ -850,7 +922,7 @@ _start:
mtdcr ocmdscntl, r4 /* set data-side IRAM config */
isync
- lis r3,CFG_OCM_DATA_ADDR@h /* OCM location */
+ lis r3,CFG_OCM_DATA_ADDR@h /* OCM location */
ori r3,r3,CFG_OCM_DATA_ADDR@l
mtdcr ocmdsarc, r3
addis r4, 0, 0xC000 /* OCM data area enabled */
@@ -1017,107 +1089,6 @@ start_ram:
#ifndef CONFIG_NAND_SPL
-/*****************************************************************************/
- .globl _start_of_vectors
-_start_of_vectors:
-
-#if 0
-/*TODO Fixup _start above so we can do this*/
-/* Critical input. */
- CRIT_EXCEPTION(0x100, CritcalInput, CritcalInputException)
-#endif
-
-/* Machine check */
- CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
-
-/* Data Storage exception. */
- STD_EXCEPTION(0x300, DataStorage, UnknownException)
-
-/* Instruction Storage exception. */
- STD_EXCEPTION(0x400, InstStorage, UnknownException)
-
-/* External Interrupt exception. */
- STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
-
-/* Alignment exception. */
- . = 0x600
-Alignment:
- EXCEPTION_PROLOG
- mfspr r4,DAR
- stw r4,_DAR(r21)
- mfspr r5,DSISR
- stw r5,_DSISR(r21)
- addi r3,r1,STACK_FRAME_OVERHEAD
- li r20,MSR_KERNEL
- rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
- lwz r6,GOT(transfer_to_handler)
- mtlr r6
- blrl
-.L_Alignment:
- .long AlignmentException - _start + EXC_OFF_SYS_RESET
- .long int_return - _start + EXC_OFF_SYS_RESET
-
-/* Program check exception */
- . = 0x700
-ProgramCheck:
- EXCEPTION_PROLOG
- addi r3,r1,STACK_FRAME_OVERHEAD
- li r20,MSR_KERNEL
- rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
- lwz r6,GOT(transfer_to_handler)
- mtlr r6
- blrl
-.L_ProgramCheck:
- .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
- .long int_return - _start + EXC_OFF_SYS_RESET
-
- /* No FPU on MPC8xx. This exception is not supposed to happen.
- */
- STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
-
- /* I guess we could implement decrementer, and may have
- * to someday for timekeeping.
- */
- STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
- STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
- STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
- STD_EXCEPTION(0xc00, SystemCall, UnknownException)
- STD_EXCEPTION(0xd00, SingleStep, UnknownException)
-
- STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
- STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
-
- /* On the MPC8xx, this is a software emulation interrupt. It occurs
- * for all unimplemented and illegal instructions.
- */
- STD_EXCEPTION(0x1000, PIT, PITException)
-
- STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
- STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
- STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
- STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
-
- STD_EXCEPTION(0x1500, Reserved5, UnknownException)
- STD_EXCEPTION(0x1600, Reserved6, UnknownException)
- STD_EXCEPTION(0x1700, Reserved7, UnknownException)
- STD_EXCEPTION(0x1800, Reserved8, UnknownException)
- STD_EXCEPTION(0x1900, Reserved9, UnknownException)
- STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
- STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
-
- STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
- STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
- STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
- STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
-
- CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
-
- .globl _end_of_vectors
-_end_of_vectors:
-
-
- . = 0x2100
-
/*
* This code finishes saving the registers to the exception frame
* and jumps to the appropriate handler for the exception.
@@ -1133,28 +1104,12 @@ transfer_to_handler:
SAVE_4GPRS(8, r21)
SAVE_8GPRS(12, r21)
SAVE_8GPRS(24, r21)
-#if 0
- andi. r23,r23,MSR_PR
- mfspr r23,SPRG3 /* if from user, fix up tss.regs */
- beq 2f
- addi r24,r1,STACK_FRAME_OVERHEAD
- stw r24,PT_REGS(r23)
-2: addi r2,r23,-TSS /* set r2 to current */
- tovirt(r2,r2,r23)
-#endif
mflr r23
andi. r24,r23,0x3f00 /* get vector offset */
stw r24,TRAP(r21)
li r22,0
stw r22,RESULT(r21)
mtspr SPRG2,r22 /* r1 is now kernel sp */
-#if 0
- addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
- cmplw 0,r1,r2
- cmplw 1,r1,r24
- crand 1,1,4
- bgt stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
-#endif
lwz r24,0(r23) /* virtual address of handler */
lwz r23,4(r23) /* where to go when done */
mtspr SRR0,r24
@@ -1215,16 +1170,72 @@ crit_return:
REST_GPR(31, r1)
lwz r2,_NIP(r1) /* Restore environment */
lwz r0,_MSR(r1)
- mtspr 990,r2 /* SRR2 */
- mtspr 991,r0 /* SRR3 */
+ mtspr csrr0,r2
+ mtspr csrr1,r0
lwz r0,GPR0(r1)
lwz r2,GPR2(r1)
lwz r1,GPR1(r1)
SYNC
rfci
-/* Cache functions.
-*/
+#ifdef CONFIG_440
+mck_return:
+ mfmsr r28 /* Disable interrupts */
+ li r4,0
+ ori r4,r4,MSR_EE
+ andc r28,r28,r4
+ SYNC /* Some chip revs need this... */
+ mtmsr r28
+ SYNC
+ lwz r2,_CTR(r1)
+ lwz r0,_LINK(r1)
+ mtctr r2
+ mtlr r0
+ lwz r2,_XER(r1)
+ lwz r0,_CCR(r1)
+ mtspr XER,r2
+ mtcrf 0xFF,r0
+ REST_10GPRS(3, r1)
+ REST_10GPRS(13, r1)
+ REST_8GPRS(23, r1)
+ REST_GPR(31, r1)
+ lwz r2,_NIP(r1) /* Restore environment */
+ lwz r0,_MSR(r1)
+ mtspr mcsrr0,r2
+ mtspr mcsrr1,r0
+ lwz r0,GPR0(r1)
+ lwz r2,GPR2(r1)
+ lwz r1,GPR1(r1)
+ SYNC
+ rfmci
+#endif /* CONFIG_440 */
+
+
+/*
+ * Cache functions.
+ *
+ * NOTE: currently the 440s run with dcache _disabled_ once relocated to DRAM,
+ * although for some cache-ralated calls stubs have to be provided to satisfy
+ * symbols resolution.
+ * Icache-related functions are used in POST framework.
+ *
+ */
+#ifdef CONFIG_440
+ .globl dcache_disable
+ .globl icache_disable
+ .globl icache_enable
+dcache_disable:
+icache_disable:
+icache_enable:
+ blr
+
+ .globl dcache_status
+ .globl icache_status
+dcache_status:
+icache_status:
+ mr r3, 0
+ blr
+#else
flush_dcache:
addis r9,r0,0x0002 /* set mask for EE and CE msr bits */
ori r9,r9,0x8000
@@ -1303,24 +1314,13 @@ dcache_status:
mfdccr r3
srwi r3, r3, 31 /* >>31 => select bit 0 */
blr
+#endif
.globl get_pvr
get_pvr:
mfspr r3, PVR
blr
-#if !defined(CONFIG_440)
- .globl wr_pit
-wr_pit:
- mtspr pit, r3
- blr
-#endif
-
- .globl wr_tcr
-wr_tcr:
- mtspr tcr, r3
- blr
-
/*------------------------------------------------------------------------------- */
/* Function: out16 */
/* Description: Output 16 bits */
@@ -1518,7 +1518,7 @@ relocate_code:
* initialization, now running from RAM.
*/
- addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
+ addi r0, r10, in_ram - _start + _START_OFFSET
mtlr r0
blr /* NEVER RETURNS! */
@@ -1588,7 +1588,7 @@ clear_bss:
*/
.globl trap_init
trap_init:
- lwz r7, GOT(_start)
+ lwz r7, GOT(_start_of_vectors)
lwz r8, GOT(_end_of_vectors)
li r9, 0x100 /* reset vector always at 0x100 */
@@ -1608,35 +1608,48 @@ trap_init:
/*
* relocate `hdlr' and `int_return' entries
*/
- li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
- li r8, Alignment - _start + EXC_OFF_SYS_RESET
+ li r7, .L_MachineCheck - _start + _START_OFFSET
+ li r8, Alignment - _start + _START_OFFSET
2:
bl trap_reloc
- addi r7, r7, 0x100 /* next exception vector */
+ addi r7, r7, 0x100 /* next exception vector */
cmplw 0, r7, r8
blt 2b
- li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
+ li r7, .L_Alignment - _start + _START_OFFSET
bl trap_reloc
- li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
+ li r7, .L_ProgramCheck - _start + _START_OFFSET
bl trap_reloc
- li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
- li r8, SystemCall - _start + EXC_OFF_SYS_RESET
-3:
+#ifdef CONFIG_440
+ li r7, .L_FPUnavailable - _start + _START_OFFSET
bl trap_reloc
- addi r7, r7, 0x100 /* next exception vector */
- cmplw 0, r7, r8
- blt 3b
- li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
- li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
-4:
+ li r7, .L_Decrementer - _start + _START_OFFSET
+ bl trap_reloc
+
+ li r7, .L_APU - _start + _START_OFFSET
+ bl trap_reloc
+
+ li r7, .L_InstructionTLBError - _start + _START_OFFSET
+ bl trap_reloc
+
+ li r7, .L_DataTLBError - _start + _START_OFFSET
+ bl trap_reloc
+#else /* CONFIG_440 */
+ li r7, .L_PIT - _start + _START_OFFSET
+ bl trap_reloc
+
+ li r7, .L_InstructionTLBMiss - _start + _START_OFFSET
+ bl trap_reloc
+
+ li r7, .L_DataTLBMiss - _start + _START_OFFSET
+ bl trap_reloc
+#endif /* CONFIG_440 */
+
+ li r7, .L_DebugBreakpoint - _start + _START_OFFSET
bl trap_reloc
- addi r7, r7, 0x100 /* next exception vector */
- cmplw 0, r7, r8
- blt 4b
#if !defined(CONFIG_440)
addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */
@@ -1679,13 +1692,13 @@ trap_reloc:
+----------------------------------------------------------------------------*/
function_prolog(dcbz_area)
rlwinm. r5,r4,0,27,31
- rlwinm r5,r4,27,5,31
- beq ..d_ra2
- addi r5,r5,0x0001
-..d_ra2:mtctr r5
-..d_ag2:dcbz r0,r3
- addi r3,r3,32
- bdnz ..d_ag2
+ rlwinm r5,r4,27,5,31
+ beq ..d_ra2
+ addi r5,r5,0x0001
+..d_ra2:mtctr r5
+..d_ag2:dcbz r0,r3
+ addi r3,r3,32
+ bdnz ..d_ag2
sync
blr
function_epilog(dcbz_area)
@@ -1694,26 +1707,26 @@ trap_reloc:
| dflush. Assume 32K at vector address is cachable.
+----------------------------------------------------------------------------*/
function_prolog(dflush)
- mfmsr r9
- rlwinm r8,r9,0,15,13
- rlwinm r8,r8,0,17,15
- mtmsr r8
- addi r3,r0,0x0000
- mtspr dvlim,r3
- mfspr r3,ivpr
- addi r4,r0,1024
- mtctr r4
+ mfmsr r9
+ rlwinm r8,r9,0,15,13
+ rlwinm r8,r8,0,17,15
+ mtmsr r8
+ addi r3,r0,0x0000
+ mtspr dvlim,r3
+ mfspr r3,ivpr
+ addi r4,r0,1024
+ mtctr r4
..dflush_loop:
- lwz r6,0x0(r3)
- addi r3,r3,32
- bdnz ..dflush_loop
- addi r3,r3,-32
- mtctr r4
-..ag: dcbf r0,r3
- addi r3,r3,-32
- bdnz ..ag
+ lwz r6,0x0(r3)
+ addi r3,r3,32
+ bdnz ..dflush_loop
+ addi r3,r3,-32
+ mtctr r4
+..ag: dcbf r0,r3
+ addi r3,r3,-32
+ bdnz ..ag
sync
- mtmsr r9
+ mtmsr r9
blr
function_epilog(dflush)
#endif /* CONFIG_440 */
diff --git a/cpu/ppc4xx/tlb.c b/cpu/ppc4xx/tlb.c
index 50344a4..049a785 100644
--- a/cpu/ppc4xx/tlb.c
+++ b/cpu/ppc4xx/tlb.c
@@ -36,7 +36,8 @@ typedef struct region {
unsigned long tlb_word2_i_value;
} region_t;
-static int add_tlb_entry(unsigned long base_addr,
+static int add_tlb_entry(unsigned long phys_addr,
+ unsigned long virt_addr,
unsigned long tlb_word0_size_value,
unsigned long tlb_word2_i_value)
{
@@ -55,9 +56,9 @@ static int add_tlb_entry(unsigned long base_addr,
return -1;
/* Second, create the TLB entry */
- tlb_word0_value = TLB_WORD0_EPN_ENCODE(base_addr) | TLB_WORD0_V_ENABLE |
+ tlb_word0_value = TLB_WORD0_EPN_ENCODE(virt_addr) | TLB_WORD0_V_ENABLE |
TLB_WORD0_TS_0 | tlb_word0_size_value;
- tlb_word1_value = TLB_WORD1_RPN_ENCODE(base_addr) | TLB_WORD1_ERPN_ENCODE(0);
+ tlb_word1_value = TLB_WORD1_RPN_ENCODE(phys_addr) | TLB_WORD1_ERPN_ENCODE(0);
tlb_word2_value = TLB_WORD2_U0_DISABLE | TLB_WORD2_U1_DISABLE |
TLB_WORD2_U2_DISABLE | TLB_WORD2_U3_DISABLE |
TLB_WORD2_W_DISABLE | tlb_word2_i_value |
@@ -81,7 +82,9 @@ static int add_tlb_entry(unsigned long base_addr,
return 0;
}
-static void program_tlb_addr(unsigned long base_addr, unsigned long mem_size,
+static void program_tlb_addr(unsigned long phys_addr,
+ unsigned long virt_addr,
+ unsigned long mem_size,
unsigned long tlb_word2_i_value)
{
int rc;
@@ -91,70 +94,86 @@ static void program_tlb_addr(unsigned long base_addr, unsigned long mem_size,
while (mem_size != 0) {
rc = 0;
/* Add the TLB entries in to map the region. */
- if (((base_addr & TLB_256MB_ALIGN_MASK) == base_addr) &&
+ if (((phys_addr & TLB_256MB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_256MB_SIZE)) {
/* Add a 256MB TLB entry */
- if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_256MB, tlb_i)) == 0) {
+ if ((rc = add_tlb_entry(phys_addr, virt_addr,
+ TLB_WORD0_SIZE_256MB, tlb_i)) == 0) {
mem_size -= TLB_256MB_SIZE;
- base_addr += TLB_256MB_SIZE;
+ phys_addr += TLB_256MB_SIZE;
+ virt_addr += TLB_256MB_SIZE;
}
- } else if (((base_addr & TLB_16MB_ALIGN_MASK) == base_addr) &&
+ } else if (((phys_addr & TLB_16MB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_16MB_SIZE)) {
/* Add a 16MB TLB entry */
- if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_16MB, tlb_i)) == 0) {
+ if ((rc = add_tlb_entry(phys_addr, virt_addr,
+ TLB_WORD0_SIZE_16MB, tlb_i)) == 0) {
mem_size -= TLB_16MB_SIZE;
- base_addr += TLB_16MB_SIZE;
+ phys_addr += TLB_16MB_SIZE;
+ virt_addr += TLB_16MB_SIZE;
}
- } else if (((base_addr & TLB_1MB_ALIGN_MASK) == base_addr) &&
+ } else if (((phys_addr & TLB_1MB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_1MB_SIZE)) {
/* Add a 1MB TLB entry */
- if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_1MB, tlb_i)) == 0) {
+ if ((rc = add_tlb_entry(phys_addr, virt_addr,
+ TLB_WORD0_SIZE_1MB, tlb_i)) == 0) {
mem_size -= TLB_1MB_SIZE;
- base_addr += TLB_1MB_SIZE;
+ phys_addr += TLB_1MB_SIZE;
+ virt_addr += TLB_1MB_SIZE;
}
- } else if (((base_addr & TLB_256KB_ALIGN_MASK) == base_addr) &&
+ } else if (((phys_addr & TLB_256KB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_256KB_SIZE)) {
/* Add a 256KB TLB entry */
- if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_256KB, tlb_i)) == 0) {
+ if ((rc = add_tlb_entry(phys_addr, virt_addr,
+ TLB_WORD0_SIZE_256KB, tlb_i)) == 0) {
mem_size -= TLB_256KB_SIZE;
- base_addr += TLB_256KB_SIZE;
+ phys_addr += TLB_256KB_SIZE;
+ virt_addr += TLB_256KB_SIZE;
}
- } else if (((base_addr & TLB_64KB_ALIGN_MASK) == base_addr) &&
+ } else if (((phys_addr & TLB_64KB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_64KB_SIZE)) {
/* Add a 64KB TLB entry */
- if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_64KB, tlb_i)) == 0) {
+ if ((rc = add_tlb_entry(phys_addr, virt_addr,
+ TLB_WORD0_SIZE_64KB, tlb_i)) == 0) {
mem_size -= TLB_64KB_SIZE;
- base_addr += TLB_64KB_SIZE;
+ phys_addr += TLB_64KB_SIZE;
+ virt_addr += TLB_64KB_SIZE;
}
- } else if (((base_addr & TLB_16KB_ALIGN_MASK) == base_addr) &&
+ } else if (((phys_addr & TLB_16KB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_16KB_SIZE)) {
/* Add a 16KB TLB entry */
- if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_16KB, tlb_i)) == 0) {
+ if ((rc = add_tlb_entry(phys_addr, virt_addr,
+ TLB_WORD0_SIZE_16KB, tlb_i)) == 0) {
mem_size -= TLB_16KB_SIZE;
- base_addr += TLB_16KB_SIZE;
+ phys_addr += TLB_16KB_SIZE;
+ virt_addr += TLB_16KB_SIZE;
}
- } else if (((base_addr & TLB_4KB_ALIGN_MASK) == base_addr) &&
+ } else if (((phys_addr & TLB_4KB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_4KB_SIZE)) {
/* Add a 4KB TLB entry */
- if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_4KB, tlb_i)) == 0) {
+ if ((rc = add_tlb_entry(phys_addr, virt_addr,
+ TLB_WORD0_SIZE_4KB, tlb_i)) == 0) {
mem_size -= TLB_4KB_SIZE;
- base_addr += TLB_4KB_SIZE;
+ phys_addr += TLB_4KB_SIZE;
+ virt_addr += TLB_4KB_SIZE;
}
- } else if (((base_addr & TLB_1KB_ALIGN_MASK) == base_addr) &&
+ } else if (((phys_addr & TLB_1KB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_1KB_SIZE)) {
/* Add a 1KB TLB entry */
- if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_1KB, tlb_i)) == 0) {
+ if ((rc = add_tlb_entry(phys_addr, virt_addr,
+ TLB_WORD0_SIZE_1KB, tlb_i)) == 0) {
mem_size -= TLB_1KB_SIZE;
- base_addr += TLB_1KB_SIZE;
+ phys_addr += TLB_1KB_SIZE;
+ virt_addr += TLB_1KB_SIZE;
}
} else {
printf("ERROR: no TLB size exists for the base address 0x%0X.\n",
- base_addr);
+ phys_addr);
}
if (rc != 0)
printf("ERROR: no TLB entries available for the base addr 0x%0X.\n",
- base_addr);
+ phys_addr);
}
return;
@@ -166,16 +185,16 @@ static void program_tlb_addr(unsigned long base_addr, unsigned long mem_size,
* Common usage for boards with SDRAM DIMM modules to dynamically
* configure the TLB's for the SDRAM
*/
-void program_tlb(u32 start, u32 size, u32 tlb_word2_i_value)
+void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value)
{
region_t region_array;
- region_array.base = start;
+ region_array.base = phys_addr;
region_array.size = size;
region_array.tlb_word2_i_value = tlb_word2_i_value; /* en-/disable cache */
/* Call the routine to add in the tlb entries for the memory regions */
- program_tlb_addr(region_array.base, region_array.size,
+ program_tlb_addr(region_array.base, virt_addr, region_array.size,
region_array.tlb_word2_i_value);
return;
diff --git a/cpu/ppc4xx/traps.c b/cpu/ppc4xx/traps.c
index 6aecca2..eb9420e 100644..100755
--- a/cpu/ppc4xx/traps.c
+++ b/cpu/ppc4xx/traps.c
@@ -36,6 +36,8 @@
#include <command.h>
#include <asm/processor.h>
+DECLARE_GLOBAL_DATA_PTR;
+
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
int (*debugger_exception_handler)(struct pt_regs *) = 0;
#endif
@@ -45,8 +47,7 @@ extern unsigned long search_exception_table(unsigned long);
/* THIS NEEDS CHANGING to use the board info structure.
*/
-#define END_OF_MEM 0x00400000
-
+#define END_OF_MEM (gd->bd->bi_memstart + gd->bd->bi_memsize)
static __inline__ void set_tsr(unsigned long val)
{
@@ -110,7 +111,7 @@ void show_regs(struct pt_regs * regs)
{
int i;
- printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n",
+ printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DEAR: %08lX\n",
regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
printf("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
@@ -120,14 +121,12 @@ void show_regs(struct pt_regs * regs)
printf("\n");
for (i = 0; i < 32; i++) {
- if ((i % 8) == 0)
- {
+ if ((i % 8) == 0) {
printf("GPR%02d: ", i);
}
printf("%08lX ", regs->gpr[i]);
- if ((i % 8) == 7)
- {
+ if ((i % 8) == 7) {
printf("\n");
}
}
@@ -139,13 +138,16 @@ _exception(int signr, struct pt_regs *regs)
{
show_regs(regs);
print_backtrace((unsigned long *)regs->gpr[1]);
- panic("Exception in kernel pc %lx signal %d",regs->nip,signr);
+ panic("Exception");
}
void
MachineCheckException(struct pt_regs *regs)
{
- unsigned long fixup;
+ unsigned long fixup, val;
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+ u32 value2;
+#endif
/* Probing PCI using config cycles cause this exception
* when a device is not present. Catch it and return to
@@ -161,26 +163,132 @@ MachineCheckException(struct pt_regs *regs)
return;
#endif
- printf("Machine check in kernel mode.\n");
+ printf("Machine Check Exception.\n");
printf("Caused by (from msr): ");
- printf("regs %p ",regs);
- switch( regs->msr & 0x000F0000) {
- case (0x80000000>>12):
- printf("Machine check signal - probably due to mm fault\n"
- "with mmu off\n");
+ printf("regs %p ", regs);
+
+ val = get_esr();
+
+#if !defined(CONFIG_440)
+ if (val& ESR_IMCP) {
+ printf("Instruction");
+ mtspr(ESR, val & ~ESR_IMCP);
+ } else {
+ printf("Data");
+ }
+ printf(" machine check.\n");
+
+#elif defined(CONFIG_440)
+ if (val& ESR_IMCP){
+ printf("Instruction Synchronous Machine Check exception\n");
+ mtspr(SPRN_ESR, val & ~ESR_IMCP);
+ } else {
+ val = mfspr(MCSR);
+ if (val & MCSR_IB)
+ printf("Instruction Read PLB Error\n");
+ if (val & MCSR_DRB)
+ printf("Data Read PLB Error\n");
+ if (val & MCSR_DWB)
+ printf("Data Write PLB Error\n");
+ if (val & MCSR_TLBP)
+ printf("TLB Parity Error\n");
+ if (val & MCSR_ICP){
+ /*flush_instruction_cache(); */
+ printf("I-Cache Parity Error\n");
+ }
+ if (val & MCSR_DCSP)
+ printf("D-Cache Search Parity Error\n");
+ if (val & MCSR_DCFP)
+ printf("D-Cache Flush Parity Error\n");
+ if (val & MCSR_IMPE)
+ printf("Machine Check exception is imprecise\n");
+
+ /* Clear MCSR */
+ mtspr(SPRN_MCSR, val);
+ }
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+ mfsdram(DDR0_00, val) ;
+ printf("DDR0: DDR0_00 %p\n", val);
+ val = (val >> 16) & 0xff;
+ if (val & 0x80)
+ printf("DDR0: At least one interrupt active\n");
+ if (val & 0x40)
+ printf("DDR0: DRAM initialization complete.\n");
+ if (val & 0x20)
+ printf("DDR0: Multiple uncorrectable ECC events.\n");
+ if (val & 0x10)
+ printf("DDR0: Single uncorrectable ECC event.\n");
+ if (val & 0x08)
+ printf("DDR0: Multiple correctable ECC events.\n");
+ if (val & 0x04)
+ printf("DDR0: Single correctable ECC event.\n");
+ if (val & 0x02)
+ printf("Multiple accesses outside the defined"
+ " physical memory space detected\n");
+ if (val & 0x01)
+ printf("DDR0: Single access outside the defined"
+ " physical memory space detected.\n");
+
+ mfsdram(DDR0_01, val);
+ val = (val >> 8) & 0x7;
+ switch (val ) {
+ case 0:
+ printf("DDR0: Write Out-of-Range command\n");
+ break;
+ case 1:
+ printf("DDR0: Read Out-of-Range command\n");
break;
- case (0x80000000>>13):
- printf("Transfer error ack signal\n");
+ case 2:
+ printf("DDR0: Masked write Out-of-Range command\n");
break;
- case (0x80000000>>14):
- printf("Data parity signal\n");
+ case 4:
+ printf("DDR0: Wrap write Out-of-Range command\n");
break;
- case (0x80000000>>15):
- printf("Address parity signal\n");
+ case 5:
+ printf("DDR0: Wrap read Out-of-Range command\n");
break;
default:
- printf("Unknown values in msr\n");
+ mfsdram(DDR0_01, value2);
+ printf("DDR0: No DDR0 error know 0x%x %p\n", val, value2);
}
+ mfsdram(DDR0_23, val);
+ if ( (val >> 16) & 0xff)
+ printf("DDR0: Syndrome for correctable ECC event 0x%x\n",
+ (val >> 16) & 0xff);
+ mfsdram(DDR0_23, val);
+ if ( (val >> 8) & 0xff)
+ printf("DDR0: Syndrome for uncorrectable ECC event 0x%x\n",
+ (val >> 8) & 0xff);
+ mfsdram(DDR0_33, val);
+ if (val)
+ printf("DDR0: Address of command that caused an "
+ "Out-of-Range interrupt %p\n", val);
+ mfsdram(DDR0_34, val);
+ if (val)
+ printf("DDR0: Address of uncorrectable ECC event %p\n", val);
+ mfsdram(DDR0_35, val);
+ if (val)
+ printf("DDR0: Address of uncorrectable ECC event %p\n", val);
+ mfsdram(DDR0_36, val);
+ if (val)
+ printf("DDR0: Data of uncorrectable ECC event 0x%08x\n", val);
+ mfsdram(DDR0_37, val);
+ if (val)
+ printf("DDR0: Data of uncorrectable ECC event 0x%08x\n", val);
+ mfsdram(DDR0_38, val);
+ if (val)
+ printf("DDR0: Address of correctable ECC event %p\n", val);
+ mfsdram(DDR0_39, val);
+ if (val)
+ printf("DDR0: Address of correctable ECC event %p\n", val);
+ mfsdram(DDR0_40, val);
+ if (val)
+ printf("DDR0: Data of correctable ECC event 0x%08x\n", val);
+ mfsdram(DDR0_41, val);
+ if (val)
+ printf("DDR0: Data of correctable ECC event 0x%08x\n", val);
+#endif /* CONFIG_440EPX */
+#endif /* CONFIG_440 */
show_regs(regs);
print_backtrace((unsigned long *)regs->gpr[1]);
panic("machine check");
@@ -224,7 +332,7 @@ ProgramCheckException(struct pt_regs *regs)
}
void
-PITException(struct pt_regs *regs)
+DecrementerPITException(struct pt_regs *regs)
{
/*
* Reset PIT interrupt
@@ -272,17 +380,17 @@ addr_probe(uint *addr)
__asm__ __volatile__( \
"1: lwz %0,0(%1)\n" \
- " eieio\n" \
- " li %0,0\n" \
- "2:\n" \
- ".section .fixup,\"ax\"\n" \
- "3: li %0,-1\n" \
- " b 2b\n" \
- ".section __ex_table,\"a\"\n" \
- " .align 2\n" \
- " .long 1b,3b\n" \
- ".text" \
- : "=r" (retval) : "r"(addr));
+ " eieio\n" \
+ " li %0,0\n" \
+ "2:\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3: li %0,-1\n" \
+ " b 2b\n" \
+ ".section __ex_table,\"a\"\n" \
+ " .align 2\n" \
+ " .long 1b,3b\n" \
+ ".text" \
+ : "=r" (retval) : "r"(addr));
return (retval);
#endif