mirror of
https://github.com/Ysurac/openmptcprouter.git
synced 2025-03-09 15:40:20 +00:00
Kernel 5.4 RUTX support
This commit is contained in:
parent
839fcf1cab
commit
cfce9f52b2
7376 changed files with 3902 additions and 546 deletions
75
common/package/boot/uboot-ipq40xx/src/post/Makefile
Normal file
75
common/package/boot/uboot-ipq40xx/src/post/Makefile
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
#
|
||||
# (C) Copyright 2002-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
include $(OBJTREE)/include/autoconf.mk
|
||||
|
||||
LIB = libpost.o
|
||||
GPLIB-$(CONFIG_HAS_POST) += libgenpost.o
|
||||
COBJS-$(CONFIG_HAS_POST) += post.o
|
||||
COBJS-$(CONFIG_POST_STD_LIST) += tests.o
|
||||
|
||||
SPLIB-$(CONFIG_HAS_POST) = drivers/libpostdrivers.o
|
||||
SPLIB-$(CONFIG_HAS_POST) += $(shell if [ -d lib_$(ARCH) ]; then echo \
|
||||
"lib_$(ARCH)/libpost$(ARCH).o"; fi)
|
||||
SPLIB-$(CONFIG_HAS_POST) += $(shell if [ -d lib_$(ARCH)/fpu ]; then echo \
|
||||
"lib_$(ARCH)/fpu/libpost$(ARCH)fpu.o"; fi)
|
||||
SPLIB-$(CONFIG_HAS_POST) += $(shell if [ -d cpu/$(CPU) ]; then echo \
|
||||
"cpu/$(CPU)/libpost$(CPU).o"; fi)
|
||||
SPLIB-$(CONFIG_HAS_POST) += $(shell if [ -d board/$(BOARD) ]; then echo \
|
||||
"board/$(BOARD)/libpost$(BOARD).o"; fi)
|
||||
|
||||
GPLIB := $(addprefix $(obj),$(GPLIB-y))
|
||||
SPLIB := $(addprefix $(obj),$(SPLIB-y))
|
||||
COBJS := $(COBJS-y)
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
LIB := $(obj)$(LIB)
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
postdeps:
|
||||
@for lib in $(SPLIB-y) ; do \
|
||||
$(MAKE) -C `dirname $$lib` all ; \
|
||||
done
|
||||
|
||||
# generic POST library
|
||||
$(GPLIB): $(obj).depend $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
# specific POST libraries
|
||||
$(SPLIB): $(obj).depend postdeps
|
||||
$(MAKE) -C $(dir $(subst $(obj),,$@))
|
||||
|
||||
# the POST lib archive
|
||||
$(LIB): $(GPLIB) $(SPLIB)
|
||||
$(call cmd_link_o_target, $^)
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
#
|
||||
# (C) Copyright 2002-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
include $(OBJTREE)/include/autoconf.mk
|
||||
|
||||
LIB = libpostlwmon.o
|
||||
|
||||
COBJS-$(CONFIG_HAS_POST) += sysmon.o
|
||||
|
||||
include $(TOPDIR)/post/rules.mk
|
||||
313
common/package/boot/uboot-ipq40xx/src/post/board/lwmon/sysmon.c
Normal file
313
common/package/boot/uboot-ipq40xx/src/post/board/lwmon/sysmon.c
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
/*
|
||||
* (C) Copyright 2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* SYSMON test
|
||||
*
|
||||
* This test performs the system hardware monitoring.
|
||||
* The test passes when all the following voltages and temperatures
|
||||
* are within allowed ranges:
|
||||
*
|
||||
* Board temperature
|
||||
* Front temperature
|
||||
* +3.3V CPU logic
|
||||
* +5V logic
|
||||
* +12V PCMCIA
|
||||
* +12V CCFL
|
||||
* +5V standby
|
||||
*
|
||||
* CCFL is not enabled if temperature values are not within allowed ranges
|
||||
*
|
||||
* See the list off all parameters in the sysmon_table below
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include <watchdog.h>
|
||||
#include <i2c.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_SYSMON
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static int sysmon_temp_invalid = 0;
|
||||
|
||||
/* #define DEBUG */
|
||||
|
||||
typedef struct sysmon_s sysmon_t;
|
||||
typedef struct sysmon_table_s sysmon_table_t;
|
||||
|
||||
static void sysmon_lm87_init (sysmon_t * this);
|
||||
static void sysmon_pic_init (sysmon_t * this);
|
||||
static uint sysmon_i2c_read (sysmon_t * this, uint addr);
|
||||
static uint sysmon_i2c_read_sgn (sysmon_t * this, uint addr);
|
||||
static void sysmon_ccfl_disable (sysmon_table_t * this);
|
||||
static void sysmon_ccfl_enable (sysmon_table_t * this);
|
||||
|
||||
struct sysmon_s
|
||||
{
|
||||
uchar chip;
|
||||
void (*init)(sysmon_t *);
|
||||
uint (*read)(sysmon_t *, uint);
|
||||
};
|
||||
|
||||
static sysmon_t sysmon_lm87 =
|
||||
{CONFIG_SYS_I2C_SYSMON_ADDR, sysmon_lm87_init, sysmon_i2c_read};
|
||||
static sysmon_t sysmon_lm87_sgn =
|
||||
{CONFIG_SYS_I2C_SYSMON_ADDR, sysmon_lm87_init, sysmon_i2c_read_sgn};
|
||||
static sysmon_t sysmon_pic =
|
||||
{CONFIG_SYS_I2C_PICIO_ADDR, sysmon_pic_init, sysmon_i2c_read};
|
||||
|
||||
static sysmon_t * sysmon_list[] =
|
||||
{
|
||||
&sysmon_lm87,
|
||||
&sysmon_lm87_sgn,
|
||||
&sysmon_pic,
|
||||
NULL
|
||||
};
|
||||
|
||||
struct sysmon_table_s
|
||||
{
|
||||
char * name;
|
||||
char * unit_name;
|
||||
sysmon_t * sysmon;
|
||||
void (*exec_before)(sysmon_table_t *);
|
||||
void (*exec_after)(sysmon_table_t *);
|
||||
|
||||
int unit_precision;
|
||||
int unit_div;
|
||||
int unit_min;
|
||||
int unit_max;
|
||||
uint val_mask;
|
||||
uint val_min;
|
||||
uint val_max;
|
||||
int val_valid;
|
||||
uint val_min_alt;
|
||||
uint val_max_alt;
|
||||
int val_valid_alt;
|
||||
uint addr;
|
||||
};
|
||||
|
||||
static sysmon_table_t sysmon_table[] =
|
||||
{
|
||||
{"Board temperature", " C", &sysmon_lm87_sgn, NULL, sysmon_ccfl_disable,
|
||||
1, 1, -128, 127, 0xFF, 0x58, 0xD5, 0, 0x6C, 0xC6, 0, 0x27},
|
||||
|
||||
{"Front temperature", " C", &sysmon_lm87, NULL, sysmon_ccfl_disable,
|
||||
1, 100, -27316, 8984, 0xFF, 0xA4, 0xFC, 0, 0xB2, 0xF1, 0, 0x29},
|
||||
|
||||
{"+3.3V CPU logic", "V", &sysmon_lm87, NULL, NULL,
|
||||
100, 1000, 0, 4386, 0xFF, 0xB6, 0xC9, 0, 0xB6, 0xC9, 0, 0x22},
|
||||
|
||||
{"+ 5 V logic", "V", &sysmon_lm87, NULL, NULL,
|
||||
100, 1000, 0, 6630, 0xFF, 0xB6, 0xCA, 0, 0xB6, 0xCA, 0, 0x23},
|
||||
|
||||
{"+12 V PCMCIA", "V", &sysmon_lm87, NULL, NULL,
|
||||
100, 1000, 0, 15460, 0xFF, 0xBC, 0xD0, 0, 0xBC, 0xD0, 0, 0x21},
|
||||
|
||||
{"+12 V CCFL", "V", &sysmon_lm87, NULL, sysmon_ccfl_enable,
|
||||
100, 1000, 0, 15900, 0xFF, 0xB6, 0xCA, 0, 0xB6, 0xCA, 0, 0x24},
|
||||
|
||||
{"+ 5 V standby", "V", &sysmon_pic, NULL, NULL,
|
||||
100, 1000, 0, 6040, 0xFF, 0xC8, 0xDE, 0, 0xC8, 0xDE, 0, 0x7C},
|
||||
};
|
||||
static int sysmon_table_size = ARRAY_SIZE(sysmon_table);
|
||||
|
||||
static int conversion_done = 0;
|
||||
|
||||
|
||||
int sysmon_init_f (void)
|
||||
{
|
||||
sysmon_t ** l;
|
||||
ulong reg;
|
||||
|
||||
/* Power on CCFL, PCMCIA */
|
||||
reg = pic_read (0x60);
|
||||
reg |= 0x09;
|
||||
pic_write (0x60, reg);
|
||||
|
||||
for (l = sysmon_list; *l; l++) {
|
||||
(*l)->init(*l);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sysmon_reloc (void)
|
||||
{
|
||||
/* Do nothing for now, sysmon_reloc() is required by the sysmon post */
|
||||
}
|
||||
|
||||
static char *sysmon_unit_value (sysmon_table_t *s, uint val)
|
||||
{
|
||||
static char buf[32];
|
||||
int unit_val =
|
||||
s->unit_min + (s->unit_max - s->unit_min) * val / s->val_mask;
|
||||
char *p, sign;
|
||||
int dec, frac;
|
||||
|
||||
if (val == -1) {
|
||||
return "I/O ERROR";
|
||||
}
|
||||
|
||||
if (unit_val < 0) {
|
||||
sign = '-';
|
||||
unit_val = -unit_val;
|
||||
} else {
|
||||
sign = '+';
|
||||
}
|
||||
|
||||
p = buf + sprintf(buf, "%c%2d", sign, unit_val / s->unit_div);
|
||||
|
||||
|
||||
frac = unit_val % s->unit_div;
|
||||
|
||||
frac /= (s->unit_div / s->unit_precision);
|
||||
|
||||
dec = s->unit_precision;
|
||||
|
||||
if (dec != 1) {
|
||||
*p++ = '.';
|
||||
}
|
||||
for (dec /= 10; dec != 0; dec /= 10) {
|
||||
*p++ = '0' + (frac / dec) % 10;
|
||||
}
|
||||
strcpy(p, s->unit_name);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void sysmon_lm87_init (sysmon_t * this)
|
||||
{
|
||||
uchar val;
|
||||
|
||||
/* Detect LM87 chip */
|
||||
if (i2c_read(this->chip, 0x40, 1, &val, 1) || (val & 0x80) != 0 ||
|
||||
i2c_read(this->chip, 0x3E, 1, &val, 1) || val != 0x02) {
|
||||
printf("Error: LM87 not found at 0x%02X\n", this->chip);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Configure pins 5,6 as AIN */
|
||||
val = 0x03;
|
||||
if (i2c_write(this->chip, 0x16, 1, &val, 1)) {
|
||||
printf("Error: can't write LM87 config register\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Start monitoring */
|
||||
val = 0x01;
|
||||
if (i2c_write(this->chip, 0x40, 1, &val, 1)) {
|
||||
printf("Error: can't write LM87 config register\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void sysmon_pic_init (sysmon_t * this)
|
||||
{
|
||||
}
|
||||
|
||||
static uint sysmon_i2c_read (sysmon_t * this, uint addr)
|
||||
{
|
||||
uchar val;
|
||||
uint res = i2c_read(this->chip, addr, 1, &val, 1);
|
||||
|
||||
return res == 0 ? val : -1;
|
||||
}
|
||||
|
||||
static uint sysmon_i2c_read_sgn (sysmon_t * this, uint addr)
|
||||
{
|
||||
uchar val;
|
||||
return i2c_read(this->chip, addr, 1, &val, 1) == 0 ?
|
||||
128 + (signed char)val : -1;
|
||||
}
|
||||
|
||||
static void sysmon_ccfl_disable (sysmon_table_t * this)
|
||||
{
|
||||
if (!this->val_valid_alt) {
|
||||
sysmon_temp_invalid = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void sysmon_ccfl_enable (sysmon_table_t * this)
|
||||
{
|
||||
ulong reg;
|
||||
|
||||
if (!sysmon_temp_invalid) {
|
||||
reg = pic_read (0x60);
|
||||
reg |= 0x06;
|
||||
pic_write (0x60, reg);
|
||||
}
|
||||
}
|
||||
|
||||
int sysmon_post_test (int flags)
|
||||
{
|
||||
int res = 0;
|
||||
sysmon_table_t * t;
|
||||
uint val;
|
||||
|
||||
/*
|
||||
* The A/D conversion on the LM87 sensor takes 300 ms.
|
||||
*/
|
||||
if (! conversion_done) {
|
||||
while (post_time_ms(gd->post_init_f_time) < 300) WATCHDOG_RESET ();
|
||||
conversion_done = 1;
|
||||
}
|
||||
|
||||
for (t = sysmon_table; t < sysmon_table + sysmon_table_size; t ++) {
|
||||
if (t->exec_before) {
|
||||
t->exec_before(t);
|
||||
}
|
||||
|
||||
val = t->sysmon->read(t->sysmon, t->addr);
|
||||
if (val != -1) {
|
||||
t->val_valid = val >= t->val_min && val <= t->val_max;
|
||||
t->val_valid_alt = val >= t->val_min_alt && val <= t->val_max_alt;
|
||||
} else {
|
||||
t->val_valid = 0;
|
||||
t->val_valid_alt = 0;
|
||||
}
|
||||
|
||||
if (t->exec_after) {
|
||||
t->exec_after(t);
|
||||
}
|
||||
|
||||
if ((!t->val_valid) || (flags & POST_MANUAL)) {
|
||||
printf("%-17s = %-10s ", t->name, sysmon_unit_value(t, val));
|
||||
printf("allowed range");
|
||||
printf(" %-8s ..", sysmon_unit_value(t, t->val_min));
|
||||
printf(" %-8s", sysmon_unit_value(t, t->val_max));
|
||||
printf(" %s\n", t->val_valid ? "OK" : "FAIL");
|
||||
}
|
||||
|
||||
if (!t->val_valid) {
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_SYSMON */
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
#
|
||||
# (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com
|
||||
#
|
||||
# Developed for DENX Software Engineering GmbH
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
include $(OBJTREE)/include/autoconf.mk
|
||||
|
||||
LIB = libpostlwmon5.o
|
||||
|
||||
COBJS-$(CONFIG_HAS_POST) += sysmon.o watchdog.o dspic.o fpga.o dsp.o gdc.o
|
||||
|
||||
include $(TOPDIR)/post/rules.mk
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com
|
||||
*
|
||||
* Developed for DENX Software Engineering GmbH
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#include <post.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_DSP
|
||||
#include <asm/io.h>
|
||||
|
||||
/* This test verifies DSP status bits in FPGA */
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define DSP_STATUS_REG 0xC4000008
|
||||
#define FPGA_STATUS_REG 0xC400000C
|
||||
|
||||
int dsp_post_test(int flags)
|
||||
{
|
||||
uint old_value;
|
||||
uint read_value;
|
||||
int ret;
|
||||
|
||||
/* momorize fpga status */
|
||||
old_value = in_be32((void *)FPGA_STATUS_REG);
|
||||
/* enable outputs */
|
||||
out_be32((void *)FPGA_STATUS_REG, 0x30);
|
||||
|
||||
/* generate sync signal */
|
||||
out_be32((void *)DSP_STATUS_REG, 0x300);
|
||||
udelay(5);
|
||||
out_be32((void *)DSP_STATUS_REG, 0);
|
||||
udelay(500);
|
||||
|
||||
/* read status */
|
||||
ret = 0;
|
||||
read_value = in_be32((void *)DSP_STATUS_REG) & 0x3;
|
||||
if (read_value != 0x03) {
|
||||
post_log("\nDSP status read %08X\n", read_value);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
/* restore fpga status */
|
||||
out_be32((void *)FPGA_STATUS_REG, old_value);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_DSP */
|
||||
121
common/package/boot/uboot-ipq40xx/src/post/board/lwmon5/dspic.c
Normal file
121
common/package/boot/uboot-ipq40xx/src/post/board/lwmon5/dspic.c
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com
|
||||
*
|
||||
* Developed for DENX Software Engineering GmbH
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/* There are two tests for dsPIC currently implemented:
|
||||
* 1. dsPIC ready test. Done in board_early_init_f(). Only result verified here.
|
||||
* 2. dsPIC POST result test. This test gets dsPIC POST codes and version.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
|
||||
#include <i2c.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define DSPIC_POST_ERROR_REG 0x800
|
||||
#define DSPIC_SYS_ERROR_REG 0x802
|
||||
#define DSPIC_SYS_VERSION_REG 0x804
|
||||
#define DSPIC_FW_VERSION_REG 0x808
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_BSPEC1
|
||||
|
||||
/* Verify that dsPIC ready test done early at hw init passed ok */
|
||||
int dspic_init_post_test(int flags)
|
||||
{
|
||||
if (in_be32((void *)CONFIG_SYS_DSPIC_TEST_ADDR) &
|
||||
CONFIG_SYS_DSPIC_TEST_MASK) {
|
||||
post_log("dsPIC init test failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_BSPEC1 */
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_BSPEC2
|
||||
/* Read a register from the dsPIC. */
|
||||
int dspic_read(ushort reg, ushort *data)
|
||||
{
|
||||
uchar buf[sizeof(*data)];
|
||||
int rval;
|
||||
|
||||
if (i2c_read(CONFIG_SYS_I2C_DSPIC_IO_ADDR, reg, 2, buf, 2))
|
||||
return -1;
|
||||
rval = i2c_read(CONFIG_SYS_I2C_DSPIC_IO_ADDR, reg, sizeof(reg),
|
||||
buf, sizeof(*data));
|
||||
*data = (buf[0] << 8) | buf[1];
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/* Verify error codes regs, display version */
|
||||
int dspic_post_test(int flags)
|
||||
{
|
||||
ushort data;
|
||||
int ret = 0;
|
||||
|
||||
post_log("\n");
|
||||
|
||||
/* read dspic FW-Version */
|
||||
if (dspic_read(DSPIC_FW_VERSION_REG, &data)) {
|
||||
post_log("dsPIC: failed read FW-Version\n");
|
||||
ret = 1;
|
||||
} else {
|
||||
post_log("dsPIC FW-Version: %u.%u\n",
|
||||
(data >> 8) & 0xFF, data & 0xFF);
|
||||
}
|
||||
|
||||
/* read dspic SYS-Version */
|
||||
if (dspic_read(DSPIC_SYS_VERSION_REG, &data)) {
|
||||
post_log("dsPIC: failed read version\n");
|
||||
ret = 1;
|
||||
} else {
|
||||
post_log("dsPIC SYS-Version: %u.%u\n",
|
||||
(data >> 8) & 0xFF, data & 0xFF);
|
||||
}
|
||||
|
||||
/* read dspic POST error code */
|
||||
if (dspic_read(DSPIC_POST_ERROR_REG, &data)) {
|
||||
post_log("dsPIC: failed read POST code\n");
|
||||
ret = 1;
|
||||
} else {
|
||||
post_log("dsPIC POST-ERROR code: 0x%04X\n", data);
|
||||
}
|
||||
|
||||
/* read dspic SYS error code */
|
||||
if ((data = dspic_read(DSPIC_SYS_ERROR_REG, &data))) {
|
||||
post_log("dsPIC: failed read system error\n");
|
||||
ret = 1;
|
||||
} else {
|
||||
post_log("dsPIC SYS-ERROR code: 0x%04X\n", data);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_BSPEC2 */
|
||||
360
common/package/boot/uboot-ipq40xx/src/post/board/lwmon5/fpga.c
Normal file
360
common/package/boot/uboot-ipq40xx/src/post/board/lwmon5/fpga.c
Normal file
|
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
* (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com
|
||||
*
|
||||
* Developed for DENX Software Engineering GmbH
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
#include <common.h>
|
||||
|
||||
/* This test performs testing of FPGA SCRATCH register,
|
||||
* gets FPGA version and run get_ram_size() on FPGA memory
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include <watchdog.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define FPGA_SCRATCH_REG 0xC4000050
|
||||
#define FPGA_VERSION_REG 0xC4000040
|
||||
#define FPGA_RAM_START 0xC4200000
|
||||
#define FPGA_RAM_END 0xC4203FFF
|
||||
#define FPGA_STAT 0xC400000C
|
||||
#define FPGA_BUFFER 0x00800000
|
||||
#define FPGA_RAM_SIZE (FPGA_RAM_END - FPGA_RAM_START + 1)
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_BSPEC3
|
||||
|
||||
const static unsigned long pattern[] = {
|
||||
0xffffffff,
|
||||
0xaaaaaaaa,
|
||||
0xcccccccc,
|
||||
0xf0f0f0f0,
|
||||
0xff00ff00,
|
||||
0xffff0000,
|
||||
0x0000ffff,
|
||||
0x00ff00ff,
|
||||
0x0f0f0f0f,
|
||||
0x33333333,
|
||||
0x55555555,
|
||||
0x00000000,
|
||||
};
|
||||
|
||||
const static unsigned long otherpattern = 0x01234567;
|
||||
|
||||
static int one_scratch_test(uint value)
|
||||
{
|
||||
uint read_value;
|
||||
int ret = 0;
|
||||
|
||||
out_be32((void *)FPGA_SCRATCH_REG, value);
|
||||
/* read other location (protect against data lines capacity) */
|
||||
ret = in_be16((void *)FPGA_VERSION_REG);
|
||||
/* verify test pattern */
|
||||
read_value = in_be32((void *)FPGA_SCRATCH_REG);
|
||||
if (read_value != value) {
|
||||
post_log("FPGA SCRATCH test failed write %08X, read %08X\n",
|
||||
value, read_value);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fpga_post_test1(ulong *start, ulong size, ulong val)
|
||||
{
|
||||
int ret = 0;
|
||||
ulong i = 0;
|
||||
ulong *mem = start;
|
||||
ulong readback;
|
||||
|
||||
for (i = 0; i < size / sizeof(ulong); i++) {
|
||||
mem[i] = val;
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
for (i = 0; i < size / sizeof(ulong); i++) {
|
||||
readback = mem[i];
|
||||
if (readback != val) {
|
||||
post_log("FPGA Memory error at %08x, "
|
||||
"wrote %08x, read %08x !\n",
|
||||
mem + i, val, readback);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fpga_post_test2(ulong *start, ulong size)
|
||||
{
|
||||
int ret = 0;
|
||||
ulong i = 0;
|
||||
ulong *mem = start;
|
||||
ulong readback;
|
||||
|
||||
for (i = 0; i < size / sizeof(ulong); i++) {
|
||||
mem[i] = 1 << (i % 32);
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
for (i = 0; i < size / sizeof(ulong); i++) {
|
||||
readback = mem[i];
|
||||
if (readback != 1 << (i % 32)) {
|
||||
post_log("FPGA Memory error at %08x, "
|
||||
"wrote %08x, read %08x !\n",
|
||||
mem + i, 1 << (i % 32), readback);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fpga_post_test3(ulong *start, ulong size)
|
||||
{
|
||||
int ret = 0;
|
||||
ulong i = 0;
|
||||
ulong *mem = start;
|
||||
ulong readback;
|
||||
|
||||
for (i = 0; i < size / sizeof(ulong); i++) {
|
||||
mem[i] = i;
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
for (i = 0; i < size / sizeof(ulong); i++) {
|
||||
readback = mem[i];
|
||||
if (readback != i) {
|
||||
post_log("FPGA Memory error at %08x, "
|
||||
"wrote %08x, read %08x !\n",
|
||||
mem + i, i, readback);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fpga_post_test4(ulong *start, ulong size)
|
||||
{
|
||||
int ret = 0;
|
||||
ulong i = 0;
|
||||
ulong *mem = start;
|
||||
ulong readback;
|
||||
|
||||
for (i = 0; i < size / sizeof(ulong); i++) {
|
||||
mem[i] = ~i;
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
for (i = 0; i < size / sizeof(ulong); i++) {
|
||||
readback = mem[i];
|
||||
if (readback != ~i) {
|
||||
post_log("FPGA Memory error at %08x, "
|
||||
"wrote %08x, read %08x !\n",
|
||||
mem + i, ~i, readback);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* FPGA Memory-pattern-test */
|
||||
static int fpga_mem_test(void)
|
||||
{
|
||||
int ret = 0;
|
||||
ulong* start = (ulong *)FPGA_RAM_START;
|
||||
ulong size = FPGA_RAM_SIZE;
|
||||
|
||||
if (ret == 0)
|
||||
ret = fpga_post_test1(start, size, 0x00000000);
|
||||
|
||||
if (ret == 0)
|
||||
ret = fpga_post_test1(start, size, 0xffffffff);
|
||||
|
||||
if (ret == 0)
|
||||
ret = fpga_post_test1(start, size, 0x55555555);
|
||||
|
||||
if (ret == 0)
|
||||
ret = fpga_post_test1(start, size, 0xaaaaaaaa);
|
||||
|
||||
WATCHDOG_RESET();
|
||||
|
||||
if (ret == 0)
|
||||
ret = fpga_post_test2(start, size);
|
||||
|
||||
if (ret == 0)
|
||||
ret = fpga_post_test3(start, size);
|
||||
|
||||
if (ret == 0)
|
||||
ret = fpga_post_test4(start, size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Verify FPGA addresslines */
|
||||
static int fpga_post_addrline(ulong *address, ulong *base, ulong size)
|
||||
{
|
||||
unsigned long *target;
|
||||
unsigned long *end;
|
||||
unsigned long readback;
|
||||
unsigned long xor;
|
||||
int ret = 0;
|
||||
|
||||
end = (ulong *)((ulong)base + size);
|
||||
xor = 0;
|
||||
|
||||
for (xor = sizeof(ulong); xor > 0; xor <<= 1) {
|
||||
target = (ulong*)((ulong)address ^ xor);
|
||||
if ((target >= base) && (target < end)) {
|
||||
*address = ~*target;
|
||||
readback = *target;
|
||||
|
||||
if (readback == *address) {
|
||||
post_log("Memory (address line) error at %08x"
|
||||
"XOR value %08x !\n",
|
||||
address, target, xor);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Verify FPGA addresslines */
|
||||
static int fpga_post_dataline(ulong *address)
|
||||
{
|
||||
unsigned long temp32 = 0;
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pattern); i++) {
|
||||
*address = pattern[i];
|
||||
/*
|
||||
* Put a different pattern on the data lines: otherwise they
|
||||
* may float long enough to read back what we wrote.
|
||||
*/
|
||||
*(address + 1) = otherpattern;
|
||||
temp32 = *address;
|
||||
|
||||
if (temp32 != pattern[i]){
|
||||
post_log("Memory (date line) error at %08x, "
|
||||
"wrote %08x, read %08x !\n",
|
||||
address, pattern[i], temp32);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Verify FPGA, get version & memory size */
|
||||
int fpga_post_test(int flags)
|
||||
{
|
||||
uint old_value;
|
||||
uint version;
|
||||
uint read_value;
|
||||
int ret = 0;
|
||||
|
||||
post_log("\n");
|
||||
old_value = in_be32((void *)FPGA_SCRATCH_REG);
|
||||
|
||||
if (one_scratch_test(0x55555555))
|
||||
ret = 1;
|
||||
if (one_scratch_test(0xAAAAAAAA))
|
||||
ret = 1;
|
||||
|
||||
out_be32((void *)FPGA_SCRATCH_REG, old_value);
|
||||
|
||||
version = in_be32((void *)FPGA_VERSION_REG);
|
||||
post_log("FPGA version %u.%u\n",
|
||||
(version >> 8) & 0xFF, version & 0xFF);
|
||||
|
||||
/* Enable write to FPGA RAM */
|
||||
out_be32((void *)FPGA_STAT, in_be32((void *)FPGA_STAT) | 0x1000);
|
||||
|
||||
/* get RAM size */
|
||||
read_value = get_ram_size((void *)CONFIG_SYS_FPGA_BASE_1, FPGA_RAM_SIZE);
|
||||
post_log("FPGA RAM size %d bytes\n", read_value);
|
||||
WATCHDOG_RESET();
|
||||
|
||||
/* copy fpga memory to DDR2 RAM*/
|
||||
memcpy((void *)FPGA_BUFFER,(void *)FPGA_RAM_START, FPGA_RAM_SIZE);
|
||||
WATCHDOG_RESET();
|
||||
|
||||
/* Test datalines */
|
||||
if (fpga_post_dataline((ulong *)FPGA_RAM_START)) {
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
WATCHDOG_RESET();
|
||||
|
||||
/* Test addresslines */
|
||||
if (fpga_post_addrline((ulong *)FPGA_RAM_START,
|
||||
(ulong *)FPGA_RAM_START, FPGA_RAM_SIZE)) {
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
WATCHDOG_RESET();
|
||||
if (fpga_post_addrline((ulong *)FPGA_RAM_END - sizeof(long),
|
||||
(ulong *)FPGA_RAM_START, FPGA_RAM_SIZE)) {
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
WATCHDOG_RESET();
|
||||
|
||||
/* Memory Pattern Test */
|
||||
if (fpga_mem_test()) {
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
WATCHDOG_RESET();
|
||||
|
||||
/* restore memory */
|
||||
memcpy((void *)FPGA_RAM_START,(void *)FPGA_BUFFER, FPGA_RAM_SIZE);
|
||||
WATCHDOG_RESET();
|
||||
|
||||
out:
|
||||
/* Disable write to RAM */
|
||||
out_be32((void *)FPGA_STAT, in_be32((void *)FPGA_STAT) & 0xEFFF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_BSPEC3 */
|
||||
379
common/package/boot/uboot-ipq40xx/src/post/board/lwmon5/gdc.c
Normal file
379
common/package/boot/uboot-ipq40xx/src/post/board/lwmon5/gdc.c
Normal file
|
|
@ -0,0 +1,379 @@
|
|||
/*
|
||||
* (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com
|
||||
*
|
||||
* Developed for DENX Software Engineering GmbH
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
#include <common.h>
|
||||
|
||||
/* This test attempts to verify board GDC. A scratch register tested, then
|
||||
* simple memory test (get_ram_size()) run over GDC memory.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include <watchdog.h>
|
||||
#include <asm/io.h>
|
||||
#include <video.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define GDC_SCRATCH_REG 0xC1FF8044
|
||||
#define GDC_VERSION_REG 0xC1FF8084
|
||||
#define GDC_HOST_BASE 0xC1FC0000
|
||||
#define GDC_RAM_START 0xC0000000
|
||||
#define GDC_RAM_END (GDC_HOST_BASE - 1)
|
||||
#define GDC_RAM_SIZE (GDC_RAM_END - GDC_RAM_START)
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_BSPEC4
|
||||
|
||||
const static unsigned long pattern[] = {
|
||||
0xffffffff,
|
||||
0xaaaaaaaa,
|
||||
0xcccccccc,
|
||||
0xf0f0f0f0,
|
||||
0xff00ff00,
|
||||
0xffff0000,
|
||||
0x0000ffff,
|
||||
0x00ff00ff,
|
||||
0x0f0f0f0f,
|
||||
0x33333333,
|
||||
0x55555555,
|
||||
0x00000000
|
||||
};
|
||||
|
||||
const static unsigned long otherpattern = 0x01234567;
|
||||
|
||||
/* test write/read og a given LIME Register */
|
||||
static int gdc_test_reg_one(uint value)
|
||||
{
|
||||
uint read_value;
|
||||
|
||||
/* write test pattern */
|
||||
out_be32((void *)GDC_SCRATCH_REG, value);
|
||||
/* read other location (protect against data lines capacity) */
|
||||
in_be32((void *)GDC_RAM_START);
|
||||
/* verify test pattern */
|
||||
read_value = in_be32((void *)GDC_SCRATCH_REG);
|
||||
if (read_value != value) {
|
||||
post_log("GDC SCRATCH test failed write %08X, read %08X\n",
|
||||
value, read_value);
|
||||
}
|
||||
|
||||
return (read_value != value);
|
||||
}
|
||||
|
||||
/* test with a given static 32 bit pattern in a given memory addressrange */
|
||||
static int gdc_post_test1(ulong *start, ulong size, ulong val)
|
||||
{
|
||||
int ret = 0;
|
||||
ulong i = 0;
|
||||
ulong *mem = start;
|
||||
ulong readback;
|
||||
|
||||
for (i = 0; i < size / sizeof(ulong); i++) {
|
||||
mem[i] = val;
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
for (i = 0; i < size / sizeof(ulong); i++) {
|
||||
readback = mem[i];
|
||||
if (readback != val) {
|
||||
post_log("GDC Memory error at %08x, "
|
||||
"wrote %08x, read %08x !\n",
|
||||
mem + i, val, readback);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* test with dynamic 32 bit pattern in a given memory addressrange */
|
||||
static int gdc_post_test2(ulong *start, ulong size)
|
||||
{
|
||||
int ret = 0;
|
||||
ulong i = 0;
|
||||
ulong *mem = start;
|
||||
ulong readback;
|
||||
|
||||
for (i = 0; i < size / sizeof(ulong); i++) {
|
||||
mem[i] = 1 << (i % 32);
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
for (i = 0; i < size / sizeof(ulong); i++) {
|
||||
readback = mem[i];
|
||||
if (readback != 1 << (i % 32)) {
|
||||
post_log("GDC Memory error at %08x, "
|
||||
"wrote %08x, read %08x !\n",
|
||||
mem + i, 1 << (i % 32), readback);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* test with dynamic 32 bit pattern in a given memory addressrange */
|
||||
static int gdc_post_test3(ulong *start, ulong size)
|
||||
{
|
||||
int ret = 0;
|
||||
ulong i = 0;
|
||||
ulong *mem = start;
|
||||
ulong readback;
|
||||
|
||||
for (i = 0; i < size / sizeof(ulong); i++) {
|
||||
mem[i] = i;
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
for (i = 0; i < size / sizeof(ulong); i++) {
|
||||
readback = mem[i];
|
||||
if (readback != i) {
|
||||
post_log("GDC Memory error at %08x, "
|
||||
"wrote %08x, read %08x !\n",
|
||||
mem + i, i, readback);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* test with dynamic 32 bit pattern in a given memory addressrange */
|
||||
static int gdc_post_test4(ulong *start, ulong size)
|
||||
{
|
||||
int ret = 0;
|
||||
ulong i = 0;
|
||||
ulong *mem = start;
|
||||
ulong readback;
|
||||
|
||||
for (i = 0; i < size / sizeof(ulong); i++) {
|
||||
mem[i] = ~i;
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
for (i = 0; i < size / sizeof(ulong); i++) {
|
||||
readback = mem[i];
|
||||
if (readback != ~i) {
|
||||
post_log("GDC Memory error at %08x, "
|
||||
"wrote %08x, read %08x !\n",
|
||||
mem + i, ~i, readback);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* do some patterntests in a given addressrange */
|
||||
int gdc_mem_test(ulong *start, ulong size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* check addressrange and do different static and dynamic
|
||||
* pattern tests with it.
|
||||
*/
|
||||
if (((void *)start) + size <= (void *)GDC_RAM_END) {
|
||||
if (ret == 0)
|
||||
ret = gdc_post_test1(start, size, 0x00000000);
|
||||
|
||||
if (ret == 0)
|
||||
ret = gdc_post_test1(start, size, 0xffffffff);
|
||||
|
||||
if (ret == 0)
|
||||
ret = gdc_post_test1(start, size, 0x55555555);
|
||||
|
||||
if (ret == 0)
|
||||
ret = gdc_post_test1(start, size, 0xaaaaaaaa);
|
||||
|
||||
if (ret == 0)
|
||||
ret = gdc_post_test2(start, size);
|
||||
|
||||
if (ret == 0)
|
||||
ret = gdc_post_test3(start, size);
|
||||
|
||||
if (ret == 0)
|
||||
ret = gdc_post_test4(start, size);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* test function of gdc memory addresslines*/
|
||||
static int gdc_post_addrline(ulong *address, ulong *base, ulong size)
|
||||
{
|
||||
ulong *target;
|
||||
ulong *end;
|
||||
ulong readback = 0;
|
||||
ulong xor = 0;
|
||||
int ret = 0;
|
||||
|
||||
end = (ulong *)((ulong)base + size);
|
||||
|
||||
for (xor = sizeof(long); xor > 0; xor <<= 1) {
|
||||
target = (ulong *)((ulong)address ^ xor);
|
||||
if ((target >= base) && (target < end)) {
|
||||
*address = ~*target;
|
||||
readback = *target;
|
||||
}
|
||||
|
||||
if (readback == *address) {
|
||||
post_log("GDC Memory (address line) error at %08x"
|
||||
"XOR value %08x !\n",
|
||||
address, target , xor);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int gdc_post_dataline(ulong *address)
|
||||
{
|
||||
unsigned long temp32 = 0;
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pattern); i++) {
|
||||
*address = pattern[i];
|
||||
/*
|
||||
* Put a different pattern on the data lines: otherwise they
|
||||
* may float long enough to read back what we wrote.
|
||||
*/
|
||||
*(address + 1) = otherpattern;
|
||||
temp32 = *address;
|
||||
|
||||
if (temp32 != pattern[i]){
|
||||
post_log("GDC Memory (date line) error at %08x, "
|
||||
"wrote %08x, read %08x !\n",
|
||||
address, pattern[i], temp32);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Verify GDC, get memory size, verify GDC memory */
|
||||
int gdc_post_test(int flags)
|
||||
{
|
||||
uint old_value;
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
|
||||
post_log("\n");
|
||||
old_value = in_be32((void *)GDC_SCRATCH_REG);
|
||||
|
||||
/*
|
||||
* GPIOC2 register behaviour: the LIME graphics processor has a
|
||||
* maximum of 5 GPIO ports that can be used in this hardware
|
||||
* configuration. Thus only the bits for these 5 GPIOs can be
|
||||
* activated in the GPIOC2 register. All other bits will always be
|
||||
* read as zero.
|
||||
*/
|
||||
if (gdc_test_reg_one(0x00150015))
|
||||
ret = 1;
|
||||
if (gdc_test_reg_one(0x000A000A))
|
||||
ret = 1;
|
||||
|
||||
out_be32((void *)GDC_SCRATCH_REG, old_value);
|
||||
|
||||
old_value = in_be32((void *)GDC_VERSION_REG);
|
||||
post_log("GDC chip version %u.%u, year %04X\n",
|
||||
(old_value >> 8) & 0xFF, old_value & 0xFF,
|
||||
(old_value >> 16) & 0xFFFF);
|
||||
|
||||
old_value = get_ram_size((void *)GDC_RAM_START,
|
||||
0x02000000);
|
||||
|
||||
debug("GDC RAM size (ist): %d bytes\n", old_value);
|
||||
debug("GDC RAM size (soll): %d bytes\n", GDC_RAM_SIZE);
|
||||
post_log("GDC RAM size: %d bytes\n", old_value);
|
||||
|
||||
/* Test SDRAM datalines */
|
||||
if (gdc_post_dataline((ulong *)GDC_RAM_START)) {
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
WATCHDOG_RESET();
|
||||
|
||||
/* Test SDRAM adresslines */
|
||||
if (gdc_post_addrline((ulong *)GDC_RAM_START,
|
||||
(ulong *)GDC_RAM_START, GDC_RAM_SIZE)) {
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
WATCHDOG_RESET();
|
||||
if (gdc_post_addrline((ulong *)GDC_RAM_END - sizeof(long),
|
||||
(ulong *)GDC_RAM_START, GDC_RAM_SIZE)) {
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
WATCHDOG_RESET();
|
||||
|
||||
/* memory pattern test */
|
||||
debug("GDC Memory test (flags %8x:%8x)\n", flags,
|
||||
POST_SLOWTEST | POST_MANUAL);
|
||||
|
||||
if (flags & POST_MANUAL) {
|
||||
debug("Full memory test\n");
|
||||
if (gdc_mem_test((ulong *)GDC_RAM_START, GDC_RAM_SIZE)) {
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
/* load splashscreen again */
|
||||
} else {
|
||||
debug("smart memory test\n");
|
||||
for (i = 0; i < (GDC_RAM_SIZE >> 20) && ret == 0; i++) {
|
||||
if (ret == 0)
|
||||
ret = gdc_mem_test((ulong *)(GDC_RAM_START +
|
||||
(i << 20)),
|
||||
0x800);
|
||||
if (ret == 0)
|
||||
ret = gdc_mem_test((ulong *)(GDC_RAM_START +
|
||||
(i << 20) + 0xff800),
|
||||
0x800);
|
||||
}
|
||||
}
|
||||
WATCHDOG_RESET();
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_BSPEC4 */
|
||||
293
common/package/boot/uboot-ipq40xx/src/post/board/lwmon5/sysmon.c
Normal file
293
common/package/boot/uboot-ipq40xx/src/post/board/lwmon5/sysmon.c
Normal file
|
|
@ -0,0 +1,293 @@
|
|||
/*
|
||||
* (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com
|
||||
*
|
||||
* Developed for DENX Software Engineering GmbH
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* SYSMON test
|
||||
*
|
||||
* This test performs the system hardware monitoring.
|
||||
* The test passes when all the following voltages and temperatures
|
||||
* are within allowed ranges:
|
||||
*
|
||||
* Temperature -40 .. +90 C
|
||||
* +5V +4.50 .. +5.50 V
|
||||
* +5V standby +3.50 .. +5.50 V
|
||||
*
|
||||
* LCD backlight is not enabled if temperature values are not within
|
||||
* allowed ranges (-30 .. + 80). The brightness of backlite can be
|
||||
* controlled by setting "brightness" enviroment variable. Default value is 50%
|
||||
*
|
||||
* See the list of all parameters in the sysmon_table below
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include <watchdog.h>
|
||||
#include <i2c.h>
|
||||
|
||||
#if defined(CONFIG_VIDEO)
|
||||
#include <mb862xx.h>
|
||||
#endif
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_SYSMON
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* from dspic.c */
|
||||
extern int dspic_read(ushort reg, ushort *data);
|
||||
|
||||
#define REG_TEMPERATURE 0x12BC
|
||||
#define REG_VOLTAGE_5V 0x12CA
|
||||
#define REG_VOLTAGE_5V_STANDBY 0x12C6
|
||||
|
||||
#define TEMPERATURE_MIN (-40) /* degr. C */
|
||||
#define TEMPERATURE_MAX (+90) /* degr. C */
|
||||
#define TEMPERATURE_DISPLAY_MIN (-35) /* degr. C */
|
||||
#define TEMPERATURE_DISPLAY_MAX (+85) /* degr. C */
|
||||
|
||||
#define VOLTAGE_5V_MIN (+4500) /* mV */
|
||||
#define VOLTAGE_5V_MAX (+5500) /* mV */
|
||||
|
||||
#define VOLTAGE_5V_STANDBY_MIN (+3500) /* mV */
|
||||
#define VOLTAGE_5V_STANDBY_MAX (+5500) /* mV */
|
||||
|
||||
typedef struct sysmon_s sysmon_t;
|
||||
typedef struct sysmon_table_s sysmon_table_t;
|
||||
|
||||
static void sysmon_dspic_init(sysmon_t *this);
|
||||
static int sysmon_dspic_read(sysmon_t *this, uint addr, int *val);
|
||||
static int sysmon_dspic_read_sgn(sysmon_t *this, uint addr, int *val);
|
||||
static void sysmon_backlight_disable(sysmon_table_t *this);
|
||||
|
||||
struct sysmon_s {
|
||||
uchar chip;
|
||||
void (*init)(sysmon_t *);
|
||||
int (*read)(sysmon_t *, uint, int *);
|
||||
};
|
||||
|
||||
static sysmon_t sysmon_dspic = {
|
||||
CONFIG_SYS_I2C_DSPIC_IO_ADDR,
|
||||
sysmon_dspic_init,
|
||||
sysmon_dspic_read
|
||||
};
|
||||
|
||||
static sysmon_t sysmon_dspic_sgn = {
|
||||
CONFIG_SYS_I2C_DSPIC_IO_ADDR,
|
||||
sysmon_dspic_init,
|
||||
sysmon_dspic_read_sgn
|
||||
};
|
||||
|
||||
static sysmon_t *sysmon_list[] = {
|
||||
&sysmon_dspic,
|
||||
NULL
|
||||
};
|
||||
|
||||
struct sysmon_table_s {
|
||||
char *name;
|
||||
char *unit_name;
|
||||
sysmon_t *sysmon;
|
||||
void (*exec_before)(sysmon_table_t *);
|
||||
void (*exec_after)(sysmon_table_t *);
|
||||
|
||||
int unit_precision;
|
||||
int unit_div;
|
||||
int unit_min;
|
||||
int unit_max;
|
||||
uint val_mask;
|
||||
uint val_min;
|
||||
uint val_max;
|
||||
int val_valid;
|
||||
uint val_min_alt;
|
||||
uint val_max_alt;
|
||||
int val_valid_alt;
|
||||
uint addr;
|
||||
};
|
||||
|
||||
static sysmon_table_t sysmon_table[] = {
|
||||
{
|
||||
"Temperature", " C", &sysmon_dspic, NULL, sysmon_backlight_disable,
|
||||
1, 1, -32768, 32767, 0xFFFF,
|
||||
0x8000 + TEMPERATURE_MIN, 0x8000 + TEMPERATURE_MAX, 0,
|
||||
0x8000 + TEMPERATURE_DISPLAY_MIN, 0x8000 + TEMPERATURE_DISPLAY_MAX, 0,
|
||||
REG_TEMPERATURE,
|
||||
},
|
||||
|
||||
{
|
||||
"+ 5 V", "V", &sysmon_dspic, NULL, NULL,
|
||||
100, 1000, -0x8000, 0x7FFF, 0xFFFF,
|
||||
0x8000 + VOLTAGE_5V_MIN, 0x8000 + VOLTAGE_5V_MAX, 0,
|
||||
0x8000 + VOLTAGE_5V_MIN, 0x8000 + VOLTAGE_5V_MAX, 0,
|
||||
REG_VOLTAGE_5V,
|
||||
},
|
||||
|
||||
{
|
||||
"+ 5 V standby", "V", &sysmon_dspic, NULL, NULL,
|
||||
100, 1000, -0x8000, 0x7FFF, 0xFFFF,
|
||||
0x8000 + VOLTAGE_5V_STANDBY_MIN, 0x8000 + VOLTAGE_5V_STANDBY_MAX, 0,
|
||||
0x8000 + VOLTAGE_5V_STANDBY_MIN, 0x8000 + VOLTAGE_5V_STANDBY_MAX, 0,
|
||||
REG_VOLTAGE_5V_STANDBY,
|
||||
},
|
||||
|
||||
{
|
||||
"Temperature", "°C", &sysmon_dspic_sgn, NULL, sysmon_backlight_disable,
|
||||
1, 1, -32768, 32767, 0xFFFF,
|
||||
0x8000 + TEMPERATURE_MIN, 0x8000 + TEMPERATURE_MAX, 0,
|
||||
0x8000 + TEMPERATURE_DISPLAY_MIN, 0x8000 + TEMPERATURE_DISPLAY_MAX, 0,
|
||||
REG_TEMPERATURE,
|
||||
},
|
||||
};
|
||||
|
||||
int sysmon_init_f(void)
|
||||
{
|
||||
sysmon_t **l;
|
||||
|
||||
for (l = sysmon_list; *l; l++)
|
||||
(*l)->init(*l);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sysmon_reloc(void)
|
||||
{
|
||||
/* Do nothing for now, sysmon_reloc() is required by the sysmon post */
|
||||
}
|
||||
|
||||
static char *sysmon_unit_value(sysmon_table_t *s, uint val)
|
||||
{
|
||||
static char buf[32];
|
||||
char *p, sign;
|
||||
int decimal, frac;
|
||||
int unit_val;
|
||||
|
||||
unit_val = s->unit_min + (s->unit_max - s->unit_min) * val / s->val_mask;
|
||||
|
||||
if (val == -1)
|
||||
return "I/O ERROR";
|
||||
|
||||
if (unit_val < 0) {
|
||||
sign = '-';
|
||||
unit_val = -unit_val;
|
||||
} else {
|
||||
sign = '+';
|
||||
}
|
||||
|
||||
p = buf + sprintf(buf, "%c%2d", sign, unit_val / s->unit_div);
|
||||
|
||||
frac = unit_val % s->unit_div;
|
||||
frac /= (s->unit_div / s->unit_precision);
|
||||
|
||||
decimal = s->unit_precision;
|
||||
|
||||
if (decimal != 1)
|
||||
*p++ = '.';
|
||||
for (decimal /= 10; decimal != 0; decimal /= 10)
|
||||
*p++ = '0' + (frac / decimal) % 10;
|
||||
strcpy(p, s->unit_name);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void sysmon_dspic_init(sysmon_t *this)
|
||||
{
|
||||
}
|
||||
|
||||
static int sysmon_dspic_read(sysmon_t *this, uint addr, int *val)
|
||||
{
|
||||
ushort data;
|
||||
|
||||
if (dspic_read(addr, &data) == 0){
|
||||
/* To fit into the table range we should add 0x8000 */
|
||||
*val = data + 0x8000;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int sysmon_dspic_read_sgn(sysmon_t *this, uint addr, int *val)
|
||||
{
|
||||
ushort data;
|
||||
|
||||
if (dspic_read(addr, &data) == 0){
|
||||
/* To fit into the table range we should add 0x8000 */
|
||||
*val = (signed short)data + 0x8000;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void sysmon_backlight_disable(sysmon_table_t *this)
|
||||
{
|
||||
#if defined(CONFIG_VIDEO)
|
||||
board_backlight_switch(this->val_valid_alt);
|
||||
#endif
|
||||
}
|
||||
|
||||
int sysmon_post_test(int flags)
|
||||
{
|
||||
int res = 0;
|
||||
sysmon_table_t * t;
|
||||
int val;
|
||||
|
||||
for (t = sysmon_table; t < sysmon_table + ARRAY_SIZE(sysmon_table); t++) {
|
||||
t->val_valid = 1;
|
||||
if (t->exec_before)
|
||||
t->exec_before(t);
|
||||
|
||||
if (t->sysmon->read(t->sysmon, t->addr, &val) != 0) {
|
||||
t->val_valid = 0;
|
||||
t->val_valid_alt = 0;
|
||||
post_log(": read failed\n");
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (t->val_valid != 0) {
|
||||
t->val_valid = val >= t->val_min && val <= t->val_max;
|
||||
t->val_valid_alt = val >= t->val_min_alt && val <= t->val_max_alt;
|
||||
}
|
||||
|
||||
if (t->exec_after)
|
||||
t->exec_after(t);
|
||||
|
||||
if ((!t->val_valid) || (flags)) {
|
||||
post_log("\n\t%-17s = %-10s ", t->name, sysmon_unit_value(t, val));
|
||||
post_log("allowed range");
|
||||
post_log(" %-8s ..", sysmon_unit_value(t, t->val_min));
|
||||
post_log(" %-8s", sysmon_unit_value(t, t->val_max));
|
||||
post_log(" %s", t->val_valid ? "OK" : "FAIL");
|
||||
}
|
||||
|
||||
if (!t->val_valid) {
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
post_log("\n");
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_SYSMON */
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com
|
||||
*
|
||||
* Developed for DENX Software Engineering GmbH
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/* This test verifies if the reason of last reset was an abnormal voltage
|
||||
* condition, than it performs watchdog test, measuing time required to
|
||||
* trigger watchdog reset.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_WATCHDOG
|
||||
|
||||
#include <watchdog.h>
|
||||
#include <asm/ppc4xx-gpio.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
static uint watchdog_magic_read(void)
|
||||
{
|
||||
return in_be32((void *)CONFIG_SYS_WATCHDOG_FLAGS_ADDR) &
|
||||
CONFIG_SYS_WATCHDOG_MAGIC_MASK;
|
||||
}
|
||||
|
||||
static void watchdog_magic_write(uint value)
|
||||
{
|
||||
out_be32((void *)CONFIG_SYS_WATCHDOG_FLAGS_ADDR, value |
|
||||
(in_be32((void *)CONFIG_SYS_WATCHDOG_FLAGS_ADDR) &
|
||||
~CONFIG_SYS_WATCHDOG_MAGIC_MASK));
|
||||
}
|
||||
|
||||
int sysmon1_post_test(int flags)
|
||||
{
|
||||
if (gpio_read_in_bit(CONFIG_SYS_GPIO_SYSMON_STATUS) == 0) {
|
||||
/*
|
||||
* 3.1. GPIO62 is low
|
||||
* Assuming system voltage failure.
|
||||
*/
|
||||
post_log("sysmon1 Abnormal voltage detected (GPIO62)\n");
|
||||
post_log("POST sysmon1 FAILED\n");
|
||||
return 1;
|
||||
} else {
|
||||
post_log("sysmon1 PASSED\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lwmon5_watchdog_post_test(int flags)
|
||||
{
|
||||
/* On each reset scratch register 1 should be tested,
|
||||
* but first test GPIO62:
|
||||
*/
|
||||
if (!(flags & POST_MANUAL) && sysmon1_post_test(flags)) {
|
||||
/* 3.1. GPIO62 is low
|
||||
* Assuming system voltage failure.
|
||||
*/
|
||||
/* 3.1.1. Set scratch register 1 to 0x0000xxxx */
|
||||
watchdog_magic_write(0);
|
||||
/* 3.1.2. Mark test as failed due to voltage?! */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (watchdog_magic_read() != CONFIG_SYS_WATCHDOG_MAGIC) {
|
||||
/* 3.2. Scratch register 1 differs from magic value 0x1248xxxx
|
||||
* Assuming PowerOn
|
||||
*/
|
||||
int ints;
|
||||
ulong base;
|
||||
ulong time;
|
||||
|
||||
/* 3.2.1. Set magic value to scratch register */
|
||||
watchdog_magic_write(CONFIG_SYS_WATCHDOG_MAGIC);
|
||||
|
||||
ints = disable_interrupts ();
|
||||
/* 3.2.2. strobe watchdog once */
|
||||
WATCHDOG_RESET();
|
||||
out_be32((void *)CONFIG_SYS_WATCHDOG_TIME_ADDR, 0);
|
||||
/* 3.2.3. save time of strobe in scratch register 2 */
|
||||
base = post_time_ms (0);
|
||||
|
||||
/* 3.2.4. Wait for 150 ms (enough for reset to happen) */
|
||||
while ((time = post_time_ms (base)) < 150)
|
||||
out_be32((void *)CONFIG_SYS_WATCHDOG_TIME_ADDR, time);
|
||||
if (ints)
|
||||
enable_interrupts ();
|
||||
|
||||
/* 3.2.5. Reset didn't happen. - Set 0x0000xxxx
|
||||
* into scratch register 1
|
||||
*/
|
||||
watchdog_magic_write(0);
|
||||
/* 3.2.6. Mark test as failed. */
|
||||
post_log("hw watchdog time : %u ms, failed ", time);
|
||||
return 2;
|
||||
} else {
|
||||
/* 3.3. Scratch register matches magic value 0x1248xxxx
|
||||
* Assume this is watchdog-initiated reset
|
||||
*/
|
||||
ulong time;
|
||||
/* 3.3.1. So, the test succeed, save measured time to syslog. */
|
||||
time = in_be32((void *)CONFIG_SYS_WATCHDOG_TIME_ADDR);
|
||||
if (time > 90 ) { /* ms*/
|
||||
post_log("hw watchdog time : %u ms, passed ", time);
|
||||
/* 3.3.2. Set scratch register 1 to 0x0000xxxx */
|
||||
watchdog_magic_write(0);
|
||||
return 0;
|
||||
} else {
|
||||
/*test minimum watchdogtime */
|
||||
post_log("hw watchdog time : %u ms, failed ", time);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_WATCHDOG */
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
#
|
||||
# (C) Copyright 2002-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
include $(OBJTREE)/include/autoconf.mk
|
||||
|
||||
LIB = libpostnetta.o
|
||||
|
||||
COBJS-$(CONFIG_HAS_POST) += codec.o dsp.o
|
||||
|
||||
include $(TOPDIR)/post/rules.mk
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* (C) Copyright 2004
|
||||
* Pantelis Antoniou, Intracom S.A. , panto@intracom.gr
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CODEC test
|
||||
*
|
||||
* This test verifies the connection and performs a memory test
|
||||
* on any connected codec(s). The meat of the work is done
|
||||
* in the board specific function.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CODEC
|
||||
|
||||
extern int board_post_codec(int flags);
|
||||
|
||||
int codec_post_test (int flags)
|
||||
{
|
||||
return board_post_codec(flags);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_CODEC */
|
||||
45
common/package/boot/uboot-ipq40xx/src/post/board/netta/dsp.c
Normal file
45
common/package/boot/uboot-ipq40xx/src/post/board/netta/dsp.c
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* (C) Copyright 2004
|
||||
* Pantelis Antoniou, Intracom S.A. , panto@intracom.gr
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* DSP test
|
||||
*
|
||||
* This test verifies the connection and performs a memory test
|
||||
* on any connected DSP(s). The meat of the work is done
|
||||
* in the board specific function.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_DSP
|
||||
|
||||
extern int board_post_dsp(int flags);
|
||||
|
||||
int dsp_post_test (int flags)
|
||||
{
|
||||
return board_post_dsp(flags);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_DSP */
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
#
|
||||
# (C) Copyright 2010 DENX Software Engineering
|
||||
# Anatolij Gustschin, agust@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
include $(OBJTREE)/include/autoconf.mk
|
||||
|
||||
LIB = libpostpdm360ng.o
|
||||
|
||||
COBJS-$(CONFIG_HAS_POST) += coproc_com.o
|
||||
|
||||
include $(TOPDIR)/post/rules.mk
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* (C) Copyright 2010 DENX Software Engineering,
|
||||
* Anatolij Gustschin, agust@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* Co-Processor communication POST
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <post.h>
|
||||
#include <serial.h>
|
||||
|
||||
#if defined(CONFIG_SERIAL_MULTI)
|
||||
|
||||
/*
|
||||
* Actually the termination sequence of the coprocessor
|
||||
* commands is "\r\n" (CR LF), but here we use a side effect of
|
||||
* the putc() routine of the serial driver which checks for LF
|
||||
* and sends CR before sending LF. Therefore the termination
|
||||
* sequence in the command below is only "\n".
|
||||
* "alive" string is the coprocessor response for ping command
|
||||
* and not a command, therefore it is terminated with "\r\n".
|
||||
*/
|
||||
char alive[] = "$AL;38\r\n";
|
||||
char ping[] = "$PI;2C\n";
|
||||
|
||||
int coprocessor_post_test(int flags)
|
||||
{
|
||||
struct stdio_dev *cop_port;
|
||||
int ret;
|
||||
char buf[10];
|
||||
|
||||
/* Test IO Coprocessor communication */
|
||||
cop_port = open_port(4, CONFIG_SYS_PDM360NG_COPROC_BAUDRATE);
|
||||
if (!cop_port)
|
||||
return -1;
|
||||
|
||||
write_port(cop_port, ping);
|
||||
udelay(CONFIG_SYS_PDM360NG_COPROC_READ_DELAY);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
ret = read_port(cop_port, buf, sizeof(buf));
|
||||
close_port(4);
|
||||
if (ret <= 0) {
|
||||
post_log("Error: Can't read IO Coprocessor port.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strcmp(buf, alive)) {
|
||||
post_log("Error: IO-Cop. resp.: %s\n", buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Test WD Coprocessor communication */
|
||||
cop_port = open_port(1, CONFIG_SYS_PDM360NG_COPROC_BAUDRATE);
|
||||
if (!cop_port) {
|
||||
post_log("Error: Can't open WD Coprocessor port.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
write_port(cop_port, ping);
|
||||
udelay(CONFIG_SYS_PDM360NG_COPROC_READ_DELAY);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
ret = read_port(cop_port, buf, sizeof(buf));
|
||||
close_port(1);
|
||||
if (ret <= 0) {
|
||||
post_log("Error: Can't read WD Coprocessor port.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strcmp(buf, alive)) {
|
||||
post_log("Error: WD-Cop. resp.: %s\n", buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_SERIAL_MULTI */
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#
|
||||
# (C) Copyright 2002-2007
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
include $(OBJTREE)/include/autoconf.mk
|
||||
|
||||
LIB = libpostmpc83xx.o
|
||||
|
||||
AOBJS-$(CONFIG_HAS_POST) +=
|
||||
COBJS-$(CONFIG_HAS_POST) += ecc.o
|
||||
|
||||
include $(TOPDIR)/post/rules.mk
|
||||
166
common/package/boot/uboot-ipq40xx/src/post/cpu/mpc83xx/ecc.c
Normal file
166
common/package/boot/uboot-ipq40xx/src/post/cpu/mpc83xx/ecc.c
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* (C) Copyright 2010
|
||||
* Eastman Kodak Company, <www.kodak.com>
|
||||
* Michael Zaidman, <michael.zaidman@kodak.com>
|
||||
*
|
||||
* The code is based on the cpu/mpc83xx/ecc.c written by
|
||||
* Dave Liu <daveliu@freescale.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc83xx.h>
|
||||
#include <watchdog.h>
|
||||
#include <asm/io.h>
|
||||
#include <post.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_ECC
|
||||
/*
|
||||
* We use the RAW I/O accessors where possible in order to
|
||||
* achieve performance goal, since the test's execution time
|
||||
* affects the board start up time.
|
||||
*/
|
||||
static inline void ecc_clear(ddr83xx_t *ddr)
|
||||
{
|
||||
/* Clear capture registers */
|
||||
__raw_writel(0, &ddr->capture_address);
|
||||
__raw_writel(0, &ddr->capture_data_hi);
|
||||
__raw_writel(0, &ddr->capture_data_lo);
|
||||
__raw_writel(0, &ddr->capture_ecc);
|
||||
__raw_writel(0, &ddr->capture_attributes);
|
||||
|
||||
/* Clear SBEC and set SBET to 1 */
|
||||
out_be32(&ddr->err_sbe, 1 << ECC_ERROR_MAN_SBET_SHIFT);
|
||||
|
||||
/* Clear Error Detect register */
|
||||
out_be32(&ddr->err_detect, ECC_ERROR_DETECT_MME |\
|
||||
ECC_ERROR_DETECT_MBE |\
|
||||
ECC_ERROR_DETECT_SBE |\
|
||||
ECC_ERROR_DETECT_MSE);
|
||||
|
||||
isync();
|
||||
}
|
||||
|
||||
int ecc_post_test(int flags)
|
||||
{
|
||||
int ret = 0;
|
||||
int int_state;
|
||||
int errbit;
|
||||
u32 pattern[2], writeback[2], retval[2];
|
||||
ddr83xx_t *ddr = &((immap_t *)CONFIG_SYS_IMMR)->ddr;
|
||||
volatile u64 *addr = (u64 *)CONFIG_SYS_POST_ECC_START_ADDR;
|
||||
|
||||
/* The pattern is written into memory to generate error */
|
||||
pattern[0] = 0xfedcba98UL;
|
||||
pattern[1] = 0x76543210UL;
|
||||
|
||||
/* After injecting error, re-initialize the memory with the value */
|
||||
writeback[0] = ~pattern[0];
|
||||
writeback[1] = ~pattern[1];
|
||||
|
||||
/* Check if ECC is enabled */
|
||||
if (__raw_readl(&ddr->err_disable) & ECC_ERROR_ENABLE) {
|
||||
debug("DDR's ECC is not enabled, skipping the ECC POST.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int_state = disable_interrupts();
|
||||
icache_enable();
|
||||
|
||||
#ifdef CONFIG_DDR_32BIT
|
||||
/* It seems like no one really uses the CONFIG_DDR_32BIT mode */
|
||||
#error "Add ECC POST support for CONFIG_DDR_32BIT here!"
|
||||
#else
|
||||
for (addr = (u64*)CONFIG_SYS_POST_ECC_START_ADDR, errbit=0;
|
||||
addr < (u64*)CONFIG_SYS_POST_ECC_STOP_ADDR; addr++, errbit++ ) {
|
||||
|
||||
WATCHDOG_RESET();
|
||||
|
||||
ecc_clear(ddr);
|
||||
|
||||
/* Enable error injection */
|
||||
setbits_be32(&ddr->ecc_err_inject, ECC_ERR_INJECT_EIEN);
|
||||
sync();
|
||||
isync();
|
||||
|
||||
/* Set bit to be injected */
|
||||
if (errbit < 32) {
|
||||
__raw_writel(1 << errbit, &ddr->data_err_inject_lo);
|
||||
__raw_writel(0, &ddr->data_err_inject_hi);
|
||||
} else {
|
||||
__raw_writel(0, &ddr->data_err_inject_lo);
|
||||
__raw_writel(1<<(errbit-32), &ddr->data_err_inject_hi);
|
||||
}
|
||||
sync();
|
||||
isync();
|
||||
|
||||
/* Write memory location injecting SBE */
|
||||
ppcDWstore((u32*)addr, pattern);
|
||||
sync();
|
||||
|
||||
/* Disable error injection */
|
||||
clrbits_be32(&ddr->ecc_err_inject, ECC_ERR_INJECT_EIEN);
|
||||
sync();
|
||||
isync();
|
||||
|
||||
/* Data read should generate SBE */
|
||||
ppcDWload((u32*)addr, retval);
|
||||
sync();
|
||||
|
||||
if (!(__raw_readl(&ddr->err_detect) & ECC_ERROR_DETECT_SBE) ||
|
||||
(__raw_readl(&ddr->data_err_inject_hi) !=
|
||||
(__raw_readl(&ddr->capture_data_hi) ^ pattern[0])) ||
|
||||
(__raw_readl(&ddr->data_err_inject_lo) !=
|
||||
(__raw_readl(&ddr->capture_data_lo) ^ pattern[1]))) {
|
||||
|
||||
post_log("ECC failed to detect SBE error at %08x, "
|
||||
"SBE injection mask %08x-%08x, wrote "
|
||||
"%08x-%08x, read %08x-%08x\n", addr,
|
||||
ddr->data_err_inject_hi,
|
||||
ddr->data_err_inject_lo,
|
||||
pattern[0], pattern[1],
|
||||
retval[0], retval[1]);
|
||||
|
||||
printf("ERR_DETECT Reg: %08x\n", ddr->err_detect);
|
||||
printf("ECC CAPTURE_DATA Reg: %08x-%08x\n",
|
||||
ddr->capture_data_hi, ddr->capture_data_lo);
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Re-initialize the ECC memory */
|
||||
ppcDWstore((u32*)addr, writeback);
|
||||
sync();
|
||||
isync();
|
||||
|
||||
errbit %= 63;
|
||||
}
|
||||
#endif /* !CONFIG_DDR_32BIT */
|
||||
|
||||
ecc_clear(ddr);
|
||||
|
||||
icache_disable();
|
||||
|
||||
if (int_state)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#
|
||||
# (C) Copyright 2002-2007
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
include $(OBJTREE)/include/autoconf.mk
|
||||
|
||||
LIB = libpostmpc8xx.o
|
||||
|
||||
AOBJS-$(CONFIG_HAS_POST) += cache_8xx.o
|
||||
COBJS-$(CONFIG_HAS_POST) += cache.o ether.o spr.o uart.o usb.o watchdog.o
|
||||
|
||||
include $(TOPDIR)/post/rules.mk
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/* Cache test
|
||||
*
|
||||
* This test verifies the CPU data and instruction cache using
|
||||
* several test scenarios.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include <watchdog.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CACHE
|
||||
|
||||
#define CACHE_POST_SIZE 1024
|
||||
|
||||
extern int cache_post_test1 (char *, unsigned int);
|
||||
extern int cache_post_test2 (char *, unsigned int);
|
||||
extern int cache_post_test3 (char *, unsigned int);
|
||||
extern int cache_post_test4 (char *, unsigned int);
|
||||
extern int cache_post_test5 (void);
|
||||
extern int cache_post_test6 (void);
|
||||
|
||||
int cache_post_test (int flags)
|
||||
{
|
||||
int ints = disable_interrupts ();
|
||||
int res = 0;
|
||||
static char ta[CACHE_POST_SIZE + 0xf];
|
||||
char *testarea = (char *) (((unsigned long) ta + 0xf) & ~0xf);
|
||||
|
||||
WATCHDOG_RESET ();
|
||||
if (res == 0)
|
||||
res = cache_post_test1 (testarea, CACHE_POST_SIZE);
|
||||
WATCHDOG_RESET ();
|
||||
if (res == 0)
|
||||
res = cache_post_test2 (testarea, CACHE_POST_SIZE);
|
||||
WATCHDOG_RESET ();
|
||||
if (res == 0)
|
||||
res = cache_post_test3 (testarea, CACHE_POST_SIZE);
|
||||
WATCHDOG_RESET ();
|
||||
if (res == 0)
|
||||
res = cache_post_test4 (testarea, CACHE_POST_SIZE);
|
||||
WATCHDOG_RESET ();
|
||||
if (res == 0)
|
||||
res = cache_post_test5 ();
|
||||
WATCHDOG_RESET ();
|
||||
if (res == 0)
|
||||
res = cache_post_test6 ();
|
||||
|
||||
WATCHDOG_RESET ();
|
||||
if (ints)
|
||||
enable_interrupts ();
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_CACHE */
|
||||
|
|
@ -0,0 +1,493 @@
|
|||
/*
|
||||
* Copyright (C) 2002 Wolfgang Denk <wd@denx.de>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined(CONFIG_MPC823) || \
|
||||
defined(CONFIG_MPC850) || \
|
||||
defined(CONFIG_MPC855) || \
|
||||
defined(CONFIG_MPC860) || \
|
||||
defined(CONFIG_MPC862)
|
||||
|
||||
#include <post.h>
|
||||
#include <ppc_asm.tmpl>
|
||||
#include <ppc_defs.h>
|
||||
#include <asm/cache.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CACHE
|
||||
|
||||
.text
|
||||
|
||||
cache_post_dinvalidate:
|
||||
lis r10, IDC_INVALL@h
|
||||
mtspr DC_CST, r10
|
||||
blr
|
||||
|
||||
cache_post_iinvalidate:
|
||||
lis r10, IDC_INVALL@h
|
||||
mtspr IC_CST, r10
|
||||
isync
|
||||
blr
|
||||
|
||||
cache_post_ddisable:
|
||||
lis r10, IDC_DISABLE@h
|
||||
mtspr DC_CST, r10
|
||||
blr
|
||||
|
||||
cache_post_dwb:
|
||||
lis r10, IDC_ENABLE@h
|
||||
mtspr DC_CST, r10
|
||||
lis r10, DC_CFWT@h
|
||||
mtspr DC_CST, r10
|
||||
blr
|
||||
|
||||
cache_post_dwt:
|
||||
lis r10, IDC_ENABLE@h
|
||||
mtspr DC_CST, r10
|
||||
lis r10, DC_SFWT@h
|
||||
mtspr DC_CST, r10
|
||||
blr
|
||||
|
||||
cache_post_idisable:
|
||||
lis r10, IDC_DISABLE@h
|
||||
mtspr IC_CST, r10
|
||||
isync
|
||||
blr
|
||||
|
||||
cache_post_ienable:
|
||||
lis r10, IDC_ENABLE@h
|
||||
mtspr IC_CST, r10
|
||||
isync
|
||||
blr
|
||||
|
||||
cache_post_iunlock:
|
||||
lis r10, IDC_UNALL@h
|
||||
mtspr IC_CST, r10
|
||||
isync
|
||||
blr
|
||||
|
||||
cache_post_ilock:
|
||||
mtspr IC_ADR, r3
|
||||
lis r10, IDC_LDLCK@h
|
||||
mtspr IC_CST, r10
|
||||
isync
|
||||
blr
|
||||
|
||||
/*
|
||||
* turn on the data cache
|
||||
* switch the data cache to write-back or write-through mode
|
||||
* invalidate the data cache
|
||||
* write the negative pattern to a cached area
|
||||
* read the area
|
||||
*
|
||||
* The negative pattern must be read at the last step
|
||||
*/
|
||||
.global cache_post_test1
|
||||
cache_post_test1:
|
||||
mflr r0
|
||||
stw r0, 4(r1)
|
||||
|
||||
stwu r3, -4(r1)
|
||||
stwu r4, -4(r1)
|
||||
|
||||
bl cache_post_dwb
|
||||
bl cache_post_dinvalidate
|
||||
|
||||
/* Write the negative pattern to the test area */
|
||||
lwz r0, 0(r1)
|
||||
mtctr r0
|
||||
li r0, 0xff
|
||||
lwz r3, 4(r1)
|
||||
subi r3, r3, 1
|
||||
1:
|
||||
stbu r0, 1(r3)
|
||||
bdnz 1b
|
||||
|
||||
/* Read the test area */
|
||||
lwz r0, 0(r1)
|
||||
mtctr r0
|
||||
lwz r4, 4(r1)
|
||||
subi r4, r4, 1
|
||||
li r3, 0
|
||||
1:
|
||||
lbzu r0, 1(r4)
|
||||
cmpli cr0, r0, 0xff
|
||||
beq 2f
|
||||
li r3, -1
|
||||
b 3f
|
||||
2:
|
||||
bdnz 1b
|
||||
3:
|
||||
|
||||
bl cache_post_ddisable
|
||||
bl cache_post_dinvalidate
|
||||
|
||||
addi r1, r1, 8
|
||||
|
||||
lwz r0, 4(r1)
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/*
|
||||
* turn on the data cache
|
||||
* switch the data cache to write-back or write-through mode
|
||||
* invalidate the data cache
|
||||
* write the zero pattern to a cached area
|
||||
* turn off the data cache
|
||||
* write the negative pattern to the area
|
||||
* turn on the data cache
|
||||
* read the area
|
||||
*
|
||||
* The negative pattern must be read at the last step
|
||||
*/
|
||||
.global cache_post_test2
|
||||
cache_post_test2:
|
||||
mflr r0
|
||||
stw r0, 4(r1)
|
||||
|
||||
stwu r3, -4(r1)
|
||||
stwu r4, -4(r1)
|
||||
|
||||
bl cache_post_dwb
|
||||
bl cache_post_dinvalidate
|
||||
|
||||
/* Write the zero pattern to the test area */
|
||||
lwz r0, 0(r1)
|
||||
mtctr r0
|
||||
li r0, 0
|
||||
lwz r3, 4(r1)
|
||||
subi r3, r3, 1
|
||||
1:
|
||||
stbu r0, 1(r3)
|
||||
bdnz 1b
|
||||
|
||||
bl cache_post_ddisable
|
||||
|
||||
/* Write the negative pattern to the test area */
|
||||
lwz r0, 0(r1)
|
||||
mtctr r0
|
||||
li r0, 0xff
|
||||
lwz r3, 4(r1)
|
||||
subi r3, r3, 1
|
||||
1:
|
||||
stbu r0, 1(r3)
|
||||
bdnz 1b
|
||||
|
||||
bl cache_post_dwb
|
||||
|
||||
/* Read the test area */
|
||||
lwz r0, 0(r1)
|
||||
mtctr r0
|
||||
lwz r4, 4(r1)
|
||||
subi r4, r4, 1
|
||||
li r3, 0
|
||||
1:
|
||||
lbzu r0, 1(r4)
|
||||
cmpli cr0, r0, 0xff
|
||||
beq 2f
|
||||
li r3, -1
|
||||
b 3f
|
||||
2:
|
||||
bdnz 1b
|
||||
3:
|
||||
|
||||
bl cache_post_ddisable
|
||||
bl cache_post_dinvalidate
|
||||
|
||||
addi r1, r1, 8
|
||||
|
||||
lwz r0, 4(r1)
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/*
|
||||
* turn on the data cache
|
||||
* switch the data cache to write-through mode
|
||||
* invalidate the data cache
|
||||
* write the zero pattern to a cached area
|
||||
* flush the data cache
|
||||
* write the negative pattern to the area
|
||||
* turn off the data cache
|
||||
* read the area
|
||||
*
|
||||
* The negative pattern must be read at the last step
|
||||
*/
|
||||
.global cache_post_test3
|
||||
cache_post_test3:
|
||||
mflr r0
|
||||
stw r0, 4(r1)
|
||||
|
||||
stwu r3, -4(r1)
|
||||
stwu r4, -4(r1)
|
||||
|
||||
bl cache_post_ddisable
|
||||
bl cache_post_dinvalidate
|
||||
|
||||
/* Write the zero pattern to the test area */
|
||||
lwz r0, 0(r1)
|
||||
mtctr r0
|
||||
li r0, 0
|
||||
lwz r3, 4(r1)
|
||||
subi r3, r3, 1
|
||||
1:
|
||||
stbu r0, 1(r3)
|
||||
bdnz 1b
|
||||
|
||||
bl cache_post_dwt
|
||||
bl cache_post_dinvalidate
|
||||
|
||||
/* Write the negative pattern to the test area */
|
||||
lwz r0, 0(r1)
|
||||
mtctr r0
|
||||
li r0, 0xff
|
||||
lwz r3, 4(r1)
|
||||
subi r3, r3, 1
|
||||
1:
|
||||
stbu r0, 1(r3)
|
||||
bdnz 1b
|
||||
|
||||
bl cache_post_ddisable
|
||||
bl cache_post_dinvalidate
|
||||
|
||||
/* Read the test area */
|
||||
lwz r0, 0(r1)
|
||||
mtctr r0
|
||||
lwz r4, 4(r1)
|
||||
subi r4, r4, 1
|
||||
li r3, 0
|
||||
1:
|
||||
lbzu r0, 1(r4)
|
||||
cmpli cr0, r0, 0xff
|
||||
beq 2f
|
||||
li r3, -1
|
||||
b 3f
|
||||
2:
|
||||
bdnz 1b
|
||||
3:
|
||||
|
||||
addi r1, r1, 8
|
||||
|
||||
lwz r0, 4(r1)
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/*
|
||||
* turn on the data cache
|
||||
* switch the data cache to write-back mode
|
||||
* invalidate the data cache
|
||||
* write the negative pattern to a cached area
|
||||
* flush the data cache
|
||||
* write the zero pattern to the area
|
||||
* invalidate the data cache
|
||||
* read the area
|
||||
*
|
||||
* The negative pattern must be read at the last step
|
||||
*/
|
||||
.global cache_post_test4
|
||||
cache_post_test4:
|
||||
mflr r0
|
||||
stw r0, 4(r1)
|
||||
|
||||
stwu r3, -4(r1)
|
||||
stwu r4, -4(r1)
|
||||
|
||||
bl cache_post_ddisable
|
||||
bl cache_post_dinvalidate
|
||||
|
||||
/* Write the negative pattern to the test area */
|
||||
lwz r0, 0(r1)
|
||||
mtctr r0
|
||||
li r0, 0xff
|
||||
lwz r3, 4(r1)
|
||||
subi r3, r3, 1
|
||||
1:
|
||||
stbu r0, 1(r3)
|
||||
bdnz 1b
|
||||
|
||||
bl cache_post_dwb
|
||||
bl cache_post_dinvalidate
|
||||
|
||||
/* Write the zero pattern to the test area */
|
||||
lwz r0, 0(r1)
|
||||
mtctr r0
|
||||
li r0, 0
|
||||
lwz r3, 4(r1)
|
||||
subi r3, r3, 1
|
||||
1:
|
||||
stbu r0, 1(r3)
|
||||
bdnz 1b
|
||||
|
||||
bl cache_post_ddisable
|
||||
bl cache_post_dinvalidate
|
||||
|
||||
/* Read the test area */
|
||||
lwz r0, 0(r1)
|
||||
mtctr r0
|
||||
lwz r4, 4(r1)
|
||||
subi r4, r4, 1
|
||||
li r3, 0
|
||||
1:
|
||||
lbzu r0, 1(r4)
|
||||
cmpli cr0, r0, 0xff
|
||||
beq 2f
|
||||
li r3, -1
|
||||
b 3f
|
||||
2:
|
||||
bdnz 1b
|
||||
3:
|
||||
|
||||
addi r1, r1, 8
|
||||
|
||||
lwz r0, 4(r1)
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
cache_post_test5_1:
|
||||
li r3, 0
|
||||
cache_post_test5_2:
|
||||
li r3, -1
|
||||
|
||||
/*
|
||||
* turn on the instruction cache
|
||||
* unlock the entire instruction cache
|
||||
* invalidate the instruction cache
|
||||
* lock a branch instruction in the instruction cache
|
||||
* replace the branch instruction with "nop"
|
||||
* jump to the branch instruction
|
||||
* check that the branch instruction was executed
|
||||
*/
|
||||
.global cache_post_test5
|
||||
cache_post_test5:
|
||||
mflr r0
|
||||
stw r0, 4(r1)
|
||||
|
||||
bl cache_post_ienable
|
||||
bl cache_post_iunlock
|
||||
bl cache_post_iinvalidate
|
||||
|
||||
/* Compute r9 = cache_post_test5_reloc */
|
||||
bl cache_post_test5_reloc
|
||||
cache_post_test5_reloc:
|
||||
mflr r9
|
||||
|
||||
/* Copy the test instruction to cache_post_test5_data */
|
||||
lis r3, (cache_post_test5_1 - cache_post_test5_reloc)@h
|
||||
ori r3, r3, (cache_post_test5_1 - cache_post_test5_reloc)@l
|
||||
add r3, r3, r9
|
||||
lis r4, (cache_post_test5_data - cache_post_test5_reloc)@h
|
||||
ori r4, r4, (cache_post_test5_data - cache_post_test5_reloc)@l
|
||||
add r4, r4, r9
|
||||
lwz r0, 0(r3)
|
||||
stw r0, 0(r4)
|
||||
|
||||
bl cache_post_iinvalidate
|
||||
|
||||
/* Lock the branch instruction */
|
||||
lis r3, (cache_post_test5_data - cache_post_test5_reloc)@h
|
||||
ori r3, r3, (cache_post_test5_data - cache_post_test5_reloc)@l
|
||||
add r3, r3, r9
|
||||
bl cache_post_ilock
|
||||
|
||||
/* Replace the test instruction */
|
||||
lis r3, (cache_post_test5_2 - cache_post_test5_reloc)@h
|
||||
ori r3, r3, (cache_post_test5_2 - cache_post_test5_reloc)@l
|
||||
add r3, r3, r9
|
||||
lis r4, (cache_post_test5_data - cache_post_test5_reloc)@h
|
||||
ori r4, r4, (cache_post_test5_data - cache_post_test5_reloc)@l
|
||||
add r4, r4, r9
|
||||
lwz r0, 0(r3)
|
||||
stw r0, 0(r4)
|
||||
|
||||
bl cache_post_iinvalidate
|
||||
|
||||
/* Execute to the test instruction */
|
||||
cache_post_test5_data:
|
||||
nop
|
||||
|
||||
bl cache_post_iunlock
|
||||
|
||||
lwz r0, 4(r1)
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
cache_post_test6_1:
|
||||
li r3, -1
|
||||
cache_post_test6_2:
|
||||
li r3, 0
|
||||
|
||||
/*
|
||||
* turn on the instruction cache
|
||||
* unlock the entire instruction cache
|
||||
* invalidate the instruction cache
|
||||
* lock a branch instruction in the instruction cache
|
||||
* replace the branch instruction with "nop"
|
||||
* jump to the branch instruction
|
||||
* check that the branch instruction was executed
|
||||
*/
|
||||
.global cache_post_test6
|
||||
cache_post_test6:
|
||||
mflr r0
|
||||
stw r0, 4(r1)
|
||||
|
||||
bl cache_post_ienable
|
||||
bl cache_post_iunlock
|
||||
bl cache_post_iinvalidate
|
||||
|
||||
/* Compute r9 = cache_post_test6_reloc */
|
||||
bl cache_post_test6_reloc
|
||||
cache_post_test6_reloc:
|
||||
mflr r9
|
||||
|
||||
/* Copy the test instruction to cache_post_test6_data */
|
||||
lis r3, (cache_post_test6_1 - cache_post_test6_reloc)@h
|
||||
ori r3, r3, (cache_post_test6_1 - cache_post_test6_reloc)@l
|
||||
add r3, r3, r9
|
||||
lis r4, (cache_post_test6_data - cache_post_test6_reloc)@h
|
||||
ori r4, r4, (cache_post_test6_data - cache_post_test6_reloc)@l
|
||||
add r4, r4, r9
|
||||
lwz r0, 0(r3)
|
||||
stw r0, 0(r4)
|
||||
|
||||
bl cache_post_iinvalidate
|
||||
|
||||
/* Replace the test instruction */
|
||||
lis r3, (cache_post_test6_2 - cache_post_test6_reloc)@h
|
||||
ori r3, r3, (cache_post_test6_2 - cache_post_test6_reloc)@l
|
||||
add r3, r3, r9
|
||||
lis r4, (cache_post_test6_data - cache_post_test6_reloc)@h
|
||||
ori r4, r4, (cache_post_test6_data - cache_post_test6_reloc)@l
|
||||
add r4, r4, r9
|
||||
lwz r0, 0(r3)
|
||||
stw r0, 0(r4)
|
||||
|
||||
bl cache_post_iinvalidate
|
||||
|
||||
/* Execute to the test instruction */
|
||||
cache_post_test6_data:
|
||||
nop
|
||||
|
||||
lwz r0, 4(r1)
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
#endif /* CONFIG_MPC823 || MPC850 || MPC855 || MPC860 */
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_CACHE */
|
||||
631
common/package/boot/uboot-ipq40xx/src/post/cpu/mpc8xx/ether.c
Normal file
631
common/package/boot/uboot-ipq40xx/src/post/cpu/mpc8xx/ether.c
Normal file
|
|
@ -0,0 +1,631 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* Ethernet test
|
||||
*
|
||||
* The Serial Communication Controllers (SCC) listed in ctlr_list array below
|
||||
* are tested in the loopback ethernet mode.
|
||||
* The controllers are configured accordingly and several packets
|
||||
* are transmitted. The configurable test parameters are:
|
||||
* MIN_PACKET_LENGTH - minimum size of packet to transmit
|
||||
* MAX_PACKET_LENGTH - maximum size of packet to transmit
|
||||
* TEST_NUM - number of tests
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_ETHER
|
||||
#if defined(CONFIG_8xx)
|
||||
#include <commproc.h>
|
||||
#elif defined(CONFIG_MPC8260)
|
||||
#include <asm/cpm_8260.h>
|
||||
#else
|
||||
#error "Apparently a bad configuration, please fix."
|
||||
#endif
|
||||
|
||||
#include <command.h>
|
||||
#include <net.h>
|
||||
#include <serial.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define MIN_PACKET_LENGTH 64
|
||||
#define MAX_PACKET_LENGTH 256
|
||||
#define TEST_NUM 1
|
||||
|
||||
#define CTLR_SCC 0
|
||||
|
||||
extern void spi_init_f (void);
|
||||
extern void spi_init_r (void);
|
||||
|
||||
/* The list of controllers to test */
|
||||
#if defined(CONFIG_MPC823)
|
||||
static int ctlr_list[][2] = { {CTLR_SCC, 1} };
|
||||
#else
|
||||
static int ctlr_list[][2] = { };
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
void (*init) (int index);
|
||||
void (*halt) (int index);
|
||||
int (*send) (int index, volatile void *packet, int length);
|
||||
int (*recv) (int index, void *packet, int length);
|
||||
} ctlr_proc[1];
|
||||
|
||||
static char *ctlr_name[1] = { "SCC" };
|
||||
|
||||
/* Ethernet Transmit and Receive Buffers */
|
||||
#define DBUF_LENGTH 1520
|
||||
|
||||
#define TX_BUF_CNT 2
|
||||
|
||||
#define TOUT_LOOP 100
|
||||
|
||||
static char txbuf[DBUF_LENGTH];
|
||||
|
||||
static uint rxIdx; /* index of the current RX buffer */
|
||||
static uint txIdx; /* index of the current TX buffer */
|
||||
|
||||
/*
|
||||
* SCC Ethernet Tx and Rx buffer descriptors allocated at the
|
||||
* immr->udata_bd address on Dual-Port RAM
|
||||
* Provide for Double Buffering
|
||||
*/
|
||||
|
||||
typedef volatile struct CommonBufferDescriptor {
|
||||
cbd_t rxbd[PKTBUFSRX]; /* Rx BD */
|
||||
cbd_t txbd[TX_BUF_CNT]; /* Tx BD */
|
||||
} RTXBD;
|
||||
|
||||
static RTXBD *rtx;
|
||||
|
||||
/*
|
||||
* SCC callbacks
|
||||
*/
|
||||
|
||||
static void scc_init (int scc_index)
|
||||
{
|
||||
uchar ea[6];
|
||||
|
||||
static int proff[] = {
|
||||
PROFF_SCC1,
|
||||
PROFF_SCC2,
|
||||
PROFF_SCC3,
|
||||
PROFF_SCC4,
|
||||
};
|
||||
static unsigned int cpm_cr[] = {
|
||||
CPM_CR_CH_SCC1,
|
||||
CPM_CR_CH_SCC2,
|
||||
CPM_CR_CH_SCC3,
|
||||
CPM_CR_CH_SCC4,
|
||||
};
|
||||
|
||||
int i;
|
||||
scc_enet_t *pram_ptr;
|
||||
|
||||
volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
|
||||
|
||||
immr->im_cpm.cp_scc[scc_index].scc_gsmrl &=
|
||||
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
|
||||
|
||||
#if defined(CONFIG_FADS)
|
||||
#if defined(CONFIG_MPC860T) || defined(CONFIG_MPC86xADS)
|
||||
/* The FADS860T and MPC86xADS don't use the MODEM_EN or DATA_VOICE signals. */
|
||||
*((uint *) BCSR4) &= ~BCSR4_ETHLOOP;
|
||||
*((uint *) BCSR4) |= BCSR4_TFPLDL | BCSR4_TPSQEL;
|
||||
*((uint *) BCSR1) &= ~BCSR1_ETHEN;
|
||||
#else
|
||||
*((uint *) BCSR4) &= ~(BCSR4_ETHLOOP | BCSR4_MODEM_EN);
|
||||
*((uint *) BCSR4) |= BCSR4_TFPLDL | BCSR4_TPSQEL | BCSR4_DATA_VOICE;
|
||||
*((uint *) BCSR1) &= ~BCSR1_ETHEN;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
pram_ptr = (scc_enet_t *) & (immr->im_cpm.cp_dparam[proff[scc_index]]);
|
||||
|
||||
rxIdx = 0;
|
||||
txIdx = 0;
|
||||
|
||||
#ifdef CONFIG_SYS_ALLOC_DPRAM
|
||||
rtx = (RTXBD *) (immr->im_cpm.cp_dpmem +
|
||||
dpram_alloc_align (sizeof (RTXBD), 8));
|
||||
#else
|
||||
rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + CPM_SCC_BASE);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
#if (defined(PA_ENET_RXD) && defined(PA_ENET_TXD))
|
||||
/* Configure port A pins for Txd and Rxd.
|
||||
*/
|
||||
immr->im_ioport.iop_papar |= (PA_ENET_RXD | PA_ENET_TXD);
|
||||
immr->im_ioport.iop_padir &= ~(PA_ENET_RXD | PA_ENET_TXD);
|
||||
immr->im_ioport.iop_paodr &= ~PA_ENET_TXD;
|
||||
#elif (defined(PB_ENET_RXD) && defined(PB_ENET_TXD))
|
||||
/* Configure port B pins for Txd and Rxd.
|
||||
*/
|
||||
immr->im_cpm.cp_pbpar |= (PB_ENET_RXD | PB_ENET_TXD);
|
||||
immr->im_cpm.cp_pbdir &= ~(PB_ENET_RXD | PB_ENET_TXD);
|
||||
immr->im_cpm.cp_pbodr &= ~PB_ENET_TXD;
|
||||
#else
|
||||
#error Configuration Error: exactly ONE of PA_ENET_[RT]XD, PB_ENET_[RT]XD must be defined
|
||||
#endif
|
||||
|
||||
#if defined(PC_ENET_LBK)
|
||||
/* Configure port C pins to disable External Loopback
|
||||
*/
|
||||
immr->im_ioport.iop_pcpar &= ~PC_ENET_LBK;
|
||||
immr->im_ioport.iop_pcdir |= PC_ENET_LBK;
|
||||
immr->im_ioport.iop_pcso &= ~PC_ENET_LBK;
|
||||
immr->im_ioport.iop_pcdat &= ~PC_ENET_LBK; /* Disable Loopback */
|
||||
#endif /* PC_ENET_LBK */
|
||||
|
||||
/* Configure port C pins to enable CLSN and RENA.
|
||||
*/
|
||||
immr->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
|
||||
immr->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
|
||||
immr->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA);
|
||||
|
||||
/* Configure port A for TCLK and RCLK.
|
||||
*/
|
||||
immr->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK);
|
||||
immr->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);
|
||||
|
||||
/*
|
||||
* Configure Serial Interface clock routing -- see section 16.7.5.3
|
||||
* First, clear all SCC bits to zero, then set the ones we want.
|
||||
*/
|
||||
|
||||
immr->im_cpm.cp_sicr &= ~SICR_ENET_MASK;
|
||||
immr->im_cpm.cp_sicr |= SICR_ENET_CLKRT;
|
||||
#else
|
||||
/*
|
||||
* SCC2 receive clock is BRG2
|
||||
* SCC2 transmit clock is BRG3
|
||||
*/
|
||||
immr->im_cpm.cp_brgc2 = 0x0001000C;
|
||||
immr->im_cpm.cp_brgc3 = 0x0001000C;
|
||||
|
||||
immr->im_cpm.cp_sicr &= ~0x00003F00;
|
||||
immr->im_cpm.cp_sicr |= 0x00000a00;
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize SDCR -- see section 16.9.23.7
|
||||
* SDMA configuration register
|
||||
*/
|
||||
immr->im_siu_conf.sc_sdcr = 0x01;
|
||||
|
||||
|
||||
/*
|
||||
* Setup SCC Ethernet Parameter RAM
|
||||
*/
|
||||
|
||||
pram_ptr->sen_genscc.scc_rfcr = 0x18; /* Normal Operation and Mot byte ordering */
|
||||
pram_ptr->sen_genscc.scc_tfcr = 0x18; /* Mot byte ordering, Normal access */
|
||||
|
||||
pram_ptr->sen_genscc.scc_mrblr = DBUF_LENGTH; /* max. ET package len 1520 */
|
||||
|
||||
pram_ptr->sen_genscc.scc_rbase = (unsigned int) (&rtx->rxbd[0]); /* Set RXBD tbl start at Dual Port */
|
||||
pram_ptr->sen_genscc.scc_tbase = (unsigned int) (&rtx->txbd[0]); /* Set TXBD tbl start at Dual Port */
|
||||
|
||||
/*
|
||||
* Setup Receiver Buffer Descriptors (13.14.24.18)
|
||||
* Settings:
|
||||
* Empty, Wrap
|
||||
*/
|
||||
|
||||
for (i = 0; i < PKTBUFSRX; i++) {
|
||||
rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
|
||||
rtx->rxbd[i].cbd_datlen = 0; /* Reset */
|
||||
rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
|
||||
}
|
||||
|
||||
rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
|
||||
|
||||
/*
|
||||
* Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
|
||||
* Settings:
|
||||
* Add PADs to Short FRAMES, Wrap, Last, Tx CRC
|
||||
*/
|
||||
|
||||
for (i = 0; i < TX_BUF_CNT; i++) {
|
||||
rtx->txbd[i].cbd_sc =
|
||||
(BD_ENET_TX_PAD | BD_ENET_TX_LAST | BD_ENET_TX_TC);
|
||||
rtx->txbd[i].cbd_datlen = 0; /* Reset */
|
||||
rtx->txbd[i].cbd_bufaddr = (uint) (&txbuf[0]);
|
||||
}
|
||||
|
||||
rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
|
||||
|
||||
/*
|
||||
* Enter Command: Initialize Rx Params for SCC
|
||||
*/
|
||||
|
||||
do { /* Spin until ready to issue command */
|
||||
__asm__ ("eieio");
|
||||
} while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
|
||||
/* Issue command */
|
||||
immr->im_cpm.cp_cpcr =
|
||||
((CPM_CR_INIT_RX << 8) | (cpm_cr[scc_index] << 4) |
|
||||
CPM_CR_FLG);
|
||||
do { /* Spin until command processed */
|
||||
__asm__ ("eieio");
|
||||
} while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
|
||||
|
||||
/*
|
||||
* Ethernet Specific Parameter RAM
|
||||
* see table 13-16, pg. 660,
|
||||
* pg. 681 (example with suggested settings)
|
||||
*/
|
||||
|
||||
pram_ptr->sen_cpres = ~(0x0); /* Preset CRC */
|
||||
pram_ptr->sen_cmask = 0xdebb20e3; /* Constant Mask for CRC */
|
||||
pram_ptr->sen_crcec = 0x0; /* Error Counter CRC (unused) */
|
||||
pram_ptr->sen_alec = 0x0; /* Alignment Error Counter (unused) */
|
||||
pram_ptr->sen_disfc = 0x0; /* Discard Frame Counter (unused) */
|
||||
pram_ptr->sen_pads = 0x8888; /* Short Frame PAD Characters */
|
||||
|
||||
pram_ptr->sen_retlim = 15; /* Retry Limit Threshold */
|
||||
pram_ptr->sen_maxflr = 1518; /* MAX Frame Length Register */
|
||||
pram_ptr->sen_minflr = 64; /* MIN Frame Length Register */
|
||||
|
||||
pram_ptr->sen_maxd1 = DBUF_LENGTH; /* MAX DMA1 Length Register */
|
||||
pram_ptr->sen_maxd2 = DBUF_LENGTH; /* MAX DMA2 Length Register */
|
||||
|
||||
pram_ptr->sen_gaddr1 = 0x0; /* Group Address Filter 1 (unused) */
|
||||
pram_ptr->sen_gaddr2 = 0x0; /* Group Address Filter 2 (unused) */
|
||||
pram_ptr->sen_gaddr3 = 0x0; /* Group Address Filter 3 (unused) */
|
||||
pram_ptr->sen_gaddr4 = 0x0; /* Group Address Filter 4 (unused) */
|
||||
|
||||
eth_getenv_enetaddr("ethaddr", ea);
|
||||
pram_ptr->sen_paddrh = (ea[5] << 8) + ea[4];
|
||||
pram_ptr->sen_paddrm = (ea[3] << 8) + ea[2];
|
||||
pram_ptr->sen_paddrl = (ea[1] << 8) + ea[0];
|
||||
|
||||
pram_ptr->sen_pper = 0x0; /* Persistence (unused) */
|
||||
pram_ptr->sen_iaddr1 = 0x0; /* Individual Address Filter 1 (unused) */
|
||||
pram_ptr->sen_iaddr2 = 0x0; /* Individual Address Filter 2 (unused) */
|
||||
pram_ptr->sen_iaddr3 = 0x0; /* Individual Address Filter 3 (unused) */
|
||||
pram_ptr->sen_iaddr4 = 0x0; /* Individual Address Filter 4 (unused) */
|
||||
pram_ptr->sen_taddrh = 0x0; /* Tmp Address (MSB) (unused) */
|
||||
pram_ptr->sen_taddrm = 0x0; /* Tmp Address (unused) */
|
||||
pram_ptr->sen_taddrl = 0x0; /* Tmp Address (LSB) (unused) */
|
||||
|
||||
/*
|
||||
* Enter Command: Initialize Tx Params for SCC
|
||||
*/
|
||||
|
||||
do { /* Spin until ready to issue command */
|
||||
__asm__ ("eieio");
|
||||
} while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
|
||||
/* Issue command */
|
||||
immr->im_cpm.cp_cpcr =
|
||||
((CPM_CR_INIT_TX << 8) | (cpm_cr[scc_index] << 4) |
|
||||
CPM_CR_FLG);
|
||||
do { /* Spin until command processed */
|
||||
__asm__ ("eieio");
|
||||
} while (immr->im_cpm.cp_cpcr & CPM_CR_FLG);
|
||||
|
||||
/*
|
||||
* Mask all Events in SCCM - we use polling mode
|
||||
*/
|
||||
immr->im_cpm.cp_scc[scc_index].scc_sccm = 0;
|
||||
|
||||
/*
|
||||
* Clear Events in SCCE -- Clear bits by writing 1's
|
||||
*/
|
||||
|
||||
immr->im_cpm.cp_scc[scc_index].scc_scce = ~(0x0);
|
||||
|
||||
|
||||
/*
|
||||
* Initialize GSMR High 32-Bits
|
||||
* Settings: Normal Mode
|
||||
*/
|
||||
|
||||
immr->im_cpm.cp_scc[scc_index].scc_gsmrh = 0;
|
||||
|
||||
/*
|
||||
* Initialize GSMR Low 32-Bits, but do not Enable Transmit/Receive
|
||||
* Settings:
|
||||
* TCI = Invert
|
||||
* TPL = 48 bits
|
||||
* TPP = Repeating 10's
|
||||
* LOOP = Loopback
|
||||
* MODE = Ethernet
|
||||
*/
|
||||
|
||||
immr->im_cpm.cp_scc[scc_index].scc_gsmrl = (SCC_GSMRL_TCI |
|
||||
SCC_GSMRL_TPL_48 |
|
||||
SCC_GSMRL_TPP_10 |
|
||||
SCC_GSMRL_DIAG_LOOP |
|
||||
SCC_GSMRL_MODE_ENET);
|
||||
|
||||
/*
|
||||
* Initialize the DSR -- see section 13.14.4 (pg. 513) v0.4
|
||||
*/
|
||||
|
||||
immr->im_cpm.cp_scc[scc_index].scc_dsr = 0xd555;
|
||||
|
||||
/*
|
||||
* Initialize the PSMR
|
||||
* Settings:
|
||||
* CRC = 32-Bit CCITT
|
||||
* NIB = Begin searching for SFD 22 bits after RENA
|
||||
* LPB = Loopback Enable (Needed when FDE is set)
|
||||
*/
|
||||
immr->im_cpm.cp_scc[scc_index].scc_psmr = SCC_PSMR_ENCRC |
|
||||
SCC_PSMR_NIB22 | SCC_PSMR_LPB;
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Configure Ethernet TENA Signal
|
||||
*/
|
||||
|
||||
#if (defined(PC_ENET_TENA) && !defined(PB_ENET_TENA))
|
||||
immr->im_ioport.iop_pcpar |= PC_ENET_TENA;
|
||||
immr->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
|
||||
#elif (defined(PB_ENET_TENA) && !defined(PC_ENET_TENA))
|
||||
immr->im_cpm.cp_pbpar |= PB_ENET_TENA;
|
||||
immr->im_cpm.cp_pbdir |= PB_ENET_TENA;
|
||||
#else
|
||||
#error Configuration Error: exactly ONE of PB_ENET_TENA, PC_ENET_TENA must be defined
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ADS) && defined(CONFIG_MPC860)
|
||||
/*
|
||||
* Port C is used to control the PHY,MC68160.
|
||||
*/
|
||||
immr->im_ioport.iop_pcdir |=
|
||||
(PC_ENET_ETHLOOP | PC_ENET_TPFLDL | PC_ENET_TPSQEL);
|
||||
|
||||
immr->im_ioport.iop_pcdat |= PC_ENET_TPFLDL;
|
||||
immr->im_ioport.iop_pcdat &= ~(PC_ENET_ETHLOOP | PC_ENET_TPSQEL);
|
||||
*((uint *) BCSR1) &= ~BCSR1_ETHEN;
|
||||
#endif /* MPC860ADS */
|
||||
|
||||
#if defined(CONFIG_AMX860)
|
||||
/*
|
||||
* Port B is used to control the PHY,MC68160.
|
||||
*/
|
||||
immr->im_cpm.cp_pbdir |=
|
||||
(PB_ENET_ETHLOOP | PB_ENET_TPFLDL | PB_ENET_TPSQEL);
|
||||
|
||||
immr->im_cpm.cp_pbdat |= PB_ENET_TPFLDL;
|
||||
immr->im_cpm.cp_pbdat &= ~(PB_ENET_ETHLOOP | PB_ENET_TPSQEL);
|
||||
|
||||
immr->im_ioport.iop_pddir |= PD_ENET_ETH_EN;
|
||||
immr->im_ioport.iop_pddat &= ~PD_ENET_ETH_EN;
|
||||
#endif /* AMX860 */
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
#ifdef CONFIG_RPXCLASSIC
|
||||
*((uchar *) BCSR0) &= ~BCSR0_ETHLPBK;
|
||||
*((uchar *) BCSR0) |= (BCSR0_ETHEN | BCSR0_COLTEST | BCSR0_FULLDPLX);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RPXLITE
|
||||
*((uchar *) BCSR0) |= BCSR0_ETHEN;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MBX
|
||||
board_ether_init ();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set the ENT/ENR bits in the GSMR Low -- Enable Transmit/Receive
|
||||
*/
|
||||
|
||||
immr->im_cpm.cp_scc[scc_index].scc_gsmrl |=
|
||||
(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
|
||||
|
||||
/*
|
||||
* Work around transmit problem with first eth packet
|
||||
*/
|
||||
#if defined (CONFIG_FADS)
|
||||
udelay (10000); /* wait 10 ms */
|
||||
#elif defined (CONFIG_AMX860) || defined(CONFIG_RPXCLASSIC)
|
||||
udelay (100000); /* wait 100 ms */
|
||||
#endif
|
||||
}
|
||||
|
||||
static void scc_halt (int scc_index)
|
||||
{
|
||||
volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
|
||||
|
||||
immr->im_cpm.cp_scc[scc_index].scc_gsmrl &=
|
||||
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
|
||||
immr->im_ioport.iop_pcso &= ~(PC_ENET_CLSN | PC_ENET_RENA);
|
||||
}
|
||||
|
||||
static int scc_send (int index, volatile void *packet, int length)
|
||||
{
|
||||
int i, j = 0;
|
||||
|
||||
while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j < TOUT_LOOP)) {
|
||||
udelay (1); /* will also trigger Wd if needed */
|
||||
j++;
|
||||
}
|
||||
if (j >= TOUT_LOOP)
|
||||
printf ("TX not ready\n");
|
||||
rtx->txbd[txIdx].cbd_bufaddr = (uint) packet;
|
||||
rtx->txbd[txIdx].cbd_datlen = length;
|
||||
rtx->txbd[txIdx].cbd_sc |=
|
||||
(BD_ENET_TX_READY | BD_ENET_TX_LAST | BD_ENET_TX_WRAP);
|
||||
while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j < TOUT_LOOP)) {
|
||||
udelay (1); /* will also trigger Wd if needed */
|
||||
j++;
|
||||
}
|
||||
if (j >= TOUT_LOOP)
|
||||
printf ("TX timeout\n");
|
||||
i = (rtx->txbd[txIdx].
|
||||
cbd_sc & BD_ENET_TX_STATS) /* return only status bits */ ;
|
||||
return i;
|
||||
}
|
||||
|
||||
static int scc_recv (int index, void *packet, int max_length)
|
||||
{
|
||||
int length = -1;
|
||||
|
||||
if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
|
||||
goto Done; /* nothing received */
|
||||
}
|
||||
|
||||
if (!(rtx->rxbd[rxIdx].cbd_sc & 0x003f)) {
|
||||
length = rtx->rxbd[rxIdx].cbd_datlen - 4;
|
||||
memcpy (packet,
|
||||
(void *) (NetRxPackets[rxIdx]),
|
||||
length < max_length ? length : max_length);
|
||||
}
|
||||
|
||||
/* Give the buffer back to the SCC. */
|
||||
rtx->rxbd[rxIdx].cbd_datlen = 0;
|
||||
|
||||
/* wrap around buffer index when necessary */
|
||||
if ((rxIdx + 1) >= PKTBUFSRX) {
|
||||
rtx->rxbd[PKTBUFSRX - 1].cbd_sc =
|
||||
(BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
|
||||
rxIdx = 0;
|
||||
} else {
|
||||
rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
|
||||
rxIdx++;
|
||||
}
|
||||
|
||||
Done:
|
||||
return length;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test routines
|
||||
*/
|
||||
|
||||
static void packet_fill (char *packet, int length)
|
||||
{
|
||||
char c = (char) length;
|
||||
int i;
|
||||
|
||||
packet[0] = 0xFF;
|
||||
packet[1] = 0xFF;
|
||||
packet[2] = 0xFF;
|
||||
packet[3] = 0xFF;
|
||||
packet[4] = 0xFF;
|
||||
packet[5] = 0xFF;
|
||||
|
||||
for (i = 6; i < length; i++) {
|
||||
packet[i] = c++;
|
||||
}
|
||||
}
|
||||
|
||||
static int packet_check (char *packet, int length)
|
||||
{
|
||||
char c = (char) length;
|
||||
int i;
|
||||
|
||||
for (i = 6; i < length; i++) {
|
||||
if (packet[i] != c++)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_ctlr (int ctlr, int index)
|
||||
{
|
||||
int res = -1;
|
||||
char packet_send[MAX_PACKET_LENGTH];
|
||||
char packet_recv[MAX_PACKET_LENGTH];
|
||||
int length;
|
||||
int i;
|
||||
int l;
|
||||
|
||||
ctlr_proc[ctlr].init (index);
|
||||
|
||||
for (i = 0; i < TEST_NUM; i++) {
|
||||
for (l = MIN_PACKET_LENGTH; l <= MAX_PACKET_LENGTH; l++) {
|
||||
packet_fill (packet_send, l);
|
||||
|
||||
ctlr_proc[ctlr].send (index, packet_send, l);
|
||||
|
||||
length = ctlr_proc[ctlr].recv (index, packet_recv,
|
||||
MAX_PACKET_LENGTH);
|
||||
|
||||
if (length != l || packet_check (packet_recv, length) < 0) {
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res = 0;
|
||||
|
||||
Done:
|
||||
|
||||
ctlr_proc[ctlr].halt (index);
|
||||
|
||||
/*
|
||||
* SCC2 Ethernet parameter RAM space overlaps
|
||||
* the SPI parameter RAM space. So we need to restore
|
||||
* the SPI configuration after SCC2 ethernet test.
|
||||
*/
|
||||
#if defined(CONFIG_SPI)
|
||||
if (ctlr == CTLR_SCC && index == 1) {
|
||||
spi_init_f ();
|
||||
spi_init_r ();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (res != 0) {
|
||||
post_log ("ethernet %s%d test failed\n", ctlr_name[ctlr],
|
||||
index + 1);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int ether_post_test (int flags)
|
||||
{
|
||||
int res = 0;
|
||||
int i;
|
||||
|
||||
ctlr_proc[CTLR_SCC].init = scc_init;
|
||||
ctlr_proc[CTLR_SCC].halt = scc_halt;
|
||||
ctlr_proc[CTLR_SCC].send = scc_send;
|
||||
ctlr_proc[CTLR_SCC].recv = scc_recv;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ctlr_list); i++) {
|
||||
if (test_ctlr (ctlr_list[i][0], ctlr_list[i][1]) != 0) {
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_8xx_CONS_NONE)
|
||||
serial_reinit_all ();
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_ETHER */
|
||||
148
common/package/boot/uboot-ipq40xx/src/post/cpu/mpc8xx/spr.c
Normal file
148
common/package/boot/uboot-ipq40xx/src/post/cpu/mpc8xx/spr.c
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* SPR test
|
||||
*
|
||||
* The test checks the contents of Special Purpose Registers (SPR) listed
|
||||
* in the spr_test_list array below.
|
||||
* Each SPR value is read using mfspr instruction, some bits are masked
|
||||
* according to the table and the resulting value is compared to the
|
||||
* corresponding table value.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_SPR
|
||||
|
||||
static struct
|
||||
{
|
||||
int number;
|
||||
char * name;
|
||||
unsigned long mask;
|
||||
unsigned long value;
|
||||
} spr_test_list [] = {
|
||||
/* Standard Special-Purpose Registers */
|
||||
|
||||
{1, "XER", 0x00000000, 0x00000000},
|
||||
{8, "LR", 0x00000000, 0x00000000},
|
||||
{9, "CTR", 0x00000000, 0x00000000},
|
||||
{18, "DSISR", 0x00000000, 0x00000000},
|
||||
{19, "DAR", 0x00000000, 0x00000000},
|
||||
{22, "DEC", 0x00000000, 0x00000000},
|
||||
{26, "SRR0", 0x00000000, 0x00000000},
|
||||
{27, "SRR1", 0x00000000, 0x00000000},
|
||||
{272, "SPRG0", 0x00000000, 0x00000000},
|
||||
{273, "SPRG1", 0x00000000, 0x00000000},
|
||||
{274, "SPRG2", 0x00000000, 0x00000000},
|
||||
{275, "SPRG3", 0x00000000, 0x00000000},
|
||||
{287, "PVR", 0xFFFF0000, 0x00500000},
|
||||
|
||||
/* Additional Special-Purpose Registers */
|
||||
|
||||
{144, "CMPA", 0x00000000, 0x00000000},
|
||||
{145, "CMPB", 0x00000000, 0x00000000},
|
||||
{146, "CMPC", 0x00000000, 0x00000000},
|
||||
{147, "CMPD", 0x00000000, 0x00000000},
|
||||
{148, "ICR", 0xFFFFFFFF, 0x00000000},
|
||||
{149, "DER", 0x00000000, 0x00000000},
|
||||
{150, "COUNTA", 0xFFFFFFFF, 0x00000000},
|
||||
{151, "COUNTB", 0xFFFFFFFF, 0x00000000},
|
||||
{152, "CMPE", 0x00000000, 0x00000000},
|
||||
{153, "CMPF", 0x00000000, 0x00000000},
|
||||
{154, "CMPG", 0x00000000, 0x00000000},
|
||||
{155, "CMPH", 0x00000000, 0x00000000},
|
||||
{156, "LCTRL1", 0xFFFFFFFF, 0x00000000},
|
||||
{157, "LCTRL2", 0xFFFFFFFF, 0x00000000},
|
||||
{158, "ICTRL", 0xFFFFFFFF, 0x00000007},
|
||||
{159, "BAR", 0x00000000, 0x00000000},
|
||||
{630, "DPDR", 0x00000000, 0x00000000},
|
||||
{631, "DPIR", 0x00000000, 0x00000000},
|
||||
{638, "IMMR", 0xFFFF0000, CONFIG_SYS_IMMR },
|
||||
{560, "IC_CST", 0x8E380000, 0x00000000},
|
||||
{561, "IC_ADR", 0x00000000, 0x00000000},
|
||||
{562, "IC_DAT", 0x00000000, 0x00000000},
|
||||
{568, "DC_CST", 0xEF380000, 0x00000000},
|
||||
{569, "DC_ADR", 0x00000000, 0x00000000},
|
||||
{570, "DC_DAT", 0x00000000, 0x00000000},
|
||||
{784, "MI_CTR", 0xFFFFFFFF, 0x00000000},
|
||||
{786, "MI_AP", 0x00000000, 0x00000000},
|
||||
{787, "MI_EPN", 0x00000000, 0x00000000},
|
||||
{789, "MI_TWC", 0xFFFFFE02, 0x00000000},
|
||||
{790, "MI_RPN", 0x00000000, 0x00000000},
|
||||
{816, "MI_DBCAM", 0x00000000, 0x00000000},
|
||||
{817, "MI_DBRAM0", 0x00000000, 0x00000000},
|
||||
{818, "MI_DBRAM1", 0x00000000, 0x00000000},
|
||||
{792, "MD_CTR", 0xFFFFFFFF, 0x04000000},
|
||||
{793, "M_CASID", 0xFFFFFFF0, 0x00000000},
|
||||
{794, "MD_AP", 0x00000000, 0x00000000},
|
||||
{795, "MD_EPN", 0x00000000, 0x00000000},
|
||||
{796, "M_TWB", 0x00000003, 0x00000000},
|
||||
{797, "MD_TWC", 0x00000003, 0x00000000},
|
||||
{798, "MD_RPN", 0x00000000, 0x00000000},
|
||||
{799, "M_TW", 0x00000000, 0x00000000},
|
||||
{824, "MD_DBCAM", 0x00000000, 0x00000000},
|
||||
{825, "MD_DBRAM0", 0x00000000, 0x00000000},
|
||||
{826, "MD_DBRAM1", 0x00000000, 0x00000000},
|
||||
};
|
||||
|
||||
static int spr_test_list_size = ARRAY_SIZE(spr_test_list);
|
||||
|
||||
int spr_post_test (int flags)
|
||||
{
|
||||
int ret = 0;
|
||||
int ic = icache_status ();
|
||||
int i;
|
||||
|
||||
unsigned long code[] = {
|
||||
0x7c6002a6, /* mfspr r3,SPR */
|
||||
0x4e800020 /* blr */
|
||||
};
|
||||
unsigned long (*get_spr) (void) = (void *) code;
|
||||
|
||||
if (ic)
|
||||
icache_disable ();
|
||||
|
||||
for (i = 0; i < spr_test_list_size; i++) {
|
||||
int num = spr_test_list[i].number;
|
||||
|
||||
/* mfspr r3,num */
|
||||
code[0] = 0x7c6002a6 | ((num & 0x1F) << 16) | ((num & 0x3E0) << 6);
|
||||
|
||||
if ((get_spr () & spr_test_list[i].mask) !=
|
||||
(spr_test_list[i].value & spr_test_list[i].mask)) {
|
||||
post_log ("The value of %s special register "
|
||||
"is incorrect: 0x%08X\n",
|
||||
spr_test_list[i].name, get_spr ());
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ic)
|
||||
icache_enable ();
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_SPR */
|
||||
554
common/package/boot/uboot-ipq40xx/src/post/cpu/mpc8xx/uart.c
Normal file
554
common/package/boot/uboot-ipq40xx/src/post/cpu/mpc8xx/uart.c
Normal file
|
|
@ -0,0 +1,554 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* UART test
|
||||
*
|
||||
* The Serial Management Controllers (SMC) and the Serial Communication
|
||||
* Controllers (SCC) listed in ctlr_list array below are tested in
|
||||
* the loopback UART mode.
|
||||
* The controllers are configured accordingly and several characters
|
||||
* are transmitted. The configurable test parameters are:
|
||||
* MIN_PACKET_LENGTH - minimum size of packet to transmit
|
||||
* MAX_PACKET_LENGTH - maximum size of packet to transmit
|
||||
* TEST_NUM - number of tests
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_UART
|
||||
#if defined(CONFIG_8xx)
|
||||
#include <commproc.h>
|
||||
#elif defined(CONFIG_MPC8260)
|
||||
#include <asm/cpm_8260.h>
|
||||
#else
|
||||
#error "Apparently a bad configuration, please fix."
|
||||
#endif
|
||||
#include <command.h>
|
||||
#include <serial.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define CTLR_SMC 0
|
||||
#define CTLR_SCC 1
|
||||
|
||||
/* The list of controllers to test */
|
||||
#if defined(CONFIG_MPC823)
|
||||
static int ctlr_list[][2] =
|
||||
{ {CTLR_SMC, 0}, {CTLR_SMC, 1}, {CTLR_SCC, 1} };
|
||||
#else
|
||||
static int ctlr_list[][2] = { };
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
void (*init) (int index);
|
||||
void (*halt) (int index);
|
||||
void (*putc) (int index, const char c);
|
||||
int (*getc) (int index);
|
||||
} ctlr_proc[2];
|
||||
|
||||
static char *ctlr_name[2] = { "SMC", "SCC" };
|
||||
|
||||
static int proff_smc[] = { PROFF_SMC1, PROFF_SMC2 };
|
||||
static int proff_scc[] =
|
||||
{ PROFF_SCC1, PROFF_SCC2, PROFF_SCC3, PROFF_SCC4 };
|
||||
|
||||
/*
|
||||
* SMC callbacks
|
||||
*/
|
||||
|
||||
static void smc_init (int smc_index)
|
||||
{
|
||||
static int cpm_cr_ch[] = { CPM_CR_CH_SMC1, CPM_CR_CH_SMC2 };
|
||||
|
||||
volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
|
||||
volatile smc_t *sp;
|
||||
volatile smc_uart_t *up;
|
||||
volatile cbd_t *tbdf, *rbdf;
|
||||
volatile cpm8xx_t *cp = &(im->im_cpm);
|
||||
uint dpaddr;
|
||||
|
||||
/* initialize pointers to SMC */
|
||||
|
||||
sp = (smc_t *) & (cp->cp_smc[smc_index]);
|
||||
up = (smc_uart_t *) & cp->cp_dparam[proff_smc[smc_index]];
|
||||
|
||||
/* Disable transmitter/receiver.
|
||||
*/
|
||||
sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
|
||||
|
||||
/* Enable SDMA.
|
||||
*/
|
||||
im->im_siu_conf.sc_sdcr = 1;
|
||||
|
||||
/* clear error conditions */
|
||||
#ifdef CONFIG_SYS_SDSR
|
||||
im->im_sdma.sdma_sdsr = CONFIG_SYS_SDSR;
|
||||
#else
|
||||
im->im_sdma.sdma_sdsr = 0x83;
|
||||
#endif
|
||||
|
||||
/* clear SDMA interrupt mask */
|
||||
#ifdef CONFIG_SYS_SDMR
|
||||
im->im_sdma.sdma_sdmr = CONFIG_SYS_SDMR;
|
||||
#else
|
||||
im->im_sdma.sdma_sdmr = 0x00;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FADS)
|
||||
/* Enable RS232 */
|
||||
*((uint *) BCSR1) &=
|
||||
~(smc_index == 1 ? BCSR1_RS232EN_1 : BCSR1_RS232EN_2);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
|
||||
/* Enable Monitor Port Transceiver */
|
||||
*((uchar *) BCSR0) |= BCSR0_ENMONXCVR;
|
||||
#endif
|
||||
|
||||
/* Set the physical address of the host memory buffers in
|
||||
* the buffer descriptors.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SYS_ALLOC_DPRAM
|
||||
dpaddr = dpram_alloc_align (sizeof (cbd_t) * 2 + 2, 8);
|
||||
#else
|
||||
dpaddr = CPM_POST_BASE;
|
||||
#endif
|
||||
|
||||
/* Allocate space for two buffer descriptors in the DP ram.
|
||||
* For now, this address seems OK, but it may have to
|
||||
* change with newer versions of the firmware.
|
||||
* damm: allocating space after the two buffers for rx/tx data
|
||||
*/
|
||||
|
||||
rbdf = (cbd_t *) & cp->cp_dpmem[dpaddr];
|
||||
rbdf->cbd_bufaddr = (uint) (rbdf + 2);
|
||||
rbdf->cbd_sc = 0;
|
||||
tbdf = rbdf + 1;
|
||||
tbdf->cbd_bufaddr = ((uint) (rbdf + 2)) + 1;
|
||||
tbdf->cbd_sc = 0;
|
||||
|
||||
/* Set up the uart parameters in the parameter ram.
|
||||
*/
|
||||
up->smc_rbase = dpaddr;
|
||||
up->smc_tbase = dpaddr + sizeof (cbd_t);
|
||||
up->smc_rfcr = SMC_EB;
|
||||
up->smc_tfcr = SMC_EB;
|
||||
|
||||
#if defined(CONFIG_MBX)
|
||||
board_serial_init ();
|
||||
#endif
|
||||
|
||||
/* Set UART mode, 8 bit, no parity, one stop.
|
||||
* Enable receive and transmit.
|
||||
* Set local loopback mode.
|
||||
*/
|
||||
sp->smc_smcmr = smcr_mk_clen (9) | SMCMR_SM_UART | (ushort) 0x0004;
|
||||
|
||||
/* Mask all interrupts and remove anything pending.
|
||||
*/
|
||||
sp->smc_smcm = 0;
|
||||
sp->smc_smce = 0xff;
|
||||
|
||||
/* Set up the baud rate generator.
|
||||
*/
|
||||
cp->cp_simode = 0x00000000;
|
||||
|
||||
cp->cp_brgc1 =
|
||||
(((gd->cpu_clk / 16 / gd->baudrate) -
|
||||
1) << 1) | CPM_BRG_EN;
|
||||
|
||||
/* Make the first buffer the only buffer.
|
||||
*/
|
||||
tbdf->cbd_sc |= BD_SC_WRAP;
|
||||
rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
|
||||
|
||||
/* Single character receive.
|
||||
*/
|
||||
up->smc_mrblr = 1;
|
||||
up->smc_maxidl = 0;
|
||||
|
||||
/* Initialize Tx/Rx parameters.
|
||||
*/
|
||||
|
||||
while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
|
||||
;
|
||||
|
||||
cp->cp_cpcr =
|
||||
mk_cr_cmd (cpm_cr_ch[smc_index], CPM_CR_INIT_TRX) | CPM_CR_FLG;
|
||||
|
||||
while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
|
||||
;
|
||||
|
||||
/* Enable transmitter/receiver.
|
||||
*/
|
||||
sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
|
||||
}
|
||||
|
||||
static void smc_halt(int smc_index)
|
||||
{
|
||||
}
|
||||
|
||||
static void smc_putc (int smc_index, const char c)
|
||||
{
|
||||
volatile cbd_t *tbdf;
|
||||
volatile char *buf;
|
||||
volatile smc_uart_t *up;
|
||||
volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
|
||||
volatile cpm8xx_t *cpmp = &(im->im_cpm);
|
||||
|
||||
up = (smc_uart_t *) & cpmp->cp_dparam[proff_smc[smc_index]];
|
||||
|
||||
tbdf = (cbd_t *) & cpmp->cp_dpmem[up->smc_tbase];
|
||||
|
||||
/* Wait for last character to go.
|
||||
*/
|
||||
|
||||
buf = (char *) tbdf->cbd_bufaddr;
|
||||
#if 0
|
||||
__asm__ ("eieio");
|
||||
while (tbdf->cbd_sc & BD_SC_READY)
|
||||
__asm__ ("eieio");
|
||||
#endif
|
||||
|
||||
*buf = c;
|
||||
tbdf->cbd_datlen = 1;
|
||||
tbdf->cbd_sc |= BD_SC_READY;
|
||||
__asm__ ("eieio");
|
||||
#if 1
|
||||
while (tbdf->cbd_sc & BD_SC_READY)
|
||||
__asm__ ("eieio");
|
||||
#endif
|
||||
}
|
||||
|
||||
static int smc_getc (int smc_index)
|
||||
{
|
||||
volatile cbd_t *rbdf;
|
||||
volatile unsigned char *buf;
|
||||
volatile smc_uart_t *up;
|
||||
volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
|
||||
volatile cpm8xx_t *cpmp = &(im->im_cpm);
|
||||
unsigned char c;
|
||||
int i;
|
||||
|
||||
up = (smc_uart_t *) & cpmp->cp_dparam[proff_smc[smc_index]];
|
||||
|
||||
rbdf = (cbd_t *) & cpmp->cp_dpmem[up->smc_rbase];
|
||||
|
||||
/* Wait for character to show up.
|
||||
*/
|
||||
buf = (unsigned char *) rbdf->cbd_bufaddr;
|
||||
#if 0
|
||||
while (rbdf->cbd_sc & BD_SC_EMPTY);
|
||||
#else
|
||||
for (i = 100; i > 0; i--) {
|
||||
if (!(rbdf->cbd_sc & BD_SC_EMPTY))
|
||||
break;
|
||||
udelay (1000);
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
return -1;
|
||||
#endif
|
||||
c = *buf;
|
||||
rbdf->cbd_sc |= BD_SC_EMPTY;
|
||||
|
||||
return (c);
|
||||
}
|
||||
|
||||
/*
|
||||
* SCC callbacks
|
||||
*/
|
||||
|
||||
static void scc_init (int scc_index)
|
||||
{
|
||||
static int cpm_cr_ch[] = {
|
||||
CPM_CR_CH_SCC1,
|
||||
CPM_CR_CH_SCC2,
|
||||
CPM_CR_CH_SCC3,
|
||||
CPM_CR_CH_SCC4,
|
||||
};
|
||||
|
||||
volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
|
||||
volatile scc_t *sp;
|
||||
volatile scc_uart_t *up;
|
||||
volatile cbd_t *tbdf, *rbdf;
|
||||
volatile cpm8xx_t *cp = &(im->im_cpm);
|
||||
uint dpaddr;
|
||||
|
||||
/* initialize pointers to SCC */
|
||||
|
||||
sp = (scc_t *) & (cp->cp_scc[scc_index]);
|
||||
up = (scc_uart_t *) & cp->cp_dparam[proff_scc[scc_index]];
|
||||
|
||||
/* Disable transmitter/receiver.
|
||||
*/
|
||||
sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
|
||||
|
||||
|
||||
/* Allocate space for two buffer descriptors in the DP ram.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SYS_ALLOC_DPRAM
|
||||
dpaddr = dpram_alloc_align (sizeof (cbd_t) * 2 + 2, 8);
|
||||
#else
|
||||
dpaddr = CPM_POST_BASE;
|
||||
#endif
|
||||
|
||||
/* Enable SDMA.
|
||||
*/
|
||||
im->im_siu_conf.sc_sdcr = 0x0001;
|
||||
|
||||
/* Set the physical address of the host memory buffers in
|
||||
* the buffer descriptors.
|
||||
*/
|
||||
|
||||
rbdf = (cbd_t *) & cp->cp_dpmem[dpaddr];
|
||||
rbdf->cbd_bufaddr = (uint) (rbdf + 2);
|
||||
rbdf->cbd_sc = 0;
|
||||
tbdf = rbdf + 1;
|
||||
tbdf->cbd_bufaddr = ((uint) (rbdf + 2)) + 1;
|
||||
tbdf->cbd_sc = 0;
|
||||
|
||||
/* Set up the baud rate generator.
|
||||
*/
|
||||
cp->cp_sicr &= ~(0x000000FF << (8 * scc_index));
|
||||
/* no |= needed, since BRG1 is 000 */
|
||||
|
||||
cp->cp_brgc1 =
|
||||
(((gd->cpu_clk / 16 / gd->baudrate) -
|
||||
1) << 1) | CPM_BRG_EN;
|
||||
|
||||
/* Set up the uart parameters in the parameter ram.
|
||||
*/
|
||||
up->scc_genscc.scc_rbase = dpaddr;
|
||||
up->scc_genscc.scc_tbase = dpaddr + sizeof (cbd_t);
|
||||
|
||||
/* Initialize Tx/Rx parameters.
|
||||
*/
|
||||
while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
|
||||
;
|
||||
cp->cp_cpcr =
|
||||
mk_cr_cmd (cpm_cr_ch[scc_index], CPM_CR_INIT_TRX) | CPM_CR_FLG;
|
||||
|
||||
while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
|
||||
;
|
||||
|
||||
up->scc_genscc.scc_rfcr = SCC_EB | 0x05;
|
||||
up->scc_genscc.scc_tfcr = SCC_EB | 0x05;
|
||||
|
||||
up->scc_genscc.scc_mrblr = 1; /* Single character receive */
|
||||
up->scc_maxidl = 0; /* disable max idle */
|
||||
up->scc_brkcr = 1; /* send one break character on stop TX */
|
||||
up->scc_parec = 0;
|
||||
up->scc_frmec = 0;
|
||||
up->scc_nosec = 0;
|
||||
up->scc_brkec = 0;
|
||||
up->scc_uaddr1 = 0;
|
||||
up->scc_uaddr2 = 0;
|
||||
up->scc_toseq = 0;
|
||||
up->scc_char1 = 0x8000;
|
||||
up->scc_char2 = 0x8000;
|
||||
up->scc_char3 = 0x8000;
|
||||
up->scc_char4 = 0x8000;
|
||||
up->scc_char5 = 0x8000;
|
||||
up->scc_char6 = 0x8000;
|
||||
up->scc_char7 = 0x8000;
|
||||
up->scc_char8 = 0x8000;
|
||||
up->scc_rccm = 0xc0ff;
|
||||
|
||||
/* Set low latency / small fifo.
|
||||
*/
|
||||
sp->scc_gsmrh = SCC_GSMRH_RFW;
|
||||
|
||||
/* Set UART mode
|
||||
*/
|
||||
sp->scc_gsmrl &= ~0xF;
|
||||
sp->scc_gsmrl |= SCC_GSMRL_MODE_UART;
|
||||
|
||||
/* Set local loopback mode.
|
||||
*/
|
||||
sp->scc_gsmrl &= ~SCC_GSMRL_DIAG_LE;
|
||||
sp->scc_gsmrl |= SCC_GSMRL_DIAG_LOOP;
|
||||
|
||||
/* Set clock divider 16 on Tx and Rx
|
||||
*/
|
||||
sp->scc_gsmrl |= (SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
|
||||
|
||||
sp->scc_psmr |= SCU_PSMR_CL;
|
||||
|
||||
/* Mask all interrupts and remove anything pending.
|
||||
*/
|
||||
sp->scc_sccm = 0;
|
||||
sp->scc_scce = 0xffff;
|
||||
sp->scc_dsr = 0x7e7e;
|
||||
sp->scc_psmr = 0x3000;
|
||||
|
||||
/* Make the first buffer the only buffer.
|
||||
*/
|
||||
tbdf->cbd_sc |= BD_SC_WRAP;
|
||||
rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
|
||||
|
||||
/* Enable transmitter/receiver.
|
||||
*/
|
||||
sp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
|
||||
}
|
||||
|
||||
static void scc_halt(int scc_index)
|
||||
{
|
||||
volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
|
||||
volatile cpm8xx_t *cp = &(im->im_cpm);
|
||||
volatile scc_t *sp = (scc_t *) & (cp->cp_scc[scc_index]);
|
||||
|
||||
sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT | SCC_GSMRL_DIAG_LE);
|
||||
}
|
||||
|
||||
static void scc_putc (int scc_index, const char c)
|
||||
{
|
||||
volatile cbd_t *tbdf;
|
||||
volatile char *buf;
|
||||
volatile scc_uart_t *up;
|
||||
volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
|
||||
volatile cpm8xx_t *cpmp = &(im->im_cpm);
|
||||
|
||||
up = (scc_uart_t *) & cpmp->cp_dparam[proff_scc[scc_index]];
|
||||
|
||||
tbdf = (cbd_t *) & cpmp->cp_dpmem[up->scc_genscc.scc_tbase];
|
||||
|
||||
/* Wait for last character to go.
|
||||
*/
|
||||
|
||||
buf = (char *) tbdf->cbd_bufaddr;
|
||||
#if 0
|
||||
__asm__ ("eieio");
|
||||
while (tbdf->cbd_sc & BD_SC_READY)
|
||||
__asm__ ("eieio");
|
||||
#endif
|
||||
|
||||
*buf = c;
|
||||
tbdf->cbd_datlen = 1;
|
||||
tbdf->cbd_sc |= BD_SC_READY;
|
||||
__asm__ ("eieio");
|
||||
#if 1
|
||||
while (tbdf->cbd_sc & BD_SC_READY)
|
||||
__asm__ ("eieio");
|
||||
#endif
|
||||
}
|
||||
|
||||
static int scc_getc (int scc_index)
|
||||
{
|
||||
volatile cbd_t *rbdf;
|
||||
volatile unsigned char *buf;
|
||||
volatile scc_uart_t *up;
|
||||
volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
|
||||
volatile cpm8xx_t *cpmp = &(im->im_cpm);
|
||||
unsigned char c;
|
||||
int i;
|
||||
|
||||
up = (scc_uart_t *) & cpmp->cp_dparam[proff_scc[scc_index]];
|
||||
|
||||
rbdf = (cbd_t *) & cpmp->cp_dpmem[up->scc_genscc.scc_rbase];
|
||||
|
||||
/* Wait for character to show up.
|
||||
*/
|
||||
buf = (unsigned char *) rbdf->cbd_bufaddr;
|
||||
#if 0
|
||||
while (rbdf->cbd_sc & BD_SC_EMPTY);
|
||||
#else
|
||||
for (i = 100; i > 0; i--) {
|
||||
if (!(rbdf->cbd_sc & BD_SC_EMPTY))
|
||||
break;
|
||||
udelay (1000);
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
return -1;
|
||||
#endif
|
||||
c = *buf;
|
||||
rbdf->cbd_sc |= BD_SC_EMPTY;
|
||||
|
||||
return (c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test routines
|
||||
*/
|
||||
|
||||
static int test_ctlr (int ctlr, int index)
|
||||
{
|
||||
int res = -1;
|
||||
char test_str[] = "*** UART Test String ***\r\n";
|
||||
int i;
|
||||
|
||||
ctlr_proc[ctlr].init (index);
|
||||
|
||||
for (i = 0; i < sizeof (test_str) - 1; i++) {
|
||||
ctlr_proc[ctlr].putc (index, test_str[i]);
|
||||
if (ctlr_proc[ctlr].getc (index) != test_str[i])
|
||||
goto Done;
|
||||
}
|
||||
|
||||
res = 0;
|
||||
|
||||
Done:
|
||||
ctlr_proc[ctlr].halt (index);
|
||||
|
||||
if (res != 0) {
|
||||
post_log ("uart %s%d test failed\n",
|
||||
ctlr_name[ctlr], index + 1);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int uart_post_test (int flags)
|
||||
{
|
||||
int res = 0;
|
||||
int i;
|
||||
|
||||
ctlr_proc[CTLR_SMC].init = smc_init;
|
||||
ctlr_proc[CTLR_SMC].halt = smc_halt;
|
||||
ctlr_proc[CTLR_SMC].putc = smc_putc;
|
||||
ctlr_proc[CTLR_SMC].getc = smc_getc;
|
||||
|
||||
ctlr_proc[CTLR_SCC].init = scc_init;
|
||||
ctlr_proc[CTLR_SCC].halt = scc_halt;
|
||||
ctlr_proc[CTLR_SCC].putc = scc_putc;
|
||||
ctlr_proc[CTLR_SCC].getc = scc_getc;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ctlr_list); i++) {
|
||||
if (test_ctlr (ctlr_list[i][0], ctlr_list[i][1]) != 0) {
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_8xx_CONS_NONE)
|
||||
serial_reinit_all ();
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_UART */
|
||||
265
common/package/boot/uboot-ipq40xx/src/post/cpu/mpc8xx/usb.c
Normal file
265
common/package/boot/uboot-ipq40xx/src/post/cpu/mpc8xx/usb.c
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* USB test
|
||||
*
|
||||
* The USB controller is tested in the local loopback mode.
|
||||
* It is configured so that endpoint 0 operates as host and endpoint 1
|
||||
* operates as function endpoint. After that an IN token transaction
|
||||
* is performed.
|
||||
* Refer to MPC850 User Manual, Section 32.11.1 USB Host Controller
|
||||
* Initialization Example.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_USB
|
||||
|
||||
#include <commproc.h>
|
||||
#include <command.h>
|
||||
|
||||
#define TOUT_LOOP 100
|
||||
|
||||
#define PROFF_USB ((uint)0x0000)
|
||||
|
||||
#define CPM_USB_EP0_BASE 0x0a00
|
||||
#define CPM_USB_EP1_BASE 0x0a20
|
||||
|
||||
#define CPM_USB_DT0_BASE 0x0a80
|
||||
#define CPM_USB_DT1_BASE 0x0a90
|
||||
#define CPM_USB_DR0_BASE 0x0aa0
|
||||
#define CPM_USB_DR1_BASE 0x0ab0
|
||||
|
||||
#define CPM_USB_RX0_BASE 0x0b00
|
||||
#define CPM_USB_RX1_BASE 0x0b08
|
||||
#define CPM_USB_TX0_BASE 0x0b20
|
||||
#define CPM_USB_TX1_BASE 0x0b28
|
||||
|
||||
#define USB_EXPECT(x) if (!(x)) goto Done;
|
||||
|
||||
typedef struct usb_param {
|
||||
ushort ep0ptr;
|
||||
ushort ep1ptr;
|
||||
ushort ep2ptr;
|
||||
ushort ep3ptr;
|
||||
uint rstate;
|
||||
uint rptr;
|
||||
ushort frame_n;
|
||||
ushort rbcnt;
|
||||
ushort rtemp;
|
||||
} usb_param_t;
|
||||
|
||||
typedef struct usb_param_block {
|
||||
ushort rbase;
|
||||
ushort tbase;
|
||||
uchar rfcr;
|
||||
uchar tfcr;
|
||||
ushort mrblr;
|
||||
ushort rbptr;
|
||||
ushort tbptr;
|
||||
uint tstate;
|
||||
uint tptr;
|
||||
ushort tcrc;
|
||||
ushort tbcnt;
|
||||
uint res[2];
|
||||
} usb_param_block_t;
|
||||
|
||||
typedef struct usb {
|
||||
uchar usmod;
|
||||
uchar usadr;
|
||||
uchar uscom;
|
||||
uchar res1;
|
||||
ushort usep[4];
|
||||
uchar res2[4];
|
||||
ushort usber;
|
||||
uchar res3[2];
|
||||
ushort usbmr;
|
||||
uchar res4;
|
||||
uchar usbs;
|
||||
uchar res5[8];
|
||||
} usb_t;
|
||||
|
||||
int usb_post_test (int flags)
|
||||
{
|
||||
int res = -1;
|
||||
volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
|
||||
volatile cpm8xx_t *cp = &(im->im_cpm);
|
||||
volatile usb_param_t *pram_ptr;
|
||||
uint dpram;
|
||||
ushort DPRAM;
|
||||
volatile cbd_t *tx;
|
||||
volatile cbd_t *rx;
|
||||
volatile usb_t *usbr;
|
||||
volatile usb_param_block_t *ep0;
|
||||
volatile usb_param_block_t *ep1;
|
||||
int j;
|
||||
|
||||
pram_ptr = (usb_param_t *) & (im->im_cpm.cp_dparam[PROFF_USB]);
|
||||
dpram = (uint) im->im_cpm.cp_dpmem;
|
||||
DPRAM = dpram;
|
||||
tx = (cbd_t *) (dpram + CPM_USB_TX0_BASE);
|
||||
rx = (cbd_t *) (dpram + CPM_USB_RX0_BASE);
|
||||
ep0 = (usb_param_block_t *) (dpram + CPM_USB_EP0_BASE);
|
||||
ep1 = (usb_param_block_t *) (dpram + CPM_USB_EP1_BASE);
|
||||
usbr = (usb_t *) & (im->im_cpm.cp_scc[0]);
|
||||
|
||||
/* 01 */
|
||||
im->im_ioport.iop_padir &= ~(ushort) 0x0200;
|
||||
im->im_ioport.iop_papar |= (ushort) 0x0200;
|
||||
|
||||
cp->cp_sicr &= ~0x000000FF;
|
||||
cp->cp_sicr |= 0x00000018;
|
||||
|
||||
cp->cp_brgc4 = 0x00010001;
|
||||
|
||||
/* 02 */
|
||||
im->im_ioport.iop_padir &= ~(ushort) 0x0002;
|
||||
im->im_ioport.iop_padir &= ~(ushort) 0x0001;
|
||||
|
||||
im->im_ioport.iop_papar |= (ushort) 0x0002;
|
||||
im->im_ioport.iop_papar |= (ushort) 0x0001;
|
||||
|
||||
/* 03 */
|
||||
im->im_ioport.iop_pcdir &= ~(ushort) 0x0020;
|
||||
im->im_ioport.iop_pcdir &= ~(ushort) 0x0010;
|
||||
|
||||
im->im_ioport.iop_pcpar &= ~(ushort) 0x0020;
|
||||
im->im_ioport.iop_pcpar &= ~(ushort) 0x0010;
|
||||
|
||||
im->im_ioport.iop_pcso |= (ushort) 0x0020;
|
||||
im->im_ioport.iop_pcso |= (ushort) 0x0010;
|
||||
|
||||
/* 04 */
|
||||
im->im_ioport.iop_pcdir |= (ushort) 0x0200;
|
||||
im->im_ioport.iop_pcdir |= (ushort) 0x0100;
|
||||
|
||||
im->im_ioport.iop_pcpar |= (ushort) 0x0200;
|
||||
im->im_ioport.iop_pcpar |= (ushort) 0x0100;
|
||||
|
||||
/* 05 */
|
||||
pram_ptr->frame_n = 0;
|
||||
|
||||
/* 06 */
|
||||
pram_ptr->ep0ptr = DPRAM + CPM_USB_EP0_BASE;
|
||||
pram_ptr->ep1ptr = DPRAM + CPM_USB_EP1_BASE;
|
||||
|
||||
/* 07-10 */
|
||||
tx[0].cbd_sc = 0xB800;
|
||||
tx[0].cbd_datlen = 3;
|
||||
tx[0].cbd_bufaddr = dpram + CPM_USB_DT0_BASE;
|
||||
|
||||
tx[1].cbd_sc = 0xBC80;
|
||||
tx[1].cbd_datlen = 3;
|
||||
tx[1].cbd_bufaddr = dpram + CPM_USB_DT1_BASE;
|
||||
|
||||
rx[0].cbd_sc = 0xA000;
|
||||
rx[0].cbd_datlen = 0;
|
||||
rx[0].cbd_bufaddr = dpram + CPM_USB_DR0_BASE;
|
||||
|
||||
rx[1].cbd_sc = 0xA000;
|
||||
rx[1].cbd_datlen = 0;
|
||||
rx[1].cbd_bufaddr = dpram + CPM_USB_DR1_BASE;
|
||||
|
||||
/* 11-12 */
|
||||
*(volatile int *) (dpram + CPM_USB_DT0_BASE) = 0x69856000;
|
||||
*(volatile int *) (dpram + CPM_USB_DT1_BASE) = 0xABCD1234;
|
||||
|
||||
*(volatile int *) (dpram + CPM_USB_DR0_BASE) = 0;
|
||||
*(volatile int *) (dpram + CPM_USB_DR1_BASE) = 0;
|
||||
|
||||
/* 13-16 */
|
||||
ep0->rbase = DPRAM + CPM_USB_RX0_BASE;
|
||||
ep0->tbase = DPRAM + CPM_USB_TX0_BASE;
|
||||
ep0->rfcr = 0x18;
|
||||
ep0->tfcr = 0x18;
|
||||
ep0->mrblr = 0x100;
|
||||
ep0->rbptr = DPRAM + CPM_USB_RX0_BASE;
|
||||
ep0->tbptr = DPRAM + CPM_USB_TX0_BASE;
|
||||
ep0->tstate = 0;
|
||||
|
||||
/* 17-20 */
|
||||
ep1->rbase = DPRAM + CPM_USB_RX1_BASE;
|
||||
ep1->tbase = DPRAM + CPM_USB_TX1_BASE;
|
||||
ep1->rfcr = 0x18;
|
||||
ep1->tfcr = 0x18;
|
||||
ep1->mrblr = 0x100;
|
||||
ep1->rbptr = DPRAM + CPM_USB_RX1_BASE;
|
||||
ep1->tbptr = DPRAM + CPM_USB_TX1_BASE;
|
||||
ep1->tstate = 0;
|
||||
|
||||
/* 21-24 */
|
||||
usbr->usep[0] = 0x0000;
|
||||
usbr->usep[1] = 0x1100;
|
||||
usbr->usep[2] = 0x2200;
|
||||
usbr->usep[3] = 0x3300;
|
||||
|
||||
/* 25 */
|
||||
usbr->usmod = 0x06;
|
||||
|
||||
/* 26 */
|
||||
usbr->usadr = 0x05;
|
||||
|
||||
/* 27 */
|
||||
usbr->uscom = 0;
|
||||
|
||||
/* 28 */
|
||||
usbr->usmod |= 0x01;
|
||||
udelay (1);
|
||||
|
||||
/* 29-30 */
|
||||
usbr->uscom = 0x80;
|
||||
usbr->uscom = 0x81;
|
||||
|
||||
/* Wait for the data packet to be transmitted */
|
||||
for (j = 0; j < TOUT_LOOP; j++) {
|
||||
if (tx[1].cbd_sc & (ushort) 0x8000)
|
||||
udelay (1);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
USB_EXPECT (j < TOUT_LOOP);
|
||||
|
||||
USB_EXPECT (tx[0].cbd_sc == 0x3800);
|
||||
USB_EXPECT (tx[0].cbd_datlen == 3);
|
||||
|
||||
USB_EXPECT (tx[1].cbd_sc == 0x3C80);
|
||||
USB_EXPECT (tx[1].cbd_datlen == 3);
|
||||
|
||||
USB_EXPECT (rx[0].cbd_sc == 0x2C00);
|
||||
USB_EXPECT (rx[0].cbd_datlen == 5);
|
||||
|
||||
USB_EXPECT (*(volatile int *) (dpram + CPM_USB_DR0_BASE) ==
|
||||
0xABCD122B);
|
||||
USB_EXPECT (*(volatile char *) (dpram + CPM_USB_DR0_BASE + 4) == 0x42);
|
||||
|
||||
res = 0;
|
||||
Done:
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_USB */
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* Watchdog test
|
||||
*
|
||||
* The test verifies the watchdog timer operation.
|
||||
* On the first iteration, the test routine disables interrupts and
|
||||
* makes a 10-second delay. If the system does not reboot during this delay,
|
||||
* the watchdog timer is not operational and the test fails. If the system
|
||||
* reboots, on the second iteration the test routine reports a success.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include <watchdog.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_WATCHDOG
|
||||
|
||||
static ulong gettbl (void)
|
||||
{
|
||||
ulong r;
|
||||
|
||||
asm ("mftbl %0":"=r" (r));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int watchdog_post_test (int flags)
|
||||
{
|
||||
if (flags & POST_REBOOT) {
|
||||
/* Test passed */
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
/* 10-second delay */
|
||||
int ints = disable_interrupts ();
|
||||
ulong base = gettbl ();
|
||||
ulong clk = get_tbclk ();
|
||||
|
||||
while ((gettbl () - base) / 10 < clk);
|
||||
|
||||
if (ints)
|
||||
enable_interrupts ();
|
||||
|
||||
/*
|
||||
* If we have reached this point, the watchdog timer
|
||||
* does not work
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_WATCHDOG */
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#
|
||||
# (C) Copyright 2002-2007
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
include $(OBJTREE)/include/autoconf.mk
|
||||
|
||||
LIB = libpostppc4xx.o
|
||||
|
||||
AOBJS-$(CONFIG_HAS_POST) += cache_4xx.o
|
||||
COBJS-$(CONFIG_HAS_POST) += cache.o
|
||||
COBJS-$(CONFIG_HAS_POST) += denali_ecc.o
|
||||
COBJS-$(CONFIG_HAS_POST) += ether.o
|
||||
COBJS-$(CONFIG_HAS_POST) += fpu.o
|
||||
COBJS-$(CONFIG_HAS_POST) += ocm.o
|
||||
COBJS-$(CONFIG_HAS_POST) += spr.o
|
||||
COBJS-$(CONFIG_HAS_POST) += uart.o
|
||||
COBJS-$(CONFIG_HAS_POST) += watchdog.o
|
||||
|
||||
include $(TOPDIR)/post/rules.mk
|
||||
122
common/package/boot/uboot-ipq40xx/src/post/cpu/ppc4xx/cache.c
Normal file
122
common/package/boot/uboot-ipq40xx/src/post/cpu/ppc4xx/cache.c
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* Author: Igor Lisitsin <igor@emcraft.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/* Cache test
|
||||
*
|
||||
* This test verifies the CPU data and instruction cache using
|
||||
* several test scenarios.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CACHE
|
||||
|
||||
#include <asm/mmu.h>
|
||||
#include <watchdog.h>
|
||||
|
||||
#define CACHE_POST_SIZE 1024
|
||||
|
||||
int cache_post_test1 (int tlb, void *p, int size);
|
||||
int cache_post_test2 (int tlb, void *p, int size);
|
||||
int cache_post_test3 (int tlb, void *p, int size);
|
||||
int cache_post_test4 (int tlb, void *p, int size);
|
||||
int cache_post_test5 (int tlb, void *p, int size);
|
||||
int cache_post_test6 (int tlb, void *p, int size);
|
||||
|
||||
#ifdef CONFIG_440
|
||||
static unsigned char testarea[CACHE_POST_SIZE]
|
||||
__attribute__((__aligned__(CACHE_POST_SIZE)));
|
||||
#endif
|
||||
|
||||
int cache_post_test (int flags)
|
||||
{
|
||||
void *virt = (void *)CONFIG_SYS_POST_CACHE_ADDR;
|
||||
int ints;
|
||||
int res = 0;
|
||||
int tlb = -1; /* index to the victim TLB entry */
|
||||
|
||||
/*
|
||||
* All 44x variants deal with cache management differently
|
||||
* because they have the address translation always enabled.
|
||||
* The 40x ppc's don't use address translation in U-Boot at all,
|
||||
* so we have to distinguish here between 40x and 44x.
|
||||
*/
|
||||
#ifdef CONFIG_440
|
||||
int word0, i;
|
||||
|
||||
/*
|
||||
* Allocate a new TLB entry, since we are going to modify
|
||||
* the write-through and caching inhibited storage attributes.
|
||||
*/
|
||||
program_tlb((u32)testarea, (u32)virt, CACHE_POST_SIZE,
|
||||
TLB_WORD2_I_ENABLE);
|
||||
|
||||
/* Find the TLB entry */
|
||||
for (i = 0;; i++) {
|
||||
if (i >= PPC4XX_TLB_SIZE) {
|
||||
printf ("Failed to program tlb entry\n");
|
||||
return -1;
|
||||
}
|
||||
word0 = mftlb1(i);
|
||||
if (TLB_WORD0_EPN_DECODE(word0) == (u32)virt) {
|
||||
tlb = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ints = disable_interrupts ();
|
||||
|
||||
WATCHDOG_RESET ();
|
||||
if (res == 0)
|
||||
res = cache_post_test1 (tlb, virt, CACHE_POST_SIZE);
|
||||
WATCHDOG_RESET ();
|
||||
if (res == 0)
|
||||
res = cache_post_test2 (tlb, virt, CACHE_POST_SIZE);
|
||||
WATCHDOG_RESET ();
|
||||
if (res == 0)
|
||||
res = cache_post_test3 (tlb, virt, CACHE_POST_SIZE);
|
||||
WATCHDOG_RESET ();
|
||||
if (res == 0)
|
||||
res = cache_post_test4 (tlb, virt, CACHE_POST_SIZE);
|
||||
WATCHDOG_RESET ();
|
||||
if (res == 0)
|
||||
res = cache_post_test5 (tlb, virt, CACHE_POST_SIZE);
|
||||
WATCHDOG_RESET ();
|
||||
if (res == 0)
|
||||
res = cache_post_test6 (tlb, virt, CACHE_POST_SIZE);
|
||||
|
||||
if (ints)
|
||||
enable_interrupts ();
|
||||
|
||||
#ifdef CONFIG_440
|
||||
remove_tlb((u32)virt, CACHE_POST_SIZE);
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_CACHE */
|
||||
|
|
@ -0,0 +1,489 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* Author: Igor Lisitsin <igor@emcraft.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <post.h>
|
||||
#include <ppc_asm.tmpl>
|
||||
#include <ppc_defs.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/mmu.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CACHE
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
* All 44x variants deal with cache management differently
|
||||
* because they have the address translation always enabled.
|
||||
* The 40x ppc's don't use address translation in U-Boot at all,
|
||||
* so we have to distinguish here between 40x and 44x.
|
||||
*/
|
||||
#ifdef CONFIG_440
|
||||
/* void cache_post_disable (int tlb)
|
||||
*/
|
||||
cache_post_disable:
|
||||
tlbre r0, r3, 0x0002
|
||||
ori r0, r0, TLB_WORD2_I_ENABLE@l
|
||||
tlbwe r0, r3, 0x0002
|
||||
sync
|
||||
isync
|
||||
blr
|
||||
|
||||
/* void cache_post_wt (int tlb)
|
||||
*/
|
||||
cache_post_wt:
|
||||
tlbre r0, r3, 0x0002
|
||||
ori r0, r0, TLB_WORD2_W_ENABLE@l
|
||||
andi. r0, r0, ~TLB_WORD2_I_ENABLE@l
|
||||
tlbwe r0, r3, 0x0002
|
||||
sync
|
||||
isync
|
||||
blr
|
||||
|
||||
/* void cache_post_wb (int tlb)
|
||||
*/
|
||||
cache_post_wb:
|
||||
tlbre r0, r3, 0x0002
|
||||
andi. r0, r0, ~TLB_WORD2_W_ENABLE@l
|
||||
andi. r0, r0, ~TLB_WORD2_I_ENABLE@l
|
||||
tlbwe r0, r3, 0x0002
|
||||
sync
|
||||
isync
|
||||
blr
|
||||
#else
|
||||
/* void cache_post_disable (int tlb)
|
||||
*/
|
||||
cache_post_disable:
|
||||
lis r0, 0x0000
|
||||
ori r0, r0, 0x0000
|
||||
mtdccr r0
|
||||
sync
|
||||
isync
|
||||
blr
|
||||
|
||||
/* void cache_post_wt (int tlb)
|
||||
*/
|
||||
cache_post_wt:
|
||||
lis r0, 0x8000
|
||||
ori r0, r0, 0x0000
|
||||
mtdccr r0
|
||||
lis r0, 0x8000
|
||||
ori r0, r0, 0x0000
|
||||
mtdcwr r0
|
||||
sync
|
||||
isync
|
||||
blr
|
||||
|
||||
/* void cache_post_wb (int tlb)
|
||||
*/
|
||||
cache_post_wb:
|
||||
lis r0, 0x8000
|
||||
ori r0, r0, 0x0000
|
||||
mtdccr r0
|
||||
lis r0, 0x0000
|
||||
ori r0, r0, 0x0000
|
||||
mtdcwr r0
|
||||
sync
|
||||
isync
|
||||
blr
|
||||
#endif
|
||||
|
||||
/* void cache_post_dinvalidate (void *p, int size)
|
||||
*/
|
||||
cache_post_dinvalidate:
|
||||
dcbi r0, r3
|
||||
addi r3, r3, CONFIG_SYS_CACHELINE_SIZE
|
||||
subic. r4, r4, CONFIG_SYS_CACHELINE_SIZE
|
||||
bgt cache_post_dinvalidate
|
||||
sync
|
||||
blr
|
||||
|
||||
/* void cache_post_dstore (void *p, int size)
|
||||
*/
|
||||
cache_post_dstore:
|
||||
dcbst r0, r3
|
||||
addi r3, r3, CONFIG_SYS_CACHELINE_SIZE
|
||||
subic. r4, r4, CONFIG_SYS_CACHELINE_SIZE
|
||||
bgt cache_post_dstore
|
||||
sync
|
||||
blr
|
||||
|
||||
/* void cache_post_dtouch (void *p, int size)
|
||||
*/
|
||||
cache_post_dtouch:
|
||||
dcbt r0, r3
|
||||
addi r3, r3, CONFIG_SYS_CACHELINE_SIZE
|
||||
subic. r4, r4, CONFIG_SYS_CACHELINE_SIZE
|
||||
bgt cache_post_dtouch
|
||||
sync
|
||||
blr
|
||||
|
||||
/* void cache_post_iinvalidate (void)
|
||||
*/
|
||||
cache_post_iinvalidate:
|
||||
iccci r0, r0
|
||||
sync
|
||||
blr
|
||||
|
||||
/* void cache_post_memset (void *p, int val, int size)
|
||||
*/
|
||||
cache_post_memset:
|
||||
mtctr r5
|
||||
1:
|
||||
stb r4, 0(r3)
|
||||
addi r3, r3, 1
|
||||
bdnz 1b
|
||||
blr
|
||||
|
||||
/* int cache_post_check (void *p, int size)
|
||||
*/
|
||||
cache_post_check:
|
||||
mtctr r4
|
||||
1:
|
||||
lbz r0, 0(r3)
|
||||
addi r3, r3, 1
|
||||
cmpwi r0, 0xff
|
||||
bne 2f
|
||||
bdnz 1b
|
||||
li r3, 0
|
||||
blr
|
||||
2:
|
||||
li r3, -1
|
||||
blr
|
||||
|
||||
#define CACHE_POST_DISABLE() \
|
||||
mr r3, r10; \
|
||||
bl cache_post_disable
|
||||
|
||||
#define CACHE_POST_WT() \
|
||||
mr r3, r10; \
|
||||
bl cache_post_wt
|
||||
|
||||
#define CACHE_POST_WB() \
|
||||
mr r3, r10; \
|
||||
bl cache_post_wb
|
||||
|
||||
#define CACHE_POST_DINVALIDATE() \
|
||||
mr r3, r11; \
|
||||
mr r4, r12; \
|
||||
bl cache_post_dinvalidate
|
||||
|
||||
#define CACHE_POST_DFLUSH() \
|
||||
mr r3, r11; \
|
||||
mr r4, r12; \
|
||||
bl cache_post_dflush
|
||||
|
||||
#define CACHE_POST_DSTORE() \
|
||||
mr r3, r11; \
|
||||
mr r4, r12; \
|
||||
bl cache_post_dstore
|
||||
|
||||
#define CACHE_POST_DTOUCH() \
|
||||
mr r3, r11; \
|
||||
mr r4, r12; \
|
||||
bl cache_post_dtouch
|
||||
|
||||
#define CACHE_POST_IINVALIDATE() \
|
||||
bl cache_post_iinvalidate
|
||||
|
||||
#define CACHE_POST_MEMSET(val) \
|
||||
mr r3, r11; \
|
||||
li r4, val; \
|
||||
mr r5, r12; \
|
||||
bl cache_post_memset
|
||||
|
||||
#define CACHE_POST_CHECK() \
|
||||
mr r3, r11; \
|
||||
mr r4, r12; \
|
||||
bl cache_post_check; \
|
||||
mr r13, r3
|
||||
|
||||
/*
|
||||
* Write and read 0xff pattern with caching enabled.
|
||||
*/
|
||||
.global cache_post_test1
|
||||
cache_post_test1:
|
||||
mflr r9
|
||||
mr r10, r3 /* tlb */
|
||||
mr r11, r4 /* p */
|
||||
mr r12, r5 /* size */
|
||||
|
||||
CACHE_POST_WB()
|
||||
CACHE_POST_DINVALIDATE()
|
||||
|
||||
/* Write the negative pattern to the test area */
|
||||
CACHE_POST_MEMSET(0xff)
|
||||
|
||||
/* Read the test area */
|
||||
CACHE_POST_CHECK()
|
||||
|
||||
CACHE_POST_DINVALIDATE()
|
||||
CACHE_POST_DISABLE()
|
||||
|
||||
mr r3, r13
|
||||
mtlr r9
|
||||
blr
|
||||
|
||||
/*
|
||||
* Write zeroes with caching enabled.
|
||||
* Write 0xff pattern with caching disabled.
|
||||
* Read 0xff pattern with caching enabled.
|
||||
*/
|
||||
.global cache_post_test2
|
||||
cache_post_test2:
|
||||
mflr r9
|
||||
mr r10, r3 /* tlb */
|
||||
mr r11, r4 /* p */
|
||||
mr r12, r5 /* size */
|
||||
|
||||
CACHE_POST_WB()
|
||||
CACHE_POST_DINVALIDATE()
|
||||
|
||||
/* Write the zero pattern to the test area */
|
||||
CACHE_POST_MEMSET(0)
|
||||
|
||||
CACHE_POST_DINVALIDATE()
|
||||
CACHE_POST_DISABLE()
|
||||
|
||||
/* Write the negative pattern to the test area */
|
||||
CACHE_POST_MEMSET(0xff)
|
||||
|
||||
CACHE_POST_WB()
|
||||
|
||||
/* Read the test area */
|
||||
CACHE_POST_CHECK()
|
||||
|
||||
CACHE_POST_DINVALIDATE()
|
||||
CACHE_POST_DISABLE()
|
||||
|
||||
mr r3, r13
|
||||
mtlr r9
|
||||
blr
|
||||
|
||||
/*
|
||||
* Write-through mode test.
|
||||
* Write zeroes, store the cache, write 0xff pattern.
|
||||
* Invalidate the cache.
|
||||
* Check that 0xff pattern is read.
|
||||
*/
|
||||
.global cache_post_test3
|
||||
cache_post_test3:
|
||||
mflr r9
|
||||
mr r10, r3 /* tlb */
|
||||
mr r11, r4 /* p */
|
||||
mr r12, r5 /* size */
|
||||
|
||||
CACHE_POST_WT()
|
||||
CACHE_POST_DINVALIDATE()
|
||||
|
||||
/* Cache the test area */
|
||||
CACHE_POST_DTOUCH()
|
||||
|
||||
/* Write the zero pattern to the test area */
|
||||
CACHE_POST_MEMSET(0)
|
||||
|
||||
CACHE_POST_DSTORE()
|
||||
|
||||
/* Write the negative pattern to the test area */
|
||||
CACHE_POST_MEMSET(0xff)
|
||||
|
||||
CACHE_POST_DINVALIDATE()
|
||||
CACHE_POST_DISABLE()
|
||||
|
||||
/* Read the test area */
|
||||
CACHE_POST_CHECK()
|
||||
|
||||
mr r3, r13
|
||||
mtlr r9
|
||||
blr
|
||||
|
||||
/*
|
||||
* Write-back mode test.
|
||||
* Write 0xff pattern, store the cache, write zeroes.
|
||||
* Invalidate the cache.
|
||||
* Check that 0xff pattern is read.
|
||||
*/
|
||||
.global cache_post_test4
|
||||
cache_post_test4:
|
||||
mflr r9
|
||||
mr r10, r3 /* tlb */
|
||||
mr r11, r4 /* p */
|
||||
mr r12, r5 /* size */
|
||||
|
||||
CACHE_POST_WB()
|
||||
CACHE_POST_DINVALIDATE()
|
||||
|
||||
/* Cache the test area */
|
||||
CACHE_POST_DTOUCH()
|
||||
|
||||
/* Write the negative pattern to the test area */
|
||||
CACHE_POST_MEMSET(0xff)
|
||||
|
||||
CACHE_POST_DSTORE()
|
||||
|
||||
/* Write the zero pattern to the test area */
|
||||
CACHE_POST_MEMSET(0)
|
||||
|
||||
CACHE_POST_DINVALIDATE()
|
||||
CACHE_POST_DISABLE()
|
||||
|
||||
/* Read the test area */
|
||||
CACHE_POST_CHECK()
|
||||
|
||||
mr r3, r13
|
||||
mtlr r9
|
||||
blr
|
||||
|
||||
/*
|
||||
* Load the test instructions into the instruction cache.
|
||||
* Replace the test instructions.
|
||||
* Check that the original instructions are executed.
|
||||
*/
|
||||
.global cache_post_test5
|
||||
cache_post_test5:
|
||||
mflr r9
|
||||
mr r10, r3 /* tlb */
|
||||
mr r11, r4 /* p */
|
||||
mr r12, r5 /* size */
|
||||
|
||||
CACHE_POST_WT()
|
||||
CACHE_POST_IINVALIDATE()
|
||||
|
||||
/* Compute r13 = cache_post_test_inst */
|
||||
bl cache_post_test5_reloc
|
||||
cache_post_test5_reloc:
|
||||
mflr r13
|
||||
lis r0, (cache_post_test_inst - cache_post_test5_reloc)@h
|
||||
ori r0, r0, (cache_post_test_inst - cache_post_test5_reloc)@l
|
||||
add r13, r13, r0
|
||||
|
||||
/* Copy the test instructions to the test area */
|
||||
lwz r0, 0(r13)
|
||||
stw r0, 0(r11)
|
||||
lwz r0, 8(r13)
|
||||
stw r0, 4(r11)
|
||||
sync
|
||||
|
||||
/* Invalidate the cache line */
|
||||
icbi r0, r11
|
||||
sync
|
||||
isync
|
||||
|
||||
/* Execute the test instructions */
|
||||
mtlr r11
|
||||
blrl
|
||||
|
||||
/* Replace the test instruction */
|
||||
lwz r0, 4(r13)
|
||||
stw r0, 0(r11)
|
||||
sync
|
||||
|
||||
/* Do not invalidate the cache line */
|
||||
isync
|
||||
|
||||
/* Execute the test instructions */
|
||||
mtlr r11
|
||||
blrl
|
||||
mr r13, r3
|
||||
|
||||
CACHE_POST_IINVALIDATE()
|
||||
CACHE_POST_DINVALIDATE()
|
||||
CACHE_POST_DISABLE()
|
||||
|
||||
mr r3, r13
|
||||
mtlr r9
|
||||
blr
|
||||
|
||||
/*
|
||||
* Load the test instructions into the instruction cache.
|
||||
* Replace the test instructions and invalidate the cache.
|
||||
* Check that the replaced instructions are executed.
|
||||
*/
|
||||
.global cache_post_test6
|
||||
cache_post_test6:
|
||||
mflr r9
|
||||
mr r10, r3 /* tlb */
|
||||
mr r11, r4 /* p */
|
||||
mr r12, r5 /* size */
|
||||
|
||||
CACHE_POST_WT()
|
||||
CACHE_POST_IINVALIDATE()
|
||||
|
||||
/* Compute r13 = cache_post_test_inst */
|
||||
bl cache_post_test6_reloc
|
||||
cache_post_test6_reloc:
|
||||
mflr r13
|
||||
lis r0, (cache_post_test_inst - cache_post_test6_reloc)@h
|
||||
ori r0, r0, (cache_post_test_inst - cache_post_test6_reloc)@l
|
||||
add r13, r13, r0
|
||||
|
||||
/* Copy the test instructions to the test area */
|
||||
lwz r0, 4(r13)
|
||||
stw r0, 0(r11)
|
||||
lwz r0, 8(r13)
|
||||
stw r0, 4(r11)
|
||||
sync
|
||||
|
||||
/* Invalidate the cache line */
|
||||
icbi r0, r11
|
||||
sync
|
||||
isync
|
||||
|
||||
/* Execute the test instructions */
|
||||
mtlr r11
|
||||
blrl
|
||||
|
||||
/* Replace the test instruction */
|
||||
lwz r0, 0(r13)
|
||||
stw r0, 0(r11)
|
||||
sync
|
||||
|
||||
/* Invalidate the cache line */
|
||||
icbi r0, r11
|
||||
sync
|
||||
isync
|
||||
|
||||
/* Execute the test instructions */
|
||||
mtlr r11
|
||||
blrl
|
||||
mr r13, r3
|
||||
|
||||
CACHE_POST_IINVALIDATE()
|
||||
CACHE_POST_DINVALIDATE()
|
||||
CACHE_POST_DISABLE()
|
||||
|
||||
mr r3, r13
|
||||
mtlr r9
|
||||
blr
|
||||
|
||||
/* Test instructions.
|
||||
*/
|
||||
cache_post_test_inst:
|
||||
li r3, 0
|
||||
li r3, -1
|
||||
blr
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_CACHE */
|
||||
|
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Developed for DENX Software Engineering GmbH.
|
||||
*
|
||||
* Author: Pavel Kolesnikov <concord@emcraft.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* define DEBUG for debugging output (obviously ;-)) */
|
||||
#if 0
|
||||
#define DEBUG
|
||||
#endif
|
||||
|
||||
#include <common.h>
|
||||
#include <watchdog.h>
|
||||
|
||||
#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
|
||||
|
||||
#include <post.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_ECC
|
||||
|
||||
/*
|
||||
* MEMORY ECC test
|
||||
*
|
||||
* This test performs the checks ECC facility of memory.
|
||||
*/
|
||||
#include <asm/processor.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/ppc440.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
const static uint8_t syndrome_codes[] = {
|
||||
0xF4, 0XF1, 0XEC, 0XEA, 0XE9, 0XE6, 0XE5, 0XE3,
|
||||
0XDC, 0XDA, 0XD9, 0XD6, 0XD5, 0XD3, 0XCE, 0XCB,
|
||||
0xB5, 0XB0, 0XAD, 0XAB, 0XA8, 0XA7, 0XA4, 0XA2,
|
||||
0X9D, 0X9B, 0X98, 0X97, 0X94, 0X92, 0X8F, 0X8A,
|
||||
0x75, 0x70, 0X6D, 0X6B, 0X68, 0X67, 0X64, 0X62,
|
||||
0X5E, 0X5B, 0X58, 0X57, 0X54, 0X52, 0X4F, 0X4A,
|
||||
0x34, 0x31, 0X2C, 0X2A, 0X29, 0X26, 0X25, 0X23,
|
||||
0X1C, 0X1A, 0X19, 0X16, 0X15, 0X13, 0X0E, 0X0B,
|
||||
0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
|
||||
};
|
||||
|
||||
#define ECC_START_ADDR 0x10
|
||||
#define ECC_STOP_ADDR 0x2000
|
||||
#define ECC_PATTERN 0x01010101
|
||||
#define ECC_PATTERN_CORR 0x11010101
|
||||
#define ECC_PATTERN_UNCORR 0x61010101
|
||||
|
||||
inline static void disable_ecc(void)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
sync(); /* Wait for any pending memory accesses to complete. */
|
||||
mfsdram(DDR0_22, value);
|
||||
mtsdram(DDR0_22, (value & ~DDR0_22_CTRL_RAW_MASK)
|
||||
| DDR0_22_CTRL_RAW_ECC_DISABLE);
|
||||
}
|
||||
|
||||
inline static void clear_and_enable_ecc(void)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
sync(); /* Wait for any pending memory accesses to complete. */
|
||||
mfsdram(DDR0_00, value);
|
||||
mtsdram(DDR0_00, value | DDR0_00_INT_ACK_ALL);
|
||||
mfsdram(DDR0_22, value);
|
||||
mtsdram(DDR0_22, (value & ~DDR0_22_CTRL_RAW_MASK)
|
||||
| DDR0_22_CTRL_RAW_ECC_ENABLE);
|
||||
}
|
||||
|
||||
static uint32_t get_ecc_status(void)
|
||||
{
|
||||
uint32_t int_status;
|
||||
#if defined(DEBUG)
|
||||
uint8_t syndrome;
|
||||
uint32_t hdata, ldata, haddr, laddr;
|
||||
uint32_t value;
|
||||
#endif
|
||||
|
||||
mfsdram(DDR0_00, int_status);
|
||||
int_status &= DDR0_00_INT_STATUS_MASK;
|
||||
|
||||
#if defined(DEBUG)
|
||||
if (int_status & (DDR0_00_INT_STATUS_BIT0 | DDR0_00_INT_STATUS_BIT1)) {
|
||||
mfsdram(DDR0_32, laddr);
|
||||
mfsdram(DDR0_33, haddr);
|
||||
haddr &= 0x00000001;
|
||||
if (int_status & DDR0_00_INT_STATUS_BIT1)
|
||||
debug("Multiple accesses");
|
||||
else
|
||||
debug("A single access");
|
||||
|
||||
debug(" outside the defined physical memory space detected\n"
|
||||
" addr = 0x%01x%08x\n", haddr, laddr);
|
||||
}
|
||||
if (int_status & (DDR0_00_INT_STATUS_BIT2 | DDR0_00_INT_STATUS_BIT3)) {
|
||||
unsigned int bit;
|
||||
|
||||
mfsdram(DDR0_23, value);
|
||||
syndrome = (value >> 16) & 0xff;
|
||||
for (bit = 0; bit < sizeof(syndrome_codes); bit++)
|
||||
if (syndrome_codes[bit] == syndrome)
|
||||
break;
|
||||
|
||||
mfsdram(DDR0_38, laddr);
|
||||
mfsdram(DDR0_39, haddr);
|
||||
haddr &= 0x00000001;
|
||||
mfsdram(DDR0_40, ldata);
|
||||
mfsdram(DDR0_41, hdata);
|
||||
if (int_status & DDR0_00_INT_STATUS_BIT3)
|
||||
debug("Multiple correctable ECC events");
|
||||
else
|
||||
debug("Single correctable ECC event");
|
||||
|
||||
debug(" detected\n 0x%01x%08x - 0x%08x%08x, bit - %d\n",
|
||||
haddr, laddr, hdata, ldata, bit);
|
||||
}
|
||||
if (int_status & (DDR0_00_INT_STATUS_BIT4 | DDR0_00_INT_STATUS_BIT5)) {
|
||||
mfsdram(DDR0_23, value);
|
||||
syndrome = (value >> 8) & 0xff;
|
||||
mfsdram(DDR0_34, laddr);
|
||||
mfsdram(DDR0_35, haddr);
|
||||
haddr &= 0x00000001;
|
||||
mfsdram(DDR0_36, ldata);
|
||||
mfsdram(DDR0_37, hdata);
|
||||
if (int_status & DDR0_00_INT_STATUS_BIT5)
|
||||
debug("Multiple uncorrectable ECC events");
|
||||
else
|
||||
debug("Single uncorrectable ECC event");
|
||||
|
||||
debug(" detected\n 0x%01x%08x - 0x%08x%08x, "
|
||||
"syndrome - 0x%02x\n",
|
||||
haddr, laddr, hdata, ldata, syndrome);
|
||||
}
|
||||
if (int_status & DDR0_00_INT_STATUS_BIT6)
|
||||
debug("DRAM initialization complete\n");
|
||||
#endif /* defined(DEBUG) */
|
||||
|
||||
return int_status;
|
||||
}
|
||||
|
||||
static int test_ecc(uint32_t ecc_addr)
|
||||
{
|
||||
uint32_t value;
|
||||
volatile uint32_t *const ecc_mem = (volatile uint32_t *)ecc_addr;
|
||||
int ret = 0;
|
||||
|
||||
WATCHDOG_RESET();
|
||||
|
||||
debug("Entering test_ecc(0x%08x)\n", ecc_addr);
|
||||
/* Set up correct ECC in memory */
|
||||
disable_ecc();
|
||||
clear_and_enable_ecc();
|
||||
out_be32(ecc_mem, ECC_PATTERN);
|
||||
out_be32(ecc_mem + 1, ECC_PATTERN);
|
||||
ppcDcbf((u32)ecc_mem);
|
||||
|
||||
/* Verify no ECC error reading back */
|
||||
value = in_be32(ecc_mem);
|
||||
disable_ecc();
|
||||
if (ECC_PATTERN != value) {
|
||||
debug("Data read error (no-error case): "
|
||||
"expected 0x%08x, read 0x%08x\n", ECC_PATTERN, value);
|
||||
ret = 1;
|
||||
}
|
||||
value = get_ecc_status();
|
||||
if (0x00000000 != value) {
|
||||
/* Expected no ECC status reported */
|
||||
debug("get_ecc_status(): expected 0x%08x, got 0x%08x\n",
|
||||
0x00000000, value);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
/* Test for correctable error by creating a one-bit error */
|
||||
out_be32(ecc_mem, ECC_PATTERN_CORR);
|
||||
ppcDcbf((u32)ecc_mem);
|
||||
clear_and_enable_ecc();
|
||||
value = in_be32(ecc_mem);
|
||||
disable_ecc();
|
||||
/* Test that the corrected data was read */
|
||||
if (ECC_PATTERN != value) {
|
||||
debug("Data read error (correctable-error case): "
|
||||
"expected 0x%08x, read 0x%08x\n", ECC_PATTERN, value);
|
||||
ret = 1;
|
||||
}
|
||||
value = get_ecc_status();
|
||||
if ((DDR0_00_INT_STATUS_BIT2 | DDR0_00_INT_STATUS_BIT7) != value) {
|
||||
/* Expected a single correctable error reported */
|
||||
debug("get_ecc_status(): expected 0x%08x, got 0x%08x\n",
|
||||
DDR0_00_INT_STATUS_BIT2, value);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
/* Test for uncorrectable error by creating a two-bit error */
|
||||
out_be32(ecc_mem, ECC_PATTERN_UNCORR);
|
||||
ppcDcbf((u32)ecc_mem);
|
||||
clear_and_enable_ecc();
|
||||
value = in_be32(ecc_mem);
|
||||
disable_ecc();
|
||||
/* Test that the corrected data was read */
|
||||
if (ECC_PATTERN_UNCORR != value) {
|
||||
debug("Data read error (uncorrectable-error case): "
|
||||
"expected 0x%08x, read 0x%08x\n", ECC_PATTERN_UNCORR,
|
||||
value);
|
||||
ret = 1;
|
||||
}
|
||||
value = get_ecc_status();
|
||||
if ((DDR0_00_INT_STATUS_BIT4 | DDR0_00_INT_STATUS_BIT7) != value) {
|
||||
/* Expected a single uncorrectable error reported */
|
||||
debug("get_ecc_status(): expected 0x%08x, got 0x%08x\n",
|
||||
DDR0_00_INT_STATUS_BIT4, value);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
/* Remove error from SDRAM and enable ECC. */
|
||||
out_be32(ecc_mem, ECC_PATTERN);
|
||||
ppcDcbf((u32)ecc_mem);
|
||||
clear_and_enable_ecc();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ecc_post_test(int flags)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t value;
|
||||
uint32_t iaddr;
|
||||
|
||||
mfsdram(DDR0_22, value);
|
||||
if (0x3 != DDR0_22_CTRL_RAW_DECODE(value)) {
|
||||
debug("SDRAM ECC not enabled, skipping ECC POST.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Mask all interrupts. */
|
||||
mfsdram(DDR0_01, value);
|
||||
mtsdram(DDR0_01, (value & ~DDR0_01_INT_MASK_MASK)
|
||||
| DDR0_01_INT_MASK_ALL_OFF);
|
||||
|
||||
for (iaddr = ECC_START_ADDR; iaddr <= ECC_STOP_ADDR; iaddr += iaddr) {
|
||||
ret = test_ecc(iaddr);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Clear possible errors resulting from ECC testing. (If not done, we
|
||||
* we could get an interrupt later on when exceptions are enabled.)
|
||||
*/
|
||||
set_mcsr(get_mcsr());
|
||||
debug("ecc_post_test() returning %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_ECC */
|
||||
#endif /* defined(CONFIG_440EPX) || defined(CONFIG_440GRX) */
|
||||
435
common/package/boot/uboot-ipq40xx/src/post/cpu/ppc4xx/ether.c
Normal file
435
common/package/boot/uboot-ipq40xx/src/post/cpu/ppc4xx/ether.c
Normal file
|
|
@ -0,0 +1,435 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* Author: Igor Lisitsin <igor@emcraft.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* Ethernet test
|
||||
*
|
||||
* The Ethernet Media Access Controllers (EMAC) are tested in the
|
||||
* internal loopback mode.
|
||||
* The controllers are configured accordingly and several packets
|
||||
* are transmitted. The configurable test parameters are:
|
||||
* MIN_PACKET_LENGTH - minimum size of packet to transmit
|
||||
* MAX_PACKET_LENGTH - maximum size of packet to transmit
|
||||
* CONFIG_SYS_POST_ETH_LOOPS - Number of test loops. Each loop
|
||||
* is tested with a different frame length. Starting with
|
||||
* MAX_PACKET_LENGTH and going down to MIN_PACKET_LENGTH.
|
||||
* Defaults to 10 and can be overriden in the board config header.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_ETHER
|
||||
|
||||
#include <asm/cache.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/ppc4xx-mal.h>
|
||||
#include <asm/ppc4xx-emac.h>
|
||||
#include <malloc.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/*
|
||||
* Get count of EMAC devices (doesn't have to be the max. possible number
|
||||
* supported by the cpu)
|
||||
*
|
||||
* CONFIG_BOARD_EMAC_COUNT added so now a "dynamic" way to configure the
|
||||
* EMAC count is possible. As it is needed for the Kilauea/Haleakala
|
||||
* 405EX/405EXr eval board, using the same binary.
|
||||
*/
|
||||
#if defined(CONFIG_BOARD_EMAC_COUNT)
|
||||
#define LAST_EMAC_NUM board_emac_count()
|
||||
#else /* CONFIG_BOARD_EMAC_COUNT */
|
||||
#if defined(CONFIG_HAS_ETH3)
|
||||
#define LAST_EMAC_NUM 4
|
||||
#elif defined(CONFIG_HAS_ETH2)
|
||||
#define LAST_EMAC_NUM 3
|
||||
#elif defined(CONFIG_HAS_ETH1)
|
||||
#define LAST_EMAC_NUM 2
|
||||
#else
|
||||
#define LAST_EMAC_NUM 1
|
||||
#endif
|
||||
#endif /* CONFIG_BOARD_EMAC_COUNT */
|
||||
|
||||
#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
|
||||
#define SDR0_MFR_ETH_CLK_SEL_V(n) ((0x01<<27) / (n+1))
|
||||
#endif
|
||||
|
||||
#define MIN_PACKET_LENGTH 64
|
||||
#define MAX_PACKET_LENGTH 1514
|
||||
#ifndef CONFIG_SYS_POST_ETH_LOOPS
|
||||
#define CONFIG_SYS_POST_ETH_LOOPS 10
|
||||
#endif
|
||||
#define PACKET_INCR ((MAX_PACKET_LENGTH - MIN_PACKET_LENGTH) / \
|
||||
CONFIG_SYS_POST_ETH_LOOPS)
|
||||
|
||||
static volatile mal_desc_t tx __cacheline_aligned;
|
||||
static volatile mal_desc_t rx __cacheline_aligned;
|
||||
static char *tx_buf;
|
||||
static char *rx_buf;
|
||||
|
||||
int board_emac_count(void);
|
||||
|
||||
static void ether_post_init (int devnum, int hw_addr)
|
||||
{
|
||||
int i;
|
||||
#if defined(CONFIG_440GX) || \
|
||||
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
|
||||
defined(CONFIG_440SP) || defined(CONFIG_440SPE)
|
||||
unsigned mode_reg;
|
||||
sys_info_t sysinfo;
|
||||
#endif
|
||||
#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || defined(CONFIG_440SPE)
|
||||
unsigned long mfr;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_440GX) || \
|
||||
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
|
||||
defined(CONFIG_440SP) || defined(CONFIG_440SPE)
|
||||
/* Need to get the OPB frequency so we can access the PHY */
|
||||
get_sys_info (&sysinfo);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
|
||||
/* provide clocks for EMAC internal loopback */
|
||||
mfsdr (SDR0_MFR, mfr);
|
||||
mfr |= SDR0_MFR_ETH_CLK_SEL_V(devnum);
|
||||
mtsdr (SDR0_MFR, mfr);
|
||||
sync ();
|
||||
#endif
|
||||
/* reset emac */
|
||||
out_be32 ((void*)(EMAC0_MR0 + hw_addr), EMAC_MR0_SRST);
|
||||
sync ();
|
||||
|
||||
for (i = 0;; i++) {
|
||||
if (!(in_be32 ((void*)(EMAC0_MR0 + hw_addr)) & EMAC_MR0_SRST))
|
||||
break;
|
||||
if (i >= 1000) {
|
||||
printf ("Timeout resetting EMAC\n");
|
||||
break;
|
||||
}
|
||||
udelay (1000);
|
||||
}
|
||||
#if defined(CONFIG_440GX) || \
|
||||
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
|
||||
defined(CONFIG_440SP) || defined(CONFIG_440SPE)
|
||||
/* Whack the M1 register */
|
||||
mode_reg = 0x0;
|
||||
if (sysinfo.freqOPB <= 50000000);
|
||||
else if (sysinfo.freqOPB <= 66666667)
|
||||
mode_reg |= EMAC_MR1_OBCI_66;
|
||||
else if (sysinfo.freqOPB <= 83333333)
|
||||
mode_reg |= EMAC_MR1_OBCI_83;
|
||||
else if (sysinfo.freqOPB <= 100000000)
|
||||
mode_reg |= EMAC_MR1_OBCI_100;
|
||||
else
|
||||
mode_reg |= EMAC_MR1_OBCI_GT100;
|
||||
|
||||
out_be32 ((void*)(EMAC0_MR1 + hw_addr), mode_reg);
|
||||
|
||||
#endif /* defined(CONFIG_440GX) || defined(CONFIG_440SP) */
|
||||
|
||||
/* set the Mal configuration reg */
|
||||
#if defined(CONFIG_440GX) || \
|
||||
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
|
||||
defined(CONFIG_440SP) || defined(CONFIG_440SPE)
|
||||
mtdcr (MAL0_CFG, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA |
|
||||
MAL_CR_PLBLT_DEFAULT | 0x00330000);
|
||||
#else
|
||||
mtdcr (MAL0_CFG, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA | MAL_CR_PLBLT_DEFAULT);
|
||||
/* Errata 1.12: MAL_1 -- Disable MAL bursting */
|
||||
if (get_pvr() == PVR_440GP_RB) {
|
||||
mtdcr (MAL0_CFG, mfdcr(MAL0_CFG) & ~MAL_CR_PLBB);
|
||||
}
|
||||
#endif
|
||||
/* setup buffer descriptors */
|
||||
tx.ctrl = MAL_TX_CTRL_WRAP;
|
||||
tx.data_len = 0;
|
||||
tx.data_ptr = (char*)L1_CACHE_ALIGN((u32)tx_buf);
|
||||
|
||||
rx.ctrl = MAL_TX_CTRL_WRAP | MAL_RX_CTRL_EMPTY;
|
||||
rx.data_len = 0;
|
||||
rx.data_ptr = (char*)L1_CACHE_ALIGN((u32)rx_buf);
|
||||
flush_dcache_range((u32)&rx, (u32)&rx + sizeof(mal_desc_t));
|
||||
flush_dcache_range((u32)&tx, (u32)&tx + sizeof(mal_desc_t));
|
||||
|
||||
switch (devnum) {
|
||||
case 1:
|
||||
/* setup MAL tx & rx channel pointers */
|
||||
#if defined (CONFIG_405EP) || defined (CONFIG_440EP) || defined (CONFIG_440GR)
|
||||
mtdcr (MAL0_TXCTP2R, &tx);
|
||||
#else
|
||||
mtdcr (MAL0_TXCTP1R, &tx);
|
||||
#endif
|
||||
#if defined(CONFIG_440)
|
||||
mtdcr (MAL0_TXBADDR, 0x0);
|
||||
mtdcr (MAL0_RXBADDR, 0x0);
|
||||
#endif
|
||||
mtdcr (MAL0_RXCTP1R, &rx);
|
||||
/* set RX buffer size */
|
||||
mtdcr (MAL0_RCBS1, PKTSIZE_ALIGN / 16);
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
/* setup MAL tx & rx channel pointers */
|
||||
#if defined(CONFIG_440)
|
||||
mtdcr (MAL0_TXBADDR, 0x0);
|
||||
mtdcr (MAL0_RXBADDR, 0x0);
|
||||
#endif
|
||||
mtdcr (MAL0_TXCTP0R, &tx);
|
||||
mtdcr (MAL0_RXCTP0R, &rx);
|
||||
/* set RX buffer size */
|
||||
mtdcr (MAL0_RCBS0, PKTSIZE_ALIGN / 16);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Enable MAL transmit and receive channels */
|
||||
#if defined(CONFIG_405EP) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
|
||||
mtdcr (MAL0_TXCASR, (MAL_TXRX_CASR >> (devnum*2)));
|
||||
#else
|
||||
mtdcr (MAL0_TXCASR, (MAL_TXRX_CASR >> devnum));
|
||||
#endif
|
||||
mtdcr (MAL0_RXCASR, (MAL_TXRX_CASR >> devnum));
|
||||
|
||||
/* set internal loopback mode */
|
||||
#ifdef CONFIG_SYS_POST_ETHER_EXT_LOOPBACK
|
||||
out_be32 ((void*)(EMAC0_MR1 + hw_addr), EMAC_MR1_FDE | 0 |
|
||||
EMAC_MR1_RFS_4K | EMAC_MR1_TX_FIFO_2K |
|
||||
EMAC_MR1_MF_100MBPS | EMAC_MR1_IST |
|
||||
in_be32 ((void*)(EMAC0_MR1 + hw_addr)));
|
||||
#else
|
||||
out_be32 ((void*)(EMAC0_MR1 + hw_addr), EMAC_MR1_FDE | EMAC_MR1_ILE |
|
||||
EMAC_MR1_RFS_4K | EMAC_MR1_TX_FIFO_2K |
|
||||
EMAC_MR1_MF_100MBPS | EMAC_MR1_IST |
|
||||
in_be32 ((void*)(EMAC0_MR1 + hw_addr)));
|
||||
#endif
|
||||
|
||||
/* set transmit enable & receive enable */
|
||||
out_be32 ((void*)(EMAC0_MR0 + hw_addr), EMAC_MR0_TXE | EMAC_MR0_RXE);
|
||||
|
||||
/* enable broadcast address */
|
||||
out_be32 ((void*)(EMAC0_RXM + hw_addr), EMAC_RMR_BAE);
|
||||
|
||||
/* set transmit request threshold register */
|
||||
out_be32 ((void*)(EMAC0_TRTR + hw_addr), 0x18000000); /* 256 byte threshold */
|
||||
|
||||
/* set receive low/high water mark register */
|
||||
#if defined(CONFIG_440)
|
||||
/* 440s has a 64 byte burst length */
|
||||
out_be32 ((void*)(EMAC0_RX_HI_LO_WMARK + hw_addr), 0x80009000);
|
||||
#else
|
||||
/* 405s have a 16 byte burst length */
|
||||
out_be32 ((void*)(EMAC0_RX_HI_LO_WMARK + hw_addr), 0x0f002000);
|
||||
#endif /* defined(CONFIG_440) */
|
||||
out_be32 ((void*)(EMAC0_TMR1 + hw_addr), 0xf8640000);
|
||||
|
||||
/* Set fifo limit entry in tx mode 0 */
|
||||
out_be32 ((void*)(EMAC0_TMR0 + hw_addr), 0x00000003);
|
||||
/* Frame gap set */
|
||||
out_be32 ((void*)(EMAC0_I_FRAME_GAP_REG + hw_addr), 0x00000008);
|
||||
sync ();
|
||||
}
|
||||
|
||||
static void ether_post_halt (int devnum, int hw_addr)
|
||||
{
|
||||
int i = 0;
|
||||
#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
|
||||
unsigned long mfr;
|
||||
#endif
|
||||
|
||||
/* 1st reset MAL channel */
|
||||
/* Note: writing a 0 to a channel has no effect */
|
||||
#if defined(CONFIG_405EP) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
|
||||
mtdcr (MAL0_TXCARR, MAL_TXRX_CASR >> (devnum * 2));
|
||||
#else
|
||||
mtdcr (MAL0_TXCARR, MAL_TXRX_CASR >> devnum);
|
||||
#endif
|
||||
mtdcr (MAL0_RXCARR, MAL_TXRX_CASR >> devnum);
|
||||
|
||||
/* wait for reset */
|
||||
while (mfdcr (MAL0_RXCASR) & (MAL_TXRX_CASR >> devnum)) {
|
||||
if (i++ >= 1000)
|
||||
break;
|
||||
udelay (1000);
|
||||
}
|
||||
/* emac reset */
|
||||
out_be32 ((void*)(EMAC0_MR0 + hw_addr), EMAC_MR0_SRST);
|
||||
|
||||
#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
|
||||
/* remove clocks for EMAC internal loopback */
|
||||
mfsdr (SDR0_MFR, mfr);
|
||||
mfr &= ~SDR0_MFR_ETH_CLK_SEL_V(devnum);
|
||||
mtsdr (SDR0_MFR, mfr);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ether_post_send (int devnum, int hw_addr, void *packet, int length)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (tx.ctrl & MAL_TX_CTRL_READY) {
|
||||
if (i++ > 100) {
|
||||
printf ("TX timeout\n");
|
||||
return;
|
||||
}
|
||||
udelay (1000);
|
||||
invalidate_dcache_range((u32)&tx, (u32)&tx + sizeof(mal_desc_t));
|
||||
}
|
||||
tx.ctrl = MAL_TX_CTRL_READY | MAL_TX_CTRL_WRAP | MAL_TX_CTRL_LAST |
|
||||
EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP;
|
||||
tx.data_len = length;
|
||||
memcpy (tx.data_ptr, packet, length);
|
||||
flush_dcache_range((u32)&tx, (u32)&tx + sizeof(mal_desc_t));
|
||||
flush_dcache_range((u32)tx.data_ptr, (u32)tx.data_ptr + length);
|
||||
sync ();
|
||||
|
||||
out_be32 ((void*)(EMAC0_TMR0 + hw_addr), in_be32 ((void*)(EMAC0_TMR0 + hw_addr)) | EMAC_TMR0_GNP0);
|
||||
sync ();
|
||||
}
|
||||
|
||||
static int ether_post_recv (int devnum, int hw_addr, void *packet, int max_length)
|
||||
{
|
||||
int length;
|
||||
int i = 0;
|
||||
|
||||
while (rx.ctrl & MAL_RX_CTRL_EMPTY) {
|
||||
if (i++ > 100) {
|
||||
printf ("RX timeout\n");
|
||||
return 0;
|
||||
}
|
||||
udelay (1000);
|
||||
invalidate_dcache_range((u32)&rx, (u32)&rx + sizeof(mal_desc_t));
|
||||
}
|
||||
length = rx.data_len - 4;
|
||||
if (length <= max_length) {
|
||||
invalidate_dcache_range((u32)rx.data_ptr, (u32)rx.data_ptr + length);
|
||||
memcpy(packet, rx.data_ptr, length);
|
||||
}
|
||||
sync ();
|
||||
|
||||
rx.ctrl |= MAL_RX_CTRL_EMPTY;
|
||||
flush_dcache_range((u32)&rx, (u32)&rx + sizeof(mal_desc_t));
|
||||
sync ();
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test routines
|
||||
*/
|
||||
|
||||
static void packet_fill (char *packet, int length)
|
||||
{
|
||||
char c = (char) length;
|
||||
int i;
|
||||
|
||||
/* set up ethernet header */
|
||||
memset (packet, 0xff, 14);
|
||||
|
||||
for (i = 14; i < length; i++) {
|
||||
packet[i] = c++;
|
||||
}
|
||||
}
|
||||
|
||||
static int packet_check (char *packet, int length)
|
||||
{
|
||||
char c = (char) length;
|
||||
int i;
|
||||
|
||||
for (i = 14; i < length; i++) {
|
||||
if (packet[i] != c++)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char packet_send[MAX_PACKET_LENGTH];
|
||||
char packet_recv[MAX_PACKET_LENGTH];
|
||||
static int test_ctlr (int devnum, int hw_addr)
|
||||
{
|
||||
int res = -1;
|
||||
int length;
|
||||
int l;
|
||||
|
||||
ether_post_init (devnum, hw_addr);
|
||||
|
||||
for (l = MAX_PACKET_LENGTH; l >= MIN_PACKET_LENGTH;
|
||||
l -= PACKET_INCR) {
|
||||
packet_fill (packet_send, l);
|
||||
|
||||
ether_post_send (devnum, hw_addr, packet_send, l);
|
||||
|
||||
length = ether_post_recv (devnum, hw_addr, packet_recv,
|
||||
sizeof (packet_recv));
|
||||
|
||||
if (length != l || packet_check (packet_recv, length) < 0) {
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
|
||||
res = 0;
|
||||
|
||||
Done:
|
||||
|
||||
ether_post_halt (devnum, hw_addr);
|
||||
|
||||
if (res != 0) {
|
||||
post_log ("EMAC%d test failed\n", devnum);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int ether_post_test (int flags)
|
||||
{
|
||||
int res = 0;
|
||||
int i;
|
||||
|
||||
/* Allocate tx & rx packet buffers */
|
||||
tx_buf = malloc (PKTSIZE_ALIGN + CONFIG_SYS_CACHELINE_SIZE);
|
||||
rx_buf = malloc (PKTSIZE_ALIGN + CONFIG_SYS_CACHELINE_SIZE);
|
||||
|
||||
if (!tx_buf || !rx_buf) {
|
||||
printf ("Failed to allocate packet buffers\n");
|
||||
res = -1;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
for (i = 0; i < LAST_EMAC_NUM; i++) {
|
||||
if (test_ctlr (i, i*0x100))
|
||||
res = -1;
|
||||
}
|
||||
|
||||
out_free:
|
||||
free (tx_buf);
|
||||
free (rx_buf);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_ETHER */
|
||||
57
common/package/boot/uboot-ipq40xx/src/post/cpu/ppc4xx/fpu.c
Normal file
57
common/package/boot/uboot-ipq40xx/src/post/cpu/ppc4xx/fpu.c
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* Author: Sergei Poselenov <sposelenov@emcraft.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined(CONFIG_440EP) || \
|
||||
defined(CONFIG_440EPX)
|
||||
|
||||
#include <asm/processor.h>
|
||||
#include <asm/ppc4xx.h>
|
||||
|
||||
|
||||
int fpu_status(void)
|
||||
{
|
||||
if (mfspr(SPRN_CCR0) & CCR0_DAPUIB)
|
||||
return 0; /* Disabled */
|
||||
else
|
||||
return 1; /* Enabled */
|
||||
}
|
||||
|
||||
|
||||
void fpu_disable(void)
|
||||
{
|
||||
mtspr(SPRN_CCR0, mfspr(SPRN_CCR0) | CCR0_DAPUIB);
|
||||
mtmsr(mfmsr() & ~MSR_FP);
|
||||
}
|
||||
|
||||
|
||||
void fpu_enable(void)
|
||||
{
|
||||
mtspr(SPRN_CCR0, mfspr(SPRN_CCR0) & ~CCR0_DAPUIB);
|
||||
mtmsr(mfmsr() | MSR_FP);
|
||||
}
|
||||
|
||||
#endif
|
||||
89
common/package/boot/uboot-ipq40xx/src/post/cpu/ppc4xx/ocm.c
Normal file
89
common/package/boot/uboot-ipq40xx/src/post/cpu/ppc4xx/ocm.c
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* (C) Copyright 2008 Ilya Yanok, EmCraft Systems, yanok@emcraft.com
|
||||
*
|
||||
* Developed for DENX Software Engineering GmbH
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* This test attempts to verify on-chip memory (OCM). Result is written
|
||||
* to the scratch register and if test succeed it won't be run till next
|
||||
* power on.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define OCM_TEST_PATTERN1 0x55555555
|
||||
#define OCM_TEST_PATTERN2 0xAAAAAAAA
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_OCM
|
||||
|
||||
static uint ocm_status_read(void)
|
||||
{
|
||||
return in_be32((void *)CONFIG_SYS_OCM_STATUS_ADDR) &
|
||||
CONFIG_SYS_OCM_STATUS_MASK;
|
||||
}
|
||||
|
||||
static void ocm_status_write(uint value)
|
||||
{
|
||||
out_be32((void *)CONFIG_SYS_OCM_STATUS_ADDR, value |
|
||||
(in_be32((void *)CONFIG_SYS_OCM_STATUS_ADDR) &
|
||||
~CONFIG_SYS_OCM_STATUS_MASK));
|
||||
}
|
||||
|
||||
static inline int ocm_test_word(uint value, uint *address)
|
||||
{
|
||||
uint read_value;
|
||||
|
||||
*address = value;
|
||||
sync();
|
||||
read_value = *address;
|
||||
|
||||
return (read_value != value);
|
||||
}
|
||||
|
||||
int ocm_post_test(int flags)
|
||||
{
|
||||
uint old_value;
|
||||
int ret = 0;
|
||||
uint *address = (uint*)CONFIG_SYS_OCM_BASE;
|
||||
|
||||
if (ocm_status_read() == CONFIG_SYS_OCM_STATUS_OK)
|
||||
return 0;
|
||||
for (; address < (uint*)(CONFIG_SYS_OCM_BASE + CONFIG_SYS_OCM_SIZE); address++) {
|
||||
old_value = *address;
|
||||
if (ocm_test_word(OCM_TEST_PATTERN1, address) ||
|
||||
ocm_test_word(OCM_TEST_PATTERN2, address)) {
|
||||
ret = 1;
|
||||
*address = old_value;
|
||||
printf("OCM POST failed at %p!\n", address);
|
||||
break;
|
||||
}
|
||||
*address = old_value;
|
||||
}
|
||||
ocm_status_write(ret ? CONFIG_SYS_OCM_STATUS_FAIL : CONFIG_SYS_OCM_STATUS_OK);
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_OCM */
|
||||
200
common/package/boot/uboot-ipq40xx/src/post/cpu/ppc4xx/spr.c
Normal file
200
common/package/boot/uboot-ipq40xx/src/post/cpu/ppc4xx/spr.c
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* Author: Igor Lisitsin <igor@emcraft.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* SPR test
|
||||
*
|
||||
* The test checks the contents of Special Purpose Registers (SPR) listed
|
||||
* in the spr_test_list array below.
|
||||
* Each SPR value is read using mfspr instruction, some bits are masked
|
||||
* according to the table and the resulting value is compared to the
|
||||
* corresponding table value.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_SPR
|
||||
|
||||
#include <asm/processor.h>
|
||||
|
||||
#ifdef CONFIG_4xx_DCACHE
|
||||
#include <asm/mmu.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
int number;
|
||||
char * name;
|
||||
unsigned long mask;
|
||||
unsigned long value;
|
||||
} spr_test_list [] = {
|
||||
/* Standard Special-Purpose Registers */
|
||||
|
||||
{0x001, "XER", 0x00000000, 0x00000000},
|
||||
{0x008, "LR", 0x00000000, 0x00000000},
|
||||
{0x009, "CTR", 0x00000000, 0x00000000},
|
||||
{0x016, "DEC", 0x00000000, 0x00000000},
|
||||
{0x01a, "SRR0", 0x00000000, 0x00000000},
|
||||
{0x01b, "SRR1", 0x00000000, 0x00000000},
|
||||
{0x110, "SPRG0", 0x00000000, 0x00000000},
|
||||
{0x111, "SPRG1", 0x00000000, 0x00000000},
|
||||
{0x112, "SPRG2", 0x00000000, 0x00000000},
|
||||
{0x113, "SPRG3", 0x00000000, 0x00000000},
|
||||
{0x11f, "PVR", 0x00000000, 0x00000000},
|
||||
|
||||
/* Additional Special-Purpose Registers.
|
||||
* The values must match the initialization
|
||||
* values from arch/powerpc/cpu/ppc4xx/start.S
|
||||
*/
|
||||
{0x30, "PID", 0x00000000, 0x00000000},
|
||||
{0x3a, "CSRR0", 0x00000000, 0x00000000},
|
||||
{0x3b, "CSRR1", 0x00000000, 0x00000000},
|
||||
{0x3d, "DEAR", 0x00000000, 0x00000000},
|
||||
{0x3e, "ESR", 0x00000000, 0x00000000},
|
||||
#ifdef CONFIG_440
|
||||
{0x3f, "IVPR", 0xffff0000, 0x00000000},
|
||||
#endif
|
||||
{0x100, "USPRG0", 0x00000000, 0x00000000},
|
||||
{0x104, "SPRG4", 0x00000000, 0x00000000},
|
||||
{0x105, "SPRG5", 0x00000000, 0x00000000},
|
||||
{0x106, "SPRG6", 0x00000000, 0x00000000},
|
||||
{0x107, "SPRG7", 0x00000000, 0x00000000},
|
||||
{0x10c, "TBL", 0x00000000, 0x00000000},
|
||||
{0x10d, "TBU", 0x00000000, 0x00000000},
|
||||
#ifdef CONFIG_440
|
||||
{0x11e, "PIR", 0x0000000f, 0x00000000},
|
||||
#endif
|
||||
{0x130, "DBSR", 0x00000000, 0x00000000},
|
||||
{0x134, "DBCR0", 0x00000000, 0x00000000},
|
||||
{0x135, "DBCR1", 0x00000000, 0x00000000},
|
||||
{0x136, "DBCR2", 0x00000000, 0x00000000},
|
||||
{0x138, "IAC1", 0x00000000, 0x00000000},
|
||||
{0x139, "IAC2", 0x00000000, 0x00000000},
|
||||
{0x13a, "IAC3", 0x00000000, 0x00000000},
|
||||
{0x13b, "IAC4", 0x00000000, 0x00000000},
|
||||
{0x13c, "DAC1", 0x00000000, 0x00000000},
|
||||
{0x13d, "DAC2", 0x00000000, 0x00000000},
|
||||
{0x13e, "DVC1", 0x00000000, 0x00000000},
|
||||
{0x13f, "DVC2", 0x00000000, 0x00000000},
|
||||
{0x150, "TSR", 0x00000000, 0x00000000},
|
||||
{0x154, "TCR", 0x00000000, 0x00000000},
|
||||
#ifdef CONFIG_440
|
||||
{0x190, "IVOR0", 0x0000fff0, 0x00000100},
|
||||
{0x191, "IVOR1", 0x0000fff0, 0x00000200},
|
||||
{0x192, "IVOR2", 0x0000fff0, 0x00000300},
|
||||
{0x193, "IVOR3", 0x0000fff0, 0x00000400},
|
||||
{0x194, "IVOR4", 0x0000fff0, 0x00000500},
|
||||
{0x195, "IVOR5", 0x0000fff0, 0x00000600},
|
||||
{0x196, "IVOR6", 0x0000fff0, 0x00000700},
|
||||
{0x197, "IVOR7", 0x0000fff0, 0x00000800},
|
||||
{0x198, "IVOR8", 0x0000fff0, 0x00000c00},
|
||||
{0x199, "IVOR9", 0x00000000, 0x00000000},
|
||||
{0x19a, "IVOR10", 0x0000fff0, 0x00000900},
|
||||
{0x19b, "IVOR11", 0x00000000, 0x00000000},
|
||||
{0x19c, "IVOR12", 0x00000000, 0x00000000},
|
||||
{0x19d, "IVOR13", 0x0000fff0, 0x00001300},
|
||||
{0x19e, "IVOR14", 0x0000fff0, 0x00001400},
|
||||
{0x19f, "IVOR15", 0x0000fff0, 0x00002000},
|
||||
#endif
|
||||
{0x23a, "MCSRR0", 0x00000000, 0x00000000},
|
||||
{0x23b, "MCSRR1", 0x00000000, 0x00000000},
|
||||
{0x23c, "MCSR", 0x00000000, 0x00000000},
|
||||
{0x370, "INV0", 0x00000000, 0x00000000},
|
||||
{0x371, "INV1", 0x00000000, 0x00000000},
|
||||
{0x372, "INV2", 0x00000000, 0x00000000},
|
||||
{0x373, "INV3", 0x00000000, 0x00000000},
|
||||
{0x374, "ITV0", 0x00000000, 0x00000000},
|
||||
{0x375, "ITV1", 0x00000000, 0x00000000},
|
||||
{0x376, "ITV2", 0x00000000, 0x00000000},
|
||||
{0x377, "ITV3", 0x00000000, 0x00000000},
|
||||
{0x378, "CCR1", 0x00000000, 0x00000000},
|
||||
{0x390, "DNV0", 0x00000000, 0x00000000},
|
||||
{0x391, "DNV1", 0x00000000, 0x00000000},
|
||||
{0x392, "DNV2", 0x00000000, 0x00000000},
|
||||
{0x393, "DNV3", 0x00000000, 0x00000000},
|
||||
{0x394, "DTV0", 0x00000000, 0x00000000},
|
||||
{0x395, "DTV1", 0x00000000, 0x00000000},
|
||||
{0x396, "DTV2", 0x00000000, 0x00000000},
|
||||
{0x397, "DTV3", 0x00000000, 0x00000000},
|
||||
#ifdef CONFIG_440
|
||||
{0x398, "DVLIM", 0x0fc1f83f, 0x0001f800},
|
||||
{0x399, "IVLIM", 0x0fc1f83f, 0x0001f800},
|
||||
#endif
|
||||
{0x39b, "RSTCFG", 0x00000000, 0x00000000},
|
||||
{0x39c, "DCDBTRL", 0x00000000, 0x00000000},
|
||||
{0x39d, "DCDBTRH", 0x00000000, 0x00000000},
|
||||
{0x39e, "ICDBTRL", 0x00000000, 0x00000000},
|
||||
{0x39f, "ICDBTRH", 0x00000000, 0x00000000},
|
||||
{0x3b2, "MMUCR", 0x00000000, 0x00000000},
|
||||
{0x3b3, "CCR0", 0x00000000, 0x00000000},
|
||||
{0x3d3, "ICDBDR", 0x00000000, 0x00000000},
|
||||
{0x3f3, "DBDR", 0x00000000, 0x00000000},
|
||||
};
|
||||
|
||||
static int spr_test_list_size = ARRAY_SIZE(spr_test_list);
|
||||
|
||||
int spr_post_test (int flags)
|
||||
{
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
unsigned long code[] = {
|
||||
0x7c6002a6, /* mfspr r3,SPR */
|
||||
0x4e800020 /* blr */
|
||||
};
|
||||
unsigned long (*get_spr) (void) = (void *) code;
|
||||
|
||||
#ifdef CONFIG_4xx_DCACHE
|
||||
/* disable cache */
|
||||
change_tlb(gd->bd->bi_memstart, gd->bd->bi_memsize, TLB_WORD2_I_ENABLE);
|
||||
#endif
|
||||
for (i = 0; i < spr_test_list_size; i++) {
|
||||
int num = spr_test_list[i].number;
|
||||
|
||||
/* mfspr r3,num */
|
||||
code[0] = 0x7c6002a6 | ((num & 0x1F) << 16) | ((num & 0x3E0) << 6);
|
||||
|
||||
asm volatile ("isync");
|
||||
|
||||
if ((get_spr () & spr_test_list[i].mask) !=
|
||||
(spr_test_list[i].value & spr_test_list[i].mask)) {
|
||||
post_log ("The value of %s special register "
|
||||
"is incorrect: 0x%08X\n",
|
||||
spr_test_list[i].name, get_spr ());
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_4xx_DCACHE
|
||||
/* enable cache */
|
||||
change_tlb(gd->bd->bi_memstart, gd->bd->bi_memsize, 0);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_SPR */
|
||||
108
common/package/boot/uboot-ipq40xx/src/post/cpu/ppc4xx/uart.c
Normal file
108
common/package/boot/uboot-ipq40xx/src/post/cpu/ppc4xx/uart.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* Author: Igor Lisitsin <igor@emcraft.com>
|
||||
*
|
||||
* Copyright 2010, Stefan Roese, DENX Software Engineering, sr@denx.de
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/ppc4xx.h>
|
||||
#include <ns16550.h>
|
||||
#include <asm/io.h>
|
||||
#include <serial.h>
|
||||
|
||||
/*
|
||||
* UART test
|
||||
*
|
||||
* The controllers are configured to loopback mode and several
|
||||
* characters are transmitted.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_UART
|
||||
|
||||
/*
|
||||
* This table defines the UART's that should be tested and can
|
||||
* be overridden in the board config file
|
||||
*/
|
||||
#ifndef CONFIG_SYS_POST_UART_TABLE
|
||||
#define CONFIG_SYS_POST_UART_TABLE { CONFIG_SYS_NS16550_COM1, \
|
||||
CONFIG_SYS_NS16550_COM2, CONFIG_SYS_NS16550_COM3, \
|
||||
CONFIG_SYS_NS16550_COM4 }
|
||||
#endif
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static int test_ctlr (struct NS16550 *com_port, int index)
|
||||
{
|
||||
int res = -1;
|
||||
char test_str[] = "*** UART Test String ***\r\n";
|
||||
int i;
|
||||
int divisor;
|
||||
|
||||
divisor = (get_serial_clock() + (gd->baudrate * (16 / 2))) /
|
||||
(16 * gd->baudrate);
|
||||
NS16550_init(com_port, divisor);
|
||||
|
||||
/*
|
||||
* Set internal loopback mode in UART
|
||||
*/
|
||||
out_8(&com_port->mcr, in_8(&com_port->mcr) | UART_MCR_LOOP);
|
||||
|
||||
/* Reset FIFOs */
|
||||
out_8(&com_port->fcr, UART_FCR_RXSR | UART_FCR_TXSR);
|
||||
udelay(100);
|
||||
|
||||
/* Flush RX-FIFO */
|
||||
while (NS16550_tstc(com_port))
|
||||
NS16550_getc(com_port);
|
||||
|
||||
for (i = 0; i < sizeof (test_str) - 1; i++) {
|
||||
NS16550_putc(com_port, test_str[i]);
|
||||
if (NS16550_getc(com_port) != test_str[i])
|
||||
goto done;
|
||||
}
|
||||
res = 0;
|
||||
done:
|
||||
if (res)
|
||||
post_log ("uart%d test failed\n", index);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int uart_post_test (int flags)
|
||||
{
|
||||
int i, res = 0;
|
||||
static unsigned long base[] = CONFIG_SYS_POST_UART_TABLE;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(base); i++) {
|
||||
if (test_ctlr((struct NS16550 *)base[i], i))
|
||||
res = -1;
|
||||
}
|
||||
serial_reinit_all ();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_UART */
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* Author: Igor Lisitsin <igor@emcraft.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* Watchdog test
|
||||
*
|
||||
* The test verifies the watchdog timer operation.
|
||||
* On the first iteration, the test routine disables interrupts and
|
||||
* makes a 10-second delay. If the system does not reboot during this delay,
|
||||
* the watchdog timer is not operational and the test fails. If the system
|
||||
* reboots, on the second iteration the test routine reports a success.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_WATCHDOG
|
||||
|
||||
#include <watchdog.h>
|
||||
|
||||
int watchdog_post_test (int flags)
|
||||
{
|
||||
if (flags & POST_REBOOT) {
|
||||
/* Test passed */
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
/* 10-second delay */
|
||||
int ints = disable_interrupts ();
|
||||
ulong base = post_time_ms (0);
|
||||
|
||||
while (post_time_ms (base) < 10000)
|
||||
;
|
||||
if (ints)
|
||||
enable_interrupts ();
|
||||
|
||||
/*
|
||||
* If we have reached this point, the watchdog timer
|
||||
* does not work
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_WATCHDOG */
|
||||
29
common/package/boot/uboot-ipq40xx/src/post/drivers/Makefile
Normal file
29
common/package/boot/uboot-ipq40xx/src/post/drivers/Makefile
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#
|
||||
# (C) Copyright 2002-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = libpostdrivers.o
|
||||
|
||||
COBJS-$(CONFIG_HAS_POST) += flash.o i2c.o memory.o rtc.o
|
||||
|
||||
include $(TOPDIR)/post/rules.mk
|
||||
107
common/package/boot/uboot-ipq40xx/src/post/drivers/flash.c
Normal file
107
common/package/boot/uboot-ipq40xx/src/post/drivers/flash.c
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Parallel NOR Flash tests
|
||||
*
|
||||
* Copyright (c) 2005-2011 Analog Devices Inc.
|
||||
*
|
||||
* Licensed under the GPL-2 or later.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <post.h>
|
||||
#include <flash.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_FLASH
|
||||
|
||||
/*
|
||||
* This code will walk over the declared sectors erasing them,
|
||||
* then programming them, then verifying the written contents.
|
||||
* Possible future work:
|
||||
* - verify sectors before/after are not erased/written
|
||||
* - verify partial writes (e.g. programming only middle of sector)
|
||||
* - verify the contents of the erased sector
|
||||
* - better seed pattern than 0x00..0xff
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_SYS_POST_FLASH_NUM
|
||||
# define CONFIG_SYS_POST_FLASH_NUM 0
|
||||
#endif
|
||||
#if CONFIG_SYS_POST_FLASH_START >= CONFIG_SYS_POST_FLASH_END
|
||||
# error "invalid flash block start/end"
|
||||
#endif
|
||||
|
||||
extern flash_info_t flash_info[];
|
||||
|
||||
static void *seed_src_data(void *ptr, ulong *old_len, ulong new_len)
|
||||
{
|
||||
unsigned char *p;
|
||||
ulong i;
|
||||
|
||||
p = ptr = realloc(ptr, new_len);
|
||||
if (!ptr)
|
||||
return ptr;
|
||||
|
||||
for (i = *old_len; i < new_len; ++i)
|
||||
p[i] = i;
|
||||
|
||||
*old_len = new_len;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int flash_post_test(int flags)
|
||||
{
|
||||
ulong len;
|
||||
void *src;
|
||||
int ret, n, n_start, n_end;
|
||||
flash_info_t *info;
|
||||
|
||||
/* the output from the common flash layers needs help */
|
||||
puts("\n");
|
||||
|
||||
len = 0;
|
||||
src = NULL;
|
||||
info = &flash_info[CONFIG_SYS_POST_FLASH_NUM];
|
||||
n_start = CONFIG_SYS_POST_FLASH_START;
|
||||
n_end = CONFIG_SYS_POST_FLASH_END;
|
||||
|
||||
for (n = n_start; n < n_end; ++n) {
|
||||
ulong s_start, s_len, s_off;
|
||||
|
||||
s_start = info->start[n];
|
||||
s_len = flash_sector_size(info, n);
|
||||
s_off = s_start - info->start[0];
|
||||
|
||||
src = seed_src_data(src, &len, s_len);
|
||||
if (!src) {
|
||||
printf("malloc(%#lx) failed\n", s_len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("\tsector %i: %#lx +%#lx", n, s_start, s_len);
|
||||
|
||||
ret = flash_erase(info, n, n + 1);
|
||||
if (ret) {
|
||||
flash_perror(ret);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = write_buff(info, src, s_start, s_len);
|
||||
if (ret) {
|
||||
flash_perror(ret);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = memcmp(src, (void *)s_start, s_len);
|
||||
if (ret) {
|
||||
printf(" verify failed with %i\n", ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(src);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
111
common/package/boot/uboot-ipq40xx/src/post/drivers/i2c.c
Normal file
111
common/package/boot/uboot-ipq40xx/src/post/drivers/i2c.c
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* I2C test
|
||||
*
|
||||
* For verifying the I2C bus, a full I2C bus scanning is performed.
|
||||
*
|
||||
* #ifdef CONFIG_SYS_POST_I2C_ADDRS
|
||||
* The test is considered as passed if all the devices and only the devices
|
||||
* in the list are found.
|
||||
* #ifdef CONFIG_SYS_POST_I2C_IGNORES
|
||||
* Ignore devices listed in CONFIG_SYS_POST_I2C_IGNORES. These devices
|
||||
* are optional or not vital to board functionality.
|
||||
* #endif
|
||||
* #else [ ! CONFIG_SYS_POST_I2C_ADDRS ]
|
||||
* The test is considered as passed if any I2C device is found.
|
||||
* #endif
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <post.h>
|
||||
#include <i2c.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_I2C
|
||||
|
||||
static int i2c_ignore_device(unsigned int chip)
|
||||
{
|
||||
#ifdef CONFIG_SYS_POST_I2C_IGNORES
|
||||
const unsigned char i2c_ignore_list[] = CONFIG_SYS_POST_I2C_IGNORES;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(i2c_ignore_list); i++)
|
||||
if (i2c_ignore_list[i] == chip)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_post_test (int flags)
|
||||
{
|
||||
unsigned int i;
|
||||
#ifndef CONFIG_SYS_POST_I2C_ADDRS
|
||||
/* Start at address 1, address 0 is the general call address */
|
||||
for (i = 1; i < 128; i++) {
|
||||
if (i2c_ignore_device(i))
|
||||
continue;
|
||||
if (i2c_probe (i) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* No devices found */
|
||||
return -1;
|
||||
#else
|
||||
unsigned int ret = 0;
|
||||
int j;
|
||||
unsigned char i2c_addr_list[] = CONFIG_SYS_POST_I2C_ADDRS;
|
||||
|
||||
/* Start at address 1, address 0 is the general call address */
|
||||
for (i = 1; i < 128; i++) {
|
||||
if (i2c_ignore_device(i))
|
||||
continue;
|
||||
if (i2c_probe(i) != 0)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < sizeof(i2c_addr_list); ++j) {
|
||||
if (i == i2c_addr_list[j]) {
|
||||
i2c_addr_list[j] = 0xff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == sizeof(i2c_addr_list)) {
|
||||
ret = -1;
|
||||
post_log("I2C: addr %02x not expected\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(i2c_addr_list); ++i) {
|
||||
if (i2c_addr_list[i] == 0xff)
|
||||
continue;
|
||||
post_log("I2C: addr %02x did not respond\n", i2c_addr_list[i]);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_I2C */
|
||||
566
common/package/boot/uboot-ipq40xx/src/post/drivers/memory.c
Normal file
566
common/package/boot/uboot-ipq40xx/src/post/drivers/memory.c
Normal file
|
|
@ -0,0 +1,566 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/* Memory test
|
||||
*
|
||||
* General observations:
|
||||
* o The recommended test sequence is to test the data lines: if they are
|
||||
* broken, nothing else will work properly. Then test the address
|
||||
* lines. Finally, test the cells in the memory now that the test
|
||||
* program knows that the address and data lines work properly.
|
||||
* This sequence also helps isolate and identify what is faulty.
|
||||
*
|
||||
* o For the address line test, it is a good idea to use the base
|
||||
* address of the lowest memory location, which causes a '1' bit to
|
||||
* walk through a field of zeros on the address lines and the highest
|
||||
* memory location, which causes a '0' bit to walk through a field of
|
||||
* '1's on the address line.
|
||||
*
|
||||
* o Floating buses can fool memory tests if the test routine writes
|
||||
* a value and then reads it back immediately. The problem is, the
|
||||
* write will charge the residual capacitance on the data bus so the
|
||||
* bus retains its state briefely. When the test program reads the
|
||||
* value back immediately, the capacitance of the bus can allow it
|
||||
* to read back what was written, even though the memory circuitry
|
||||
* is broken. To avoid this, the test program should write a test
|
||||
* pattern to the target location, write a different pattern elsewhere
|
||||
* to charge the residual capacitance in a differnt manner, then read
|
||||
* the target location back.
|
||||
*
|
||||
* o Always read the target location EXACTLY ONCE and save it in a local
|
||||
* variable. The problem with reading the target location more than
|
||||
* once is that the second and subsequent reads may work properly,
|
||||
* resulting in a failed test that tells the poor technician that
|
||||
* "Memory error at 00000000, wrote aaaaaaaa, read aaaaaaaa" which
|
||||
* doesn't help him one bit and causes puzzled phone calls. Been there,
|
||||
* done that.
|
||||
*
|
||||
* Data line test:
|
||||
* ---------------
|
||||
* This tests data lines for shorts and opens by forcing adjacent data
|
||||
* to opposite states. Because the data lines could be routed in an
|
||||
* arbitrary manner the must ensure test patterns ensure that every case
|
||||
* is tested. By using the following series of binary patterns every
|
||||
* combination of adjacent bits is test regardless of routing.
|
||||
*
|
||||
* ...101010101010101010101010
|
||||
* ...110011001100110011001100
|
||||
* ...111100001111000011110000
|
||||
* ...111111110000000011111111
|
||||
*
|
||||
* Carrying this out, gives us six hex patterns as follows:
|
||||
*
|
||||
* 0xaaaaaaaaaaaaaaaa
|
||||
* 0xcccccccccccccccc
|
||||
* 0xf0f0f0f0f0f0f0f0
|
||||
* 0xff00ff00ff00ff00
|
||||
* 0xffff0000ffff0000
|
||||
* 0xffffffff00000000
|
||||
*
|
||||
* To test for short and opens to other signals on our boards, we
|
||||
* simply test with the 1's complemnt of the paterns as well, resulting
|
||||
* in twelve patterns total.
|
||||
*
|
||||
* After writing a test pattern. a special pattern 0x0123456789ABCDEF is
|
||||
* written to a different address in case the data lines are floating.
|
||||
* Thus, if a byte lane fails, you will see part of the special
|
||||
* pattern in that byte lane when the test runs. For example, if the
|
||||
* xx__xxxxxxxxxxxx byte line fails, you will see aa23aaaaaaaaaaaa
|
||||
* (for the 'a' test pattern).
|
||||
*
|
||||
* Address line test:
|
||||
* ------------------
|
||||
* This function performs a test to verify that all the address lines
|
||||
* hooked up to the RAM work properly. If there is an address line
|
||||
* fault, it usually shows up as two different locations in the address
|
||||
* map (related by the faulty address line) mapping to one physical
|
||||
* memory storage location. The artifact that shows up is writing to
|
||||
* the first location "changes" the second location.
|
||||
*
|
||||
* To test all address lines, we start with the given base address and
|
||||
* xor the address with a '1' bit to flip one address line. For each
|
||||
* test, we shift the '1' bit left to test the next address line.
|
||||
*
|
||||
* In the actual code, we start with address sizeof(ulong) since our
|
||||
* test pattern we use is a ulong and thus, if we tried to test lower
|
||||
* order address bits, it wouldn't work because our pattern would
|
||||
* overwrite itself.
|
||||
*
|
||||
* Example for a 4 bit address space with the base at 0000:
|
||||
* 0000 <- base
|
||||
* 0001 <- test 1
|
||||
* 0010 <- test 2
|
||||
* 0100 <- test 3
|
||||
* 1000 <- test 4
|
||||
* Example for a 4 bit address space with the base at 0010:
|
||||
* 0010 <- base
|
||||
* 0011 <- test 1
|
||||
* 0000 <- (below the base address, skipped)
|
||||
* 0110 <- test 2
|
||||
* 1010 <- test 3
|
||||
*
|
||||
* The test locations are successively tested to make sure that they are
|
||||
* not "mirrored" onto the base address due to a faulty address line.
|
||||
* Note that the base and each test location are related by one address
|
||||
* line flipped. Note that the base address need not be all zeros.
|
||||
*
|
||||
* Memory tests 1-4:
|
||||
* -----------------
|
||||
* These tests verify RAM using sequential writes and reads
|
||||
* to/from RAM. There are several test cases that use different patterns to
|
||||
* verify RAM. Each test case fills a region of RAM with one pattern and
|
||||
* then reads the region back and compares its contents with the pattern.
|
||||
* The following patterns are used:
|
||||
*
|
||||
* 1a) zero pattern (0x00000000)
|
||||
* 1b) negative pattern (0xffffffff)
|
||||
* 1c) checkerboard pattern (0x55555555)
|
||||
* 1d) checkerboard pattern (0xaaaaaaaa)
|
||||
* 2) bit-flip pattern ((1 << (offset % 32))
|
||||
* 3) address pattern (offset)
|
||||
* 4) address pattern (~offset)
|
||||
*
|
||||
* Being run in normal mode, the test verifies only small 4Kb
|
||||
* regions of RAM around each 1Mb boundary. For example, for 64Mb
|
||||
* RAM the following areas are verified: 0x00000000-0x00000800,
|
||||
* 0x000ff800-0x00100800, 0x001ff800-0x00200800, ..., 0x03fff800-
|
||||
* 0x04000000. If the test is run in slow-test mode, it verifies
|
||||
* the whole RAM.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include <watchdog.h>
|
||||
|
||||
#if CONFIG_POST & (CONFIG_SYS_POST_MEMORY | CONFIG_SYS_POST_MEM_REGIONS)
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/*
|
||||
* Define INJECT_*_ERRORS for testing error detection in the presence of
|
||||
* _good_ hardware.
|
||||
*/
|
||||
#undef INJECT_DATA_ERRORS
|
||||
#undef INJECT_ADDRESS_ERRORS
|
||||
|
||||
#ifdef INJECT_DATA_ERRORS
|
||||
#warning "Injecting data line errors for testing purposes"
|
||||
#endif
|
||||
|
||||
#ifdef INJECT_ADDRESS_ERRORS
|
||||
#warning "Injecting address line errors for testing purposes"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* This function performs a double word move from the data at
|
||||
* the source pointer to the location at the destination pointer.
|
||||
* This is helpful for testing memory on processors which have a 64 bit
|
||||
* wide data bus.
|
||||
*
|
||||
* On those PowerPC with FPU, use assembly and a floating point move:
|
||||
* this does a 64 bit move.
|
||||
*
|
||||
* For other processors, let the compiler generate the best code it can.
|
||||
*/
|
||||
static void move64(const unsigned long long *src, unsigned long long *dest)
|
||||
{
|
||||
#if defined(CONFIG_MPC8260) || defined(CONFIG_MPC824X)
|
||||
asm ("lfd 0, 0(3)\n\t" /* fpr0 = *scr */
|
||||
"stfd 0, 0(4)" /* *dest = fpr0 */
|
||||
: : : "fr0" ); /* Clobbers fr0 */
|
||||
return;
|
||||
#else
|
||||
*dest = *src;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* This is 64 bit wide test patterns. Note that they reside in ROM
|
||||
* (which presumably works) and the tests write them to RAM which may
|
||||
* not work.
|
||||
*
|
||||
* The "otherpattern" is written to drive the data bus to values other
|
||||
* than the test pattern. This is for detecting floating bus lines.
|
||||
*
|
||||
*/
|
||||
const static unsigned long long pattern[] = {
|
||||
0xaaaaaaaaaaaaaaaaULL,
|
||||
0xccccccccccccccccULL,
|
||||
0xf0f0f0f0f0f0f0f0ULL,
|
||||
0xff00ff00ff00ff00ULL,
|
||||
0xffff0000ffff0000ULL,
|
||||
0xffffffff00000000ULL,
|
||||
0x00000000ffffffffULL,
|
||||
0x0000ffff0000ffffULL,
|
||||
0x00ff00ff00ff00ffULL,
|
||||
0x0f0f0f0f0f0f0f0fULL,
|
||||
0x3333333333333333ULL,
|
||||
0x5555555555555555ULL
|
||||
};
|
||||
const unsigned long long otherpattern = 0x0123456789abcdefULL;
|
||||
|
||||
|
||||
static int memory_post_dataline(unsigned long long * pmem)
|
||||
{
|
||||
unsigned long long temp64 = 0;
|
||||
int num_patterns = ARRAY_SIZE(pattern);
|
||||
int i;
|
||||
unsigned int hi, lo, pathi, patlo;
|
||||
int ret = 0;
|
||||
|
||||
for ( i = 0; i < num_patterns; i++) {
|
||||
move64(&(pattern[i]), pmem++);
|
||||
/*
|
||||
* Put a different pattern on the data lines: otherwise they
|
||||
* may float long enough to read back what we wrote.
|
||||
*/
|
||||
move64(&otherpattern, pmem--);
|
||||
move64(pmem, &temp64);
|
||||
|
||||
#ifdef INJECT_DATA_ERRORS
|
||||
temp64 ^= 0x00008000;
|
||||
#endif
|
||||
|
||||
if (temp64 != pattern[i]){
|
||||
pathi = (pattern[i]>>32) & 0xffffffff;
|
||||
patlo = pattern[i] & 0xffffffff;
|
||||
|
||||
hi = (temp64>>32) & 0xffffffff;
|
||||
lo = temp64 & 0xffffffff;
|
||||
|
||||
post_log("Memory (date line) error at %08x, "
|
||||
"wrote %08x%08x, read %08x%08x !\n",
|
||||
pmem, pathi, patlo, hi, lo);
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int memory_post_addrline(ulong *testaddr, ulong *base, ulong size)
|
||||
{
|
||||
ulong *target;
|
||||
ulong *end;
|
||||
ulong readback;
|
||||
ulong xor;
|
||||
int ret = 0;
|
||||
|
||||
end = (ulong *)((ulong)base + size); /* pointer arith! */
|
||||
xor = 0;
|
||||
for(xor = sizeof(ulong); xor > 0; xor <<= 1) {
|
||||
target = (ulong *)((ulong)testaddr ^ xor);
|
||||
if((target >= base) && (target < end)) {
|
||||
*testaddr = ~*target;
|
||||
readback = *target;
|
||||
|
||||
#ifdef INJECT_ADDRESS_ERRORS
|
||||
if(xor == 0x00008000) {
|
||||
readback = *testaddr;
|
||||
}
|
||||
#endif
|
||||
if(readback == *testaddr) {
|
||||
post_log("Memory (address line) error at %08x<->%08x, "
|
||||
"XOR value %08x !\n",
|
||||
testaddr, target, xor);
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int memory_post_test1(unsigned long start,
|
||||
unsigned long size,
|
||||
unsigned long val)
|
||||
{
|
||||
unsigned long i;
|
||||
ulong *mem = (ulong *) start;
|
||||
ulong readback;
|
||||
int ret = 0;
|
||||
|
||||
for (i = 0; i < size / sizeof (ulong); i++) {
|
||||
mem[i] = val;
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
for (i = 0; i < size / sizeof (ulong) && !ret; i++) {
|
||||
readback = mem[i];
|
||||
if (readback != val) {
|
||||
post_log("Memory error at %08x, "
|
||||
"wrote %08x, read %08x !\n",
|
||||
mem + i, val, readback);
|
||||
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int memory_post_test2(unsigned long start, unsigned long size)
|
||||
{
|
||||
unsigned long i;
|
||||
ulong *mem = (ulong *) start;
|
||||
ulong readback;
|
||||
int ret = 0;
|
||||
|
||||
for (i = 0; i < size / sizeof (ulong); i++) {
|
||||
mem[i] = 1 << (i % 32);
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
for (i = 0; i < size / sizeof (ulong) && !ret; i++) {
|
||||
readback = mem[i];
|
||||
if (readback != (1 << (i % 32))) {
|
||||
post_log("Memory error at %08x, "
|
||||
"wrote %08x, read %08x !\n",
|
||||
mem + i, 1 << (i % 32), readback);
|
||||
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int memory_post_test3(unsigned long start, unsigned long size)
|
||||
{
|
||||
unsigned long i;
|
||||
ulong *mem = (ulong *) start;
|
||||
ulong readback;
|
||||
int ret = 0;
|
||||
|
||||
for (i = 0; i < size / sizeof (ulong); i++) {
|
||||
mem[i] = i;
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
for (i = 0; i < size / sizeof (ulong) && !ret; i++) {
|
||||
readback = mem[i];
|
||||
if (readback != i) {
|
||||
post_log("Memory error at %08x, "
|
||||
"wrote %08x, read %08x !\n",
|
||||
mem + i, i, readback);
|
||||
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int memory_post_test4(unsigned long start, unsigned long size)
|
||||
{
|
||||
unsigned long i;
|
||||
ulong *mem = (ulong *) start;
|
||||
ulong readback;
|
||||
int ret = 0;
|
||||
|
||||
for (i = 0; i < size / sizeof (ulong); i++) {
|
||||
mem[i] = ~i;
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
for (i = 0; i < size / sizeof (ulong) && !ret; i++) {
|
||||
readback = mem[i];
|
||||
if (readback != ~i) {
|
||||
post_log("Memory error at %08x, "
|
||||
"wrote %08x, read %08x !\n",
|
||||
mem + i, ~i, readback);
|
||||
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
if (i % 1024 == 0)
|
||||
WATCHDOG_RESET();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int memory_post_test_lines(unsigned long start, unsigned long size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = memory_post_dataline((unsigned long long *)start);
|
||||
WATCHDOG_RESET();
|
||||
if (!ret)
|
||||
ret = memory_post_addrline((ulong *)start, (ulong *)start,
|
||||
size);
|
||||
WATCHDOG_RESET();
|
||||
if (!ret)
|
||||
ret = memory_post_addrline((ulong *)(start+size-8),
|
||||
(ulong *)start, size);
|
||||
WATCHDOG_RESET();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int memory_post_test_patterns(unsigned long start, unsigned long size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = memory_post_test1(start, size, 0x00000000);
|
||||
WATCHDOG_RESET();
|
||||
if (!ret)
|
||||
ret = memory_post_test1(start, size, 0xffffffff);
|
||||
WATCHDOG_RESET();
|
||||
if (!ret)
|
||||
ret = memory_post_test1(start, size, 0x55555555);
|
||||
WATCHDOG_RESET();
|
||||
if (!ret)
|
||||
ret = memory_post_test1(start, size, 0xaaaaaaaa);
|
||||
WATCHDOG_RESET();
|
||||
if (!ret)
|
||||
ret = memory_post_test2(start, size);
|
||||
WATCHDOG_RESET();
|
||||
if (!ret)
|
||||
ret = memory_post_test3(start, size);
|
||||
WATCHDOG_RESET();
|
||||
if (!ret)
|
||||
ret = memory_post_test4(start, size);
|
||||
WATCHDOG_RESET();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int memory_post_test_regions(unsigned long start, unsigned long size)
|
||||
{
|
||||
unsigned long i;
|
||||
int ret = 0;
|
||||
|
||||
for (i = 0; i < (size >> 20) && (!ret); i++) {
|
||||
if (!ret)
|
||||
ret = memory_post_test_patterns(start + (i << 20),
|
||||
0x800);
|
||||
if (!ret)
|
||||
ret = memory_post_test_patterns(start + (i << 20) +
|
||||
0xff800, 0x800);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int memory_post_tests(unsigned long start, unsigned long size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = memory_post_test_lines(start, size);
|
||||
if (!ret)
|
||||
ret = memory_post_test_patterns(start, size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* !! this is only valid, if you have contiguous memory banks !!
|
||||
*/
|
||||
__attribute__((weak))
|
||||
int arch_memory_test_prepare(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
|
||||
{
|
||||
bd_t *bd = gd->bd;
|
||||
|
||||
*vstart = CONFIG_SYS_SDRAM_BASE;
|
||||
*size = (gd->ram_size >= 256 << 20 ?
|
||||
256 << 20 : gd->ram_size) - (1 << 20);
|
||||
|
||||
/* Limit area to be tested with the board info struct */
|
||||
if ((*vstart) + (*size) > (ulong)bd)
|
||||
*size = (ulong)bd - *vstart;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__((weak))
|
||||
int arch_memory_test_advance(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__attribute__((weak))
|
||||
int arch_memory_test_cleanup(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__((weak))
|
||||
void arch_memory_failure_handle(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int memory_regions_post_test(int flags)
|
||||
{
|
||||
int ret = 0;
|
||||
phys_addr_t phys_offset = 0;
|
||||
u32 memsize, vstart;
|
||||
|
||||
arch_memory_test_prepare(&vstart, &memsize, &phys_offset);
|
||||
|
||||
ret = memory_post_test_lines(vstart, memsize);
|
||||
if (!ret)
|
||||
ret = memory_post_test_regions(vstart, memsize);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int memory_post_test(int flags)
|
||||
{
|
||||
int ret = 0;
|
||||
phys_addr_t phys_offset = 0;
|
||||
u32 memsize, vstart;
|
||||
|
||||
arch_memory_test_prepare(&vstart, &memsize, &phys_offset);
|
||||
|
||||
do {
|
||||
if (flags & POST_SLOWTEST) {
|
||||
ret = memory_post_tests(vstart, memsize);
|
||||
} else { /* POST_NORMAL */
|
||||
ret = memory_post_test_regions(vstart, memsize);
|
||||
}
|
||||
} while (!ret &&
|
||||
!arch_memory_test_advance(&vstart, &memsize, &phys_offset));
|
||||
|
||||
arch_memory_test_cleanup(&vstart, &memsize, &phys_offset);
|
||||
if (ret)
|
||||
arch_memory_failure_handle();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST&(CONFIG_SYS_POST_MEMORY|CONFIG_SYS_POST_MEM_REGIONS) */
|
||||
195
common/package/boot/uboot-ipq40xx/src/post/drivers/rtc.c
Normal file
195
common/package/boot/uboot-ipq40xx/src/post/drivers/rtc.c
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* RTC test
|
||||
*
|
||||
* The Real Time Clock (RTC) operation is verified by this test.
|
||||
* The following features are verified:
|
||||
* o) RTC Power Fault
|
||||
* This is verified by analyzing the rtc_get() return status.
|
||||
* o) Time uniformity
|
||||
* This is verified by reading RTC in polling within
|
||||
* a short period of time.
|
||||
* o) Passing month boundaries
|
||||
* This is checked by setting RTC to a second before
|
||||
* a month boundary and reading it after its passing the
|
||||
* boundary. The test is performed for both leap- and
|
||||
* nonleap-years.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include <rtc.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_RTC
|
||||
|
||||
static int rtc_post_skip (ulong * diff)
|
||||
{
|
||||
struct rtc_time tm1;
|
||||
struct rtc_time tm2;
|
||||
ulong start1;
|
||||
ulong start2;
|
||||
|
||||
rtc_get (&tm1);
|
||||
start1 = get_timer (0);
|
||||
|
||||
while (1) {
|
||||
rtc_get (&tm2);
|
||||
start2 = get_timer (0);
|
||||
if (tm1.tm_sec != tm2.tm_sec)
|
||||
break;
|
||||
if (start2 - start1 > 1500)
|
||||
break;
|
||||
}
|
||||
|
||||
if (tm1.tm_sec != tm2.tm_sec) {
|
||||
*diff = start2 - start1;
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void rtc_post_restore (struct rtc_time *tm, unsigned int sec)
|
||||
{
|
||||
time_t t = mktime (tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour,
|
||||
tm->tm_min, tm->tm_sec) + sec;
|
||||
struct rtc_time ntm;
|
||||
|
||||
to_tm (t, &ntm);
|
||||
|
||||
rtc_set (&ntm);
|
||||
}
|
||||
|
||||
int rtc_post_test (int flags)
|
||||
{
|
||||
ulong diff;
|
||||
unsigned int i;
|
||||
struct rtc_time svtm;
|
||||
static unsigned int daysnl[] =
|
||||
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
static unsigned int daysl[] =
|
||||
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
unsigned int ynl = 1999;
|
||||
unsigned int yl = 2000;
|
||||
unsigned int skipped = 0;
|
||||
int reliable;
|
||||
|
||||
/* Time reliability */
|
||||
reliable = rtc_get (&svtm);
|
||||
|
||||
/* Time uniformity */
|
||||
if (rtc_post_skip (&diff) != 0) {
|
||||
post_log ("Timeout while waiting for a new second !\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (rtc_post_skip (&diff) != 0) {
|
||||
post_log ("Timeout while waiting for a new second !\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (diff < 950 || diff > 1050) {
|
||||
post_log ("Invalid second duration !\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Passing month boundaries */
|
||||
|
||||
if (rtc_post_skip (&diff) != 0) {
|
||||
post_log ("Timeout while waiting for a new second !\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
rtc_get (&svtm);
|
||||
|
||||
for (i = 0; i < 12; i++) {
|
||||
time_t t = mktime (ynl, i + 1, daysnl[i], 23, 59, 59);
|
||||
struct rtc_time tm;
|
||||
|
||||
to_tm (t, &tm);
|
||||
rtc_set (&tm);
|
||||
|
||||
skipped++;
|
||||
if (rtc_post_skip (&diff) != 0) {
|
||||
rtc_post_restore (&svtm, skipped);
|
||||
post_log ("Timeout while waiting for a new second !\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
rtc_get (&tm);
|
||||
if (tm.tm_mon == i + 1) {
|
||||
rtc_post_restore (&svtm, skipped);
|
||||
post_log ("Month %d boundary is not passed !\n", i + 1);
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 12; i++) {
|
||||
time_t t = mktime (yl, i + 1, daysl[i], 23, 59, 59);
|
||||
struct rtc_time tm;
|
||||
|
||||
to_tm (t, &tm);
|
||||
rtc_set (&tm);
|
||||
|
||||
skipped++;
|
||||
if (rtc_post_skip (&diff) != 0) {
|
||||
rtc_post_restore (&svtm, skipped);
|
||||
post_log ("Timeout while waiting for a new second !\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
rtc_get (&tm);
|
||||
if (tm.tm_mon == i + 1) {
|
||||
rtc_post_restore (&svtm, skipped);
|
||||
post_log ("Month %d boundary is not passed !\n", i + 1);
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
rtc_post_restore (&svtm, skipped);
|
||||
|
||||
/* If come here, then RTC operates correcty, check the correctness
|
||||
* of the time it reports.
|
||||
*/
|
||||
if (reliable < 0) {
|
||||
post_log ("RTC Time is not reliable! Power fault? \n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_RTC */
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
#
|
||||
# (C) Copyright 2002-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = libpost$(ARCH).o
|
||||
|
||||
AOBJS-$(CONFIG_HAS_POST) += asm.o
|
||||
COBJS-$(CONFIG_HAS_POST) += cpu.o cmp.o cmpi.o two.o twox.o three.o threex.o
|
||||
COBJS-$(CONFIG_HAS_POST) += threei.o andi.o srawi.o rlwnm.o rlwinm.o rlwimi.o
|
||||
COBJS-$(CONFIG_HAS_POST) += store.o load.o cr.o b.o multi.o string.o complex.o
|
||||
|
||||
include $(TOPDIR)/post/rules.mk
|
||||
119
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/andi.c
Normal file
119
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/andi.c
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Logic instructions: andi., andis.
|
||||
*
|
||||
* The test contains a pre-built table of instructions, operands and
|
||||
* expected results. For each table entry, the test will cyclically use
|
||||
* different sets of operand registers and result registers.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op);
|
||||
extern ulong cpu_post_makecr (long v);
|
||||
|
||||
static struct cpu_post_andi_s
|
||||
{
|
||||
ulong cmd;
|
||||
ulong op1;
|
||||
ushort op2;
|
||||
ulong res;
|
||||
} cpu_post_andi_table[] =
|
||||
{
|
||||
{
|
||||
OP_ANDI_,
|
||||
0x80008000,
|
||||
0xffff,
|
||||
0x00008000
|
||||
},
|
||||
{
|
||||
OP_ANDIS_,
|
||||
0x80008000,
|
||||
0xffff,
|
||||
0x80000000
|
||||
},
|
||||
};
|
||||
static unsigned int cpu_post_andi_size = ARRAY_SIZE(cpu_post_andi_table);
|
||||
|
||||
int cpu_post_test_andi (void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i, reg;
|
||||
int flag = disable_interrupts();
|
||||
|
||||
for (i = 0; i < cpu_post_andi_size && ret == 0; i++)
|
||||
{
|
||||
struct cpu_post_andi_s *test = cpu_post_andi_table + i;
|
||||
|
||||
for (reg = 0; reg < 32 && ret == 0; reg++)
|
||||
{
|
||||
unsigned int reg0 = (reg + 0) % 32;
|
||||
unsigned int reg1 = (reg + 1) % 32;
|
||||
unsigned int stk = reg < 16 ? 31 : 15;
|
||||
unsigned long codecr[] =
|
||||
{
|
||||
ASM_STW(stk, 1, -4),
|
||||
ASM_ADDI(stk, 1, -16),
|
||||
ASM_STW(3, stk, 8),
|
||||
ASM_STW(reg0, stk, 4),
|
||||
ASM_STW(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 8),
|
||||
ASM_11IX(test->cmd, reg1, reg0, test->op2),
|
||||
ASM_STW(reg1, stk, 8),
|
||||
ASM_LWZ(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 4),
|
||||
ASM_LWZ(3, stk, 8),
|
||||
ASM_ADDI(1, stk, 16),
|
||||
ASM_LWZ(stk, 1, -4),
|
||||
ASM_BLR,
|
||||
};
|
||||
ulong res;
|
||||
ulong cr;
|
||||
|
||||
cpu_post_exec_21 (codecr, & cr, & res, test->op1);
|
||||
|
||||
ret = res == test->res &&
|
||||
(cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at andi test %d !\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
358
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/asm.S
Normal file
358
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/asm.S
Normal file
|
|
@ -0,0 +1,358 @@
|
|||
/*
|
||||
* Copyright (C) 2002 Wolfgang Denk <wd@denx.de>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <post.h>
|
||||
#include <ppc_asm.tmpl>
|
||||
#include <ppc_defs.h>
|
||||
#include <asm/cache.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
/* void cpu_post_exec_02 (ulong *code, ulong op1, ulong op2); */
|
||||
.global cpu_post_exec_02
|
||||
cpu_post_exec_02:
|
||||
isync
|
||||
mflr r0
|
||||
stwu r0, -4(r1)
|
||||
|
||||
subi r1, r1, 104
|
||||
stmw r6, 0(r1)
|
||||
|
||||
mtlr r3
|
||||
mr r3, r4
|
||||
mr r4, r5
|
||||
blrl
|
||||
|
||||
lmw r6, 0(r1)
|
||||
addi r1, r1, 104
|
||||
|
||||
lwz r0, 0(r1)
|
||||
addi r1, r1, 4
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/* void cpu_post_exec_04 (ulong *code, ulong op1, ulong op2, ulong op3, ulong op4); */
|
||||
.global cpu_post_exec_04
|
||||
cpu_post_exec_04:
|
||||
isync
|
||||
mflr r0
|
||||
stwu r0, -4(r1)
|
||||
|
||||
subi r1, r1, 96
|
||||
stmw r8, 0(r1)
|
||||
|
||||
mtlr r3
|
||||
mr r3, r4
|
||||
mr r4, r5
|
||||
mr r5, r6
|
||||
mtxer r7
|
||||
blrl
|
||||
|
||||
lmw r8, 0(r1)
|
||||
addi r1, r1, 96
|
||||
|
||||
lwz r0, 0(r1)
|
||||
addi r1, r1, 4
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/* void cpu_post_exec_12 (ulong *code, ulong *res, ulong op1, ulong op2); */
|
||||
.global cpu_post_exec_12
|
||||
cpu_post_exec_12:
|
||||
isync
|
||||
mflr r0
|
||||
stwu r0, -4(r1)
|
||||
stwu r4, -4(r1)
|
||||
|
||||
mtlr r3
|
||||
mr r3, r5
|
||||
mr r4, r6
|
||||
blrl
|
||||
|
||||
lwz r4, 0(r1)
|
||||
stw r3, 0(r4)
|
||||
|
||||
lwz r0, 4(r1)
|
||||
addi r1, r1, 8
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/* void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1); */
|
||||
.global cpu_post_exec_11
|
||||
cpu_post_exec_11:
|
||||
isync
|
||||
mflr r0
|
||||
stwu r0, -4(r1)
|
||||
stwu r4, -4(r1)
|
||||
|
||||
mtlr r3
|
||||
mr r3, r5
|
||||
blrl
|
||||
|
||||
lwz r4, 0(r1)
|
||||
stw r3, 0(r4)
|
||||
|
||||
lwz r0, 4(r1)
|
||||
addi r1, r1, 8
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/* void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op1); */
|
||||
.global cpu_post_exec_21
|
||||
cpu_post_exec_21:
|
||||
isync
|
||||
mflr r0
|
||||
stwu r0, -4(r1)
|
||||
stwu r4, -4(r1)
|
||||
stwu r5, -4(r1)
|
||||
|
||||
li r0, 0
|
||||
mtxer r0
|
||||
lwz r0, 0(r4)
|
||||
mtcr r0
|
||||
|
||||
mtlr r3
|
||||
mr r3, r6
|
||||
blrl
|
||||
|
||||
mfcr r0
|
||||
lwz r4, 4(r1)
|
||||
stw r0, 0(r4)
|
||||
lwz r4, 0(r1)
|
||||
stw r3, 0(r4)
|
||||
|
||||
lwz r0, 8(r1)
|
||||
addi r1, r1, 12
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/* void cpu_post_exec_22 (ulong *code, ulong *cr, ulong *res, ulong op1,
|
||||
ulong op2); */
|
||||
.global cpu_post_exec_22
|
||||
cpu_post_exec_22:
|
||||
isync
|
||||
mflr r0
|
||||
stwu r0, -4(r1)
|
||||
stwu r4, -4(r1)
|
||||
stwu r5, -4(r1)
|
||||
|
||||
li r0, 0
|
||||
mtxer r0
|
||||
lwz r0, 0(r4)
|
||||
mtcr r0
|
||||
|
||||
mtlr r3
|
||||
mr r3, r6
|
||||
mr r4, r7
|
||||
blrl
|
||||
|
||||
mfcr r0
|
||||
lwz r4, 4(r1)
|
||||
stw r0, 0(r4)
|
||||
lwz r4, 0(r1)
|
||||
stw r3, 0(r4)
|
||||
|
||||
lwz r0, 8(r1)
|
||||
addi r1, r1, 12
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/* void cpu_post_exec_12w (ulong *code, ulong *op1, ulong op2, ulong op3); */
|
||||
.global cpu_post_exec_12w
|
||||
cpu_post_exec_12w:
|
||||
isync
|
||||
mflr r0
|
||||
stwu r0, -4(r1)
|
||||
stwu r4, -4(r1)
|
||||
|
||||
mtlr r3
|
||||
lwz r3, 0(r4)
|
||||
mr r4, r5
|
||||
mr r5, r6
|
||||
blrl
|
||||
|
||||
lwz r4, 0(r1)
|
||||
stw r3, 0(r4)
|
||||
|
||||
lwz r0, 4(r1)
|
||||
addi r1, r1, 8
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/* void cpu_post_exec_11w (ulong *code, ulong *op1, ulong op2); */
|
||||
.global cpu_post_exec_11w
|
||||
cpu_post_exec_11w:
|
||||
isync
|
||||
mflr r0
|
||||
stwu r0, -4(r1)
|
||||
stwu r4, -4(r1)
|
||||
|
||||
mtlr r3
|
||||
lwz r3, 0(r4)
|
||||
mr r4, r5
|
||||
blrl
|
||||
|
||||
lwz r4, 0(r1)
|
||||
stw r3, 0(r4)
|
||||
|
||||
lwz r0, 4(r1)
|
||||
addi r1, r1, 8
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/* void cpu_post_exec_22w (ulong *code, ulong *op1, ulong op2, ulong *op3); */
|
||||
.global cpu_post_exec_22w
|
||||
cpu_post_exec_22w:
|
||||
isync
|
||||
mflr r0
|
||||
stwu r0, -4(r1)
|
||||
stwu r4, -4(r1)
|
||||
stwu r6, -4(r1)
|
||||
|
||||
mtlr r3
|
||||
lwz r3, 0(r4)
|
||||
mr r4, r5
|
||||
blrl
|
||||
|
||||
lwz r4, 4(r1)
|
||||
stw r3, 0(r4)
|
||||
lwz r4, 0(r1)
|
||||
stw r5, 0(r4)
|
||||
|
||||
lwz r0, 8(r1)
|
||||
addi r1, r1, 12
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/* void cpu_post_exec_21w (ulong *code, ulong *op1, ulong *op2); */
|
||||
.global cpu_post_exec_21w
|
||||
cpu_post_exec_21w:
|
||||
isync
|
||||
mflr r0
|
||||
stwu r0, -4(r1)
|
||||
stwu r4, -4(r1)
|
||||
stwu r5, -4(r1)
|
||||
|
||||
mtlr r3
|
||||
lwz r3, 0(r4)
|
||||
blrl
|
||||
|
||||
lwz r5, 4(r1)
|
||||
stw r3, 0(r5)
|
||||
lwz r5, 0(r1)
|
||||
stw r4, 0(r5)
|
||||
|
||||
lwz r0, 8(r1)
|
||||
addi r1, r1, 12
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/* void cpu_post_exec_21x (ulong *code, ulong *op1, ulong *op2, ulong op3); */
|
||||
.global cpu_post_exec_21x
|
||||
cpu_post_exec_21x:
|
||||
isync
|
||||
mflr r0
|
||||
stwu r0, -4(r1)
|
||||
stwu r4, -4(r1)
|
||||
stwu r5, -4(r1)
|
||||
|
||||
mtlr r3
|
||||
mr r3, r6
|
||||
blrl
|
||||
|
||||
lwz r5, 4(r1)
|
||||
stw r3, 0(r5)
|
||||
lwz r5, 0(r1)
|
||||
stw r4, 0(r5)
|
||||
|
||||
lwz r0, 8(r1)
|
||||
addi r1, r1, 12
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/* void cpu_post_exec_31 (ulong *code, ulong *ctr, ulong *lr, ulong *jump,
|
||||
ulong cr); */
|
||||
.global cpu_post_exec_31
|
||||
cpu_post_exec_31:
|
||||
isync
|
||||
mflr r0
|
||||
stwu r0, -4(r1)
|
||||
stwu r4, -4(r1)
|
||||
stwu r5, -4(r1)
|
||||
stwu r6, -4(r1)
|
||||
|
||||
mtlr r3
|
||||
lwz r3, 0(r4)
|
||||
lwz r4, 0(r5)
|
||||
mr r6, r7
|
||||
|
||||
mfcr r7
|
||||
blrl
|
||||
mtcr r7
|
||||
|
||||
lwz r7, 8(r1)
|
||||
stw r3, 0(r7)
|
||||
lwz r7, 4(r1)
|
||||
stw r4, 0(r7)
|
||||
lwz r7, 0(r1)
|
||||
stw r5, 0(r7)
|
||||
|
||||
lwz r0, 12(r1)
|
||||
addi r1, r1, 16
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/* int cpu_post_complex_1_asm (int a1, int a2, int a3, int a4, int n); */
|
||||
.global cpu_post_complex_1_asm
|
||||
cpu_post_complex_1_asm:
|
||||
li r9,0
|
||||
cmpw r9,r7
|
||||
bge cpu_post_complex_1_done
|
||||
mtctr r7
|
||||
cpu_post_complex_1_loop:
|
||||
mullw r0,r3,r4
|
||||
subf r0,r5,r0
|
||||
divw r0,r0,r6
|
||||
add r9,r9,r0
|
||||
bdnz cpu_post_complex_1_loop
|
||||
cpu_post_complex_1_done:
|
||||
mr r3,r9
|
||||
blr
|
||||
|
||||
/* int cpu_post_complex_2_asm (int x, int n); */
|
||||
.global cpu_post_complex_2_asm
|
||||
cpu_post_complex_2_asm:
|
||||
mr. r0,r4
|
||||
mtctr r0
|
||||
mr r0,r3
|
||||
li r3,1
|
||||
li r4,1
|
||||
blelr
|
||||
cpu_post_complex_2_loop:
|
||||
mullw r3,r3,r0
|
||||
add r3,r3,r4
|
||||
bdnz cpu_post_complex_2_loop
|
||||
blr
|
||||
|
||||
#endif
|
||||
198
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/b.c
Normal file
198
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/b.c
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Branch instructions: b, bl, bc
|
||||
*
|
||||
* The first 2 instructions (b, bl) are verified by jumping
|
||||
* to a fixed address and checking whether control was transfered
|
||||
* to that very point. For the bl instruction the value of the
|
||||
* link register is checked as well (using mfspr).
|
||||
* To verify the bc instruction various combinations of the BI/BO
|
||||
* fields, the CTR and the condition register values are
|
||||
* checked. The list of such combinations is pre-built and
|
||||
* linked in U-Boot at build time.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
|
||||
extern void cpu_post_exec_31 (ulong *code, ulong *ctr, ulong *lr, ulong *jump,
|
||||
ulong cr);
|
||||
|
||||
static int cpu_post_test_bc (ulong cmd, ulong bo, ulong bi,
|
||||
int pjump, int decr, int link, ulong pctr, ulong cr)
|
||||
{
|
||||
int ret = 0;
|
||||
ulong lr = 0;
|
||||
ulong ctr = pctr;
|
||||
ulong jump;
|
||||
|
||||
unsigned long code[] =
|
||||
{
|
||||
ASM_MTCR(6),
|
||||
ASM_MFLR(6),
|
||||
ASM_MTCTR(3),
|
||||
ASM_MTLR(4),
|
||||
ASM_LI(5, 1),
|
||||
ASM_3O(cmd, bo, bi, 8),
|
||||
ASM_LI(5, 0),
|
||||
ASM_MFCTR(3),
|
||||
ASM_MFLR(4),
|
||||
ASM_MTLR(6),
|
||||
ASM_BLR,
|
||||
};
|
||||
|
||||
cpu_post_exec_31 (code, &ctr, &lr, &jump, cr);
|
||||
|
||||
if (ret == 0)
|
||||
ret = pjump == jump ? 0 : -1;
|
||||
if (ret == 0)
|
||||
{
|
||||
if (decr)
|
||||
ret = pctr == ctr + 1 ? 0 : -1;
|
||||
else
|
||||
ret = pctr == ctr ? 0 : -1;
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
if (link)
|
||||
ret = lr == (ulong) code + 24 ? 0 : -1;
|
||||
else
|
||||
ret = lr == 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cpu_post_test_b (void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i;
|
||||
int flag = disable_interrupts();
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
ulong code[] =
|
||||
{
|
||||
ASM_MFLR(4),
|
||||
ASM_MTLR(3),
|
||||
ASM_B(4),
|
||||
ASM_MFLR(3),
|
||||
ASM_MTLR(4),
|
||||
ASM_BLR,
|
||||
};
|
||||
ulong res;
|
||||
|
||||
cpu_post_exec_11 (code, &res, 0);
|
||||
|
||||
ret = res == 0 ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at b1 test !\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
ulong code[] =
|
||||
{
|
||||
ASM_MFLR(4),
|
||||
ASM_MTLR(3),
|
||||
ASM_BL(4),
|
||||
ASM_MFLR(3),
|
||||
ASM_MTLR(4),
|
||||
ASM_BLR,
|
||||
};
|
||||
ulong res;
|
||||
|
||||
cpu_post_exec_11 (code, &res, 0);
|
||||
|
||||
ret = res == (ulong)code + 12 ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at b2 test !\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
ulong cc, cd;
|
||||
int cond;
|
||||
ulong ctr;
|
||||
int link;
|
||||
|
||||
i = 0;
|
||||
|
||||
for (cc = 0; cc < 4 && ret == 0; cc++)
|
||||
{
|
||||
for (cd = 0; cd < 4 && ret == 0; cd++)
|
||||
{
|
||||
for (link = 0; link <= 1 && ret == 0; link++)
|
||||
{
|
||||
for (cond = 0; cond <= 1 && ret == 0; cond++)
|
||||
{
|
||||
for (ctr = 1; ctr <= 2 && ret == 0; ctr++)
|
||||
{
|
||||
int decr = cd < 2;
|
||||
int cr = cond ? 0x80000000 : 0x00000000;
|
||||
int jumpc = cc >= 2 ||
|
||||
(cc == 0 && !cond) ||
|
||||
(cc == 1 && cond);
|
||||
int jumpd = cd >= 2 ||
|
||||
(cd == 0 && ctr != 1) ||
|
||||
(cd == 1 && ctr == 1);
|
||||
int jump = jumpc && jumpd;
|
||||
|
||||
ret = cpu_post_test_bc (link ? OP_BCL : OP_BC,
|
||||
(cc << 3) + (cd << 1), 0, jump, decr, link,
|
||||
ctr, cr);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at b3 test %d !\n", i);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
133
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/cmp.c
Normal file
133
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/cmp.c
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Integer compare instructions: cmpw, cmplw
|
||||
*
|
||||
* To verify these instructions the test runs them with
|
||||
* different combinations of operands, reads the condition
|
||||
* register value and compares it with the expected one.
|
||||
* The test contains a pre-built table
|
||||
* containing the description of each test case: the instruction,
|
||||
* the values of the operands, the condition field to save
|
||||
* the result in and the expected result.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern void cpu_post_exec_12 (ulong *code, ulong *res, ulong op1, ulong op2);
|
||||
|
||||
static struct cpu_post_cmp_s
|
||||
{
|
||||
ulong cmd;
|
||||
ulong op1;
|
||||
ulong op2;
|
||||
ulong cr;
|
||||
ulong res;
|
||||
} cpu_post_cmp_table[] =
|
||||
{
|
||||
{
|
||||
OP_CMPW,
|
||||
123,
|
||||
123,
|
||||
2,
|
||||
0x02
|
||||
},
|
||||
{
|
||||
OP_CMPW,
|
||||
123,
|
||||
133,
|
||||
3,
|
||||
0x08
|
||||
},
|
||||
{
|
||||
OP_CMPW,
|
||||
123,
|
||||
-133,
|
||||
4,
|
||||
0x04
|
||||
},
|
||||
{
|
||||
OP_CMPLW,
|
||||
123,
|
||||
123,
|
||||
2,
|
||||
0x02
|
||||
},
|
||||
{
|
||||
OP_CMPLW,
|
||||
123,
|
||||
-133,
|
||||
3,
|
||||
0x08
|
||||
},
|
||||
{
|
||||
OP_CMPLW,
|
||||
123,
|
||||
113,
|
||||
4,
|
||||
0x04
|
||||
},
|
||||
};
|
||||
static unsigned int cpu_post_cmp_size = ARRAY_SIZE(cpu_post_cmp_table);
|
||||
|
||||
int cpu_post_test_cmp (void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i;
|
||||
int flag = disable_interrupts();
|
||||
|
||||
for (i = 0; i < cpu_post_cmp_size && ret == 0; i++)
|
||||
{
|
||||
struct cpu_post_cmp_s *test = cpu_post_cmp_table + i;
|
||||
unsigned long code[] =
|
||||
{
|
||||
ASM_2C(test->cmd, test->cr, 3, 4),
|
||||
ASM_MFCR(3),
|
||||
ASM_BLR
|
||||
};
|
||||
ulong res;
|
||||
|
||||
cpu_post_exec_12 (code, & res, test->op1, test->op2);
|
||||
|
||||
ret = ((res >> (28 - 4 * test->cr)) & 0xe) == test->res ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at cmp test %d !\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
133
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/cmpi.c
Normal file
133
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/cmpi.c
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Integer compare instructions: cmpwi, cmplwi
|
||||
*
|
||||
* To verify these instructions the test runs them with
|
||||
* different combinations of operands, reads the condition
|
||||
* register value and compares it with the expected one.
|
||||
* The test contains a pre-built table
|
||||
* containing the description of each test case: the instruction,
|
||||
* the values of the operands, the condition field to save
|
||||
* the result in and the expected result.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
|
||||
|
||||
static struct cpu_post_cmpi_s
|
||||
{
|
||||
ulong cmd;
|
||||
ulong op1;
|
||||
ushort op2;
|
||||
ulong cr;
|
||||
ulong res;
|
||||
} cpu_post_cmpi_table[] =
|
||||
{
|
||||
{
|
||||
OP_CMPWI,
|
||||
123,
|
||||
123,
|
||||
2,
|
||||
0x02
|
||||
},
|
||||
{
|
||||
OP_CMPWI,
|
||||
123,
|
||||
133,
|
||||
3,
|
||||
0x08
|
||||
},
|
||||
{
|
||||
OP_CMPWI,
|
||||
123,
|
||||
-133,
|
||||
4,
|
||||
0x04
|
||||
},
|
||||
{
|
||||
OP_CMPLWI,
|
||||
123,
|
||||
123,
|
||||
2,
|
||||
0x02
|
||||
},
|
||||
{
|
||||
OP_CMPLWI,
|
||||
123,
|
||||
-133,
|
||||
3,
|
||||
0x08
|
||||
},
|
||||
{
|
||||
OP_CMPLWI,
|
||||
123,
|
||||
113,
|
||||
4,
|
||||
0x04
|
||||
},
|
||||
};
|
||||
static unsigned int cpu_post_cmpi_size = ARRAY_SIZE(cpu_post_cmpi_table);
|
||||
|
||||
int cpu_post_test_cmpi (void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i;
|
||||
int flag = disable_interrupts();
|
||||
|
||||
for (i = 0; i < cpu_post_cmpi_size && ret == 0; i++)
|
||||
{
|
||||
struct cpu_post_cmpi_s *test = cpu_post_cmpi_table + i;
|
||||
unsigned long code[] =
|
||||
{
|
||||
ASM_1IC(test->cmd, test->cr, 3, test->op2),
|
||||
ASM_MFCR(3),
|
||||
ASM_BLR
|
||||
};
|
||||
ulong res;
|
||||
|
||||
cpu_post_exec_11 (code, & res, test->op1);
|
||||
|
||||
ret = ((res >> (28 - 4 * test->cr)) & 0xe) == test->res ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at cmpi test %d !\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
127
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/complex.c
Normal file
127
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/complex.c
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Complex calculations
|
||||
*
|
||||
* The calculations in this test are just a combination of simpler
|
||||
* calculations, but probably under different timing conditions, etc.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern int cpu_post_complex_1_asm (int a1, int a2, int a3, int a4, int n);
|
||||
extern int cpu_post_complex_2_asm (int x, int n);
|
||||
|
||||
/*
|
||||
* n
|
||||
* SUM (a1 * a2 - a3) / a4 = n * result
|
||||
* i=1
|
||||
*/
|
||||
static int cpu_post_test_complex_1 (void)
|
||||
{
|
||||
int a1 = 666;
|
||||
int a2 = 667;
|
||||
int a3 = 668;
|
||||
int a4 = 66;
|
||||
int n = 100;
|
||||
int result = 6720; /* (a1 * a2 - a3) / a4 */
|
||||
|
||||
if (cpu_post_complex_1_asm(a1, a2, a3, a4, n) != n * result)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* (1 + x + x^2 + ... + x^n) * (1 - x) = 1 - x^(n+1)
|
||||
*/
|
||||
static int cpu_post_test_complex_2 (void)
|
||||
{
|
||||
int ret = -1;
|
||||
int x;
|
||||
int n;
|
||||
int k;
|
||||
int left;
|
||||
int right;
|
||||
|
||||
for (x = -8; x <= 8; x ++)
|
||||
{
|
||||
n = 9;
|
||||
|
||||
left = cpu_post_complex_2_asm(x, n);
|
||||
left *= 1 - x;
|
||||
|
||||
right = 1;
|
||||
for (k = 0; k <= n; k ++)
|
||||
{
|
||||
right *= x;
|
||||
}
|
||||
right = 1 - right;
|
||||
|
||||
if (left != right)
|
||||
{
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
Done:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cpu_post_test_complex (void)
|
||||
{
|
||||
int ret = 0;
|
||||
int flag = disable_interrupts();
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = cpu_post_test_complex_1();
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = cpu_post_test_complex_2();
|
||||
}
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at complex test !\n");
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
147
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/cpu.c
Normal file
147
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/cpu.c
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
*
|
||||
* This test checks the arithmetic logic unit (ALU) of CPU.
|
||||
* It tests independently various groups of instructions using
|
||||
* run-time modification of the code to reduce the memory footprint.
|
||||
* For more details refer to post/cpu/ *.c files.
|
||||
*/
|
||||
|
||||
#include <watchdog.h>
|
||||
#include <post.h>
|
||||
#include <asm/mmu.h>
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern int cpu_post_test_cmp (void);
|
||||
extern int cpu_post_test_cmpi (void);
|
||||
extern int cpu_post_test_two (void);
|
||||
extern int cpu_post_test_twox (void);
|
||||
extern int cpu_post_test_three (void);
|
||||
extern int cpu_post_test_threex (void);
|
||||
extern int cpu_post_test_threei (void);
|
||||
extern int cpu_post_test_andi (void);
|
||||
extern int cpu_post_test_srawi (void);
|
||||
extern int cpu_post_test_rlwnm (void);
|
||||
extern int cpu_post_test_rlwinm (void);
|
||||
extern int cpu_post_test_rlwimi (void);
|
||||
extern int cpu_post_test_store (void);
|
||||
extern int cpu_post_test_load (void);
|
||||
extern int cpu_post_test_cr (void);
|
||||
extern int cpu_post_test_b (void);
|
||||
extern int cpu_post_test_multi (void);
|
||||
extern int cpu_post_test_string (void);
|
||||
extern int cpu_post_test_complex (void);
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
ulong cpu_post_makecr (long v)
|
||||
{
|
||||
ulong cr = 0;
|
||||
|
||||
if (v < 0)
|
||||
cr |= 0x80000000;
|
||||
if (v > 0)
|
||||
cr |= 0x40000000;
|
||||
if (v == 0)
|
||||
cr |= 0x20000000;
|
||||
|
||||
return cr;
|
||||
}
|
||||
|
||||
int cpu_post_test (int flags)
|
||||
{
|
||||
int ic = icache_status ();
|
||||
int ret = 0;
|
||||
|
||||
WATCHDOG_RESET();
|
||||
if (ic)
|
||||
icache_disable ();
|
||||
#ifdef CONFIG_4xx_DCACHE
|
||||
/* disable cache */
|
||||
change_tlb(gd->bd->bi_memstart, gd->bd->bi_memsize, TLB_WORD2_I_ENABLE);
|
||||
#endif
|
||||
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_cmp ();
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_cmpi ();
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_two ();
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_twox ();
|
||||
WATCHDOG_RESET();
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_three ();
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_threex ();
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_threei ();
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_andi ();
|
||||
WATCHDOG_RESET();
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_srawi ();
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_rlwnm ();
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_rlwinm ();
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_rlwimi ();
|
||||
WATCHDOG_RESET();
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_store ();
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_load ();
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_cr ();
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_b ();
|
||||
WATCHDOG_RESET();
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_multi ();
|
||||
WATCHDOG_RESET();
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_string ();
|
||||
if (ret == 0)
|
||||
ret = cpu_post_test_complex ();
|
||||
WATCHDOG_RESET();
|
||||
|
||||
if (ic)
|
||||
icache_enable ();
|
||||
#ifdef CONFIG_4xx_DCACHE
|
||||
/* enable cache */
|
||||
change_tlb(gd->bd->bi_memstart, gd->bd->bi_memsize, 0);
|
||||
#endif
|
||||
|
||||
WATCHDOG_RESET();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_CPU */
|
||||
224
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/cpu_asm.h
Normal file
224
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/cpu_asm.h
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef _CPU_ASM_H
|
||||
#define _CPU_ASM_H
|
||||
|
||||
#define BIT_C 0x00000001
|
||||
|
||||
#define OP_BLR 0x4e800020
|
||||
#define OP_EXTSB 0x7c000774
|
||||
#define OP_EXTSH 0x7c000734
|
||||
#define OP_NEG 0x7c0000d0
|
||||
#define OP_CNTLZW 0x7c000034
|
||||
#define OP_ADD 0x7c000214
|
||||
#define OP_ADDC 0x7c000014
|
||||
#define OP_ADDME 0x7c0001d4
|
||||
#define OP_ADDZE 0x7c000194
|
||||
#define OP_ADDE 0x7c000114
|
||||
#define OP_ADDI 0x38000000
|
||||
#define OP_SUBF 0x7c000050
|
||||
#define OP_SUBFC 0x7c000010
|
||||
#define OP_SUBFE 0x7c000110
|
||||
#define OP_SUBFME 0x7c0001d0
|
||||
#define OP_SUBFZE 0x7c000190
|
||||
#define OP_MFCR 0x7c000026
|
||||
#define OP_MTCR 0x7c0ff120
|
||||
#define OP_MFXER 0x7c0102a6
|
||||
#define OP_MTXER 0x7c0103a6
|
||||
#define OP_MCRXR 0x7c000400
|
||||
#define OP_MCRF 0x4c000000
|
||||
#define OP_CRAND 0x4c000202
|
||||
#define OP_CRANDC 0x4c000102
|
||||
#define OP_CROR 0x4c000382
|
||||
#define OP_CRORC 0x4c000342
|
||||
#define OP_CRXOR 0x4c000182
|
||||
#define OP_CRNAND 0x4c0001c2
|
||||
#define OP_CRNOR 0x4c000042
|
||||
#define OP_CREQV 0x4c000242
|
||||
#define OP_CMPW 0x7c000000
|
||||
#define OP_CMPLW 0x7c000040
|
||||
#define OP_CMPWI 0x2c000000
|
||||
#define OP_CMPLWI 0x28000000
|
||||
#define OP_MULLW 0x7c0001d6
|
||||
#define OP_MULHW 0x7c000096
|
||||
#define OP_MULHWU 0x7c000016
|
||||
#define OP_DIVW 0x7c0003d6
|
||||
#define OP_DIVWU 0x7c000396
|
||||
#define OP_OR 0x7c000378
|
||||
#define OP_ORC 0x7c000338
|
||||
#define OP_XOR 0x7c000278
|
||||
#define OP_NAND 0x7c0003b8
|
||||
#define OP_NOR 0x7c0000f8
|
||||
#define OP_EQV 0x7c000238
|
||||
#define OP_SLW 0x7c000030
|
||||
#define OP_SRW 0x7c000430
|
||||
#define OP_SRAW 0x7c000630
|
||||
#define OP_ORI 0x60000000
|
||||
#define OP_ORIS 0x64000000
|
||||
#define OP_XORI 0x68000000
|
||||
#define OP_XORIS 0x6c000000
|
||||
#define OP_ANDI_ 0x70000000
|
||||
#define OP_ANDIS_ 0x74000000
|
||||
#define OP_SRAWI 0x7c000670
|
||||
#define OP_RLWINM 0x54000000
|
||||
#define OP_RLWNM 0x5c000000
|
||||
#define OP_RLWIMI 0x50000000
|
||||
#define OP_LWZ 0x80000000
|
||||
#define OP_LHZ 0xa0000000
|
||||
#define OP_LHA 0xa8000000
|
||||
#define OP_LBZ 0x88000000
|
||||
#define OP_LWZU 0x84000000
|
||||
#define OP_LHZU 0xa4000000
|
||||
#define OP_LHAU 0xac000000
|
||||
#define OP_LBZU 0x8c000000
|
||||
#define OP_LWZX 0x7c00002e
|
||||
#define OP_LHZX 0x7c00022e
|
||||
#define OP_LHAX 0x7c0002ae
|
||||
#define OP_LBZX 0x7c0000ae
|
||||
#define OP_LWZUX 0x7c00006e
|
||||
#define OP_LHZUX 0x7c00026e
|
||||
#define OP_LHAUX 0x7c0002ee
|
||||
#define OP_LBZUX 0x7c0000ee
|
||||
#define OP_STW 0x90000000
|
||||
#define OP_STH 0xb0000000
|
||||
#define OP_STB 0x98000000
|
||||
#define OP_STWU 0x94000000
|
||||
#define OP_STHU 0xb4000000
|
||||
#define OP_STBU 0x9c000000
|
||||
#define OP_STWX 0x7c00012e
|
||||
#define OP_STHX 0x7c00032e
|
||||
#define OP_STBX 0x7c0001ae
|
||||
#define OP_STWUX 0x7c00016e
|
||||
#define OP_STHUX 0x7c00036e
|
||||
#define OP_STBUX 0x7c0001ee
|
||||
#define OP_B 0x48000000
|
||||
#define OP_BL 0x48000001
|
||||
#define OP_BC 0x40000000
|
||||
#define OP_BCL 0x40000001
|
||||
#define OP_MTLR 0x7c0803a6
|
||||
#define OP_MFLR 0x7c0802a6
|
||||
#define OP_MTCTR 0x7c0903a6
|
||||
#define OP_MFCTR 0x7c0902a6
|
||||
#define OP_LMW 0xb8000000
|
||||
#define OP_STMW 0xbc000000
|
||||
#define OP_LSWI 0x7c0004aa
|
||||
#define OP_LSWX 0x7c00042a
|
||||
#define OP_STSWI 0x7c0005aa
|
||||
#define OP_STSWX 0x7c00052a
|
||||
|
||||
#define ASM_0(opcode) (opcode)
|
||||
#define ASM_1(opcode, rd) ((opcode) + \
|
||||
((rd) << 21))
|
||||
#define ASM_1C(opcode, cr) ((opcode) + \
|
||||
((cr) << 23))
|
||||
#define ASM_11(opcode, rd, rs) ((opcode) + \
|
||||
((rd) << 21) + \
|
||||
((rs) << 16))
|
||||
#define ASM_11C(opcode, cd, cs) ((opcode) + \
|
||||
((cd) << 23) + \
|
||||
((cs) << 18))
|
||||
#define ASM_11X(opcode, rd, rs) ((opcode) + \
|
||||
((rs) << 21) + \
|
||||
((rd) << 16))
|
||||
#define ASM_11I(opcode, rd, rs, simm) ((opcode) + \
|
||||
((rd) << 21) + \
|
||||
((rs) << 16) + \
|
||||
((simm) & 0xffff))
|
||||
#define ASM_11IF(opcode, rd, rs, simm) ((opcode) + \
|
||||
((rd) << 21) + \
|
||||
((rs) << 16) + \
|
||||
((simm) << 11))
|
||||
#define ASM_11S(opcode, rd, rs, sh) ((opcode) + \
|
||||
((rs) << 21) + \
|
||||
((rd) << 16) + \
|
||||
((sh) << 11))
|
||||
#define ASM_11IX(opcode, rd, rs, imm) ((opcode) + \
|
||||
((rs) << 21) + \
|
||||
((rd) << 16) + \
|
||||
((imm) & 0xffff))
|
||||
#define ASM_12(opcode, rd, rs1, rs2) ((opcode) + \
|
||||
((rd) << 21) + \
|
||||
((rs1) << 16) + \
|
||||
((rs2) << 11))
|
||||
#define ASM_12F(opcode, fd, fs1, fs2) ((opcode) + \
|
||||
((fd) << 21) + \
|
||||
((fs1) << 16) + \
|
||||
((fs2) << 11))
|
||||
#define ASM_12X(opcode, rd, rs1, rs2) ((opcode) + \
|
||||
((rs1) << 21) + \
|
||||
((rd) << 16) + \
|
||||
((rs2) << 11))
|
||||
#define ASM_2C(opcode, cr, rs1, rs2) ((opcode) + \
|
||||
((cr) << 23) + \
|
||||
((rs1) << 16) + \
|
||||
((rs2) << 11))
|
||||
#define ASM_1IC(opcode, cr, rs, imm) ((opcode) + \
|
||||
((cr) << 23) + \
|
||||
((rs) << 16) + \
|
||||
((imm) & 0xffff))
|
||||
#define ASM_122(opcode, rd, rs1, rs2, imm1, imm2) \
|
||||
((opcode) + \
|
||||
((rs1) << 21) + \
|
||||
((rd) << 16) + \
|
||||
((rs2) << 11) + \
|
||||
((imm1) << 6) + \
|
||||
((imm2) << 1))
|
||||
#define ASM_113(opcode, rd, rs, imm1, imm2, imm3) \
|
||||
((opcode) + \
|
||||
((rs) << 21) + \
|
||||
((rd) << 16) + \
|
||||
((imm1) << 11) + \
|
||||
((imm2) << 6) + \
|
||||
((imm3) << 1))
|
||||
#define ASM_1O(opcode, off) ((opcode) + (off))
|
||||
#define ASM_3O(opcode, bo, bi, off) ((opcode) + \
|
||||
((bo) << 21) + \
|
||||
((bi) << 16) + \
|
||||
(off))
|
||||
|
||||
#define ASM_ADDI(rd, rs, simm) ASM_11I(OP_ADDI, rd, rs, simm)
|
||||
#define ASM_BLR ASM_0(OP_BLR)
|
||||
#define ASM_STW(rd, rs, simm) ASM_11I(OP_STW, rd, rs, simm)
|
||||
#define ASM_LWZ(rd, rs, simm) ASM_11I(OP_LWZ, rd, rs, simm)
|
||||
#define ASM_MFCR(rd) ASM_1(OP_MFCR, rd)
|
||||
#define ASM_MTCR(rd) ASM_1(OP_MTCR, rd)
|
||||
#define ASM_MFXER(rd) ASM_1(OP_MFXER, rd)
|
||||
#define ASM_MTXER(rd) ASM_1(OP_MTXER, rd)
|
||||
#define ASM_MFCTR(rd) ASM_1(OP_MFCTR, rd)
|
||||
#define ASM_MTCTR(rd) ASM_1(OP_MTCTR, rd)
|
||||
#define ASM_MCRXR(cr) ASM_1C(OP_MCRXR, cr)
|
||||
#define ASM_MCRF(cd, cs) ASM_11C(OP_MCRF, cd, cs)
|
||||
#define ASM_B(off) ASM_1O(OP_B, off)
|
||||
#define ASM_BL(off) ASM_1O(OP_BL, off)
|
||||
#define ASM_MFLR(rd) ASM_1(OP_MFLR, rd)
|
||||
#define ASM_MTLR(rd) ASM_1(OP_MTLR, rd)
|
||||
#define ASM_LI(rd, imm) ASM_ADDI(rd, 0, imm)
|
||||
#define ASM_LMW(rd, rs, simm) ASM_11I(OP_LMW, rd, rs, simm)
|
||||
#define ASM_STMW(rd, rs, simm) ASM_11I(OP_STMW, rd, rs, simm)
|
||||
#define ASM_LSWI(rd, rs, simm) ASM_11IF(OP_LSWI, rd, rs, simm)
|
||||
#define ASM_LSWX(rd, rs1, rs2) ASM_12(OP_LSWX, rd, rs1, rs2)
|
||||
#define ASM_STSWI(rd, rs, simm) ASM_11IF(OP_STSWI, rd, rs, simm)
|
||||
#define ASM_STSWX(rd, rs1, rs2) ASM_12(OP_STSWX, rd, rs1, rs2)
|
||||
|
||||
|
||||
#endif /* _CPU_ASM_H */
|
||||
353
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/cr.c
Normal file
353
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/cr.c
Normal file
|
|
@ -0,0 +1,353 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Condition register istructions: mtcr, mfcr, mcrxr,
|
||||
* crand, crandc, cror, crorc, crxor,
|
||||
* crnand, crnor, creqv, mcrf
|
||||
*
|
||||
* The mtcrf/mfcr instructions is tested by loading different
|
||||
* values into the condition register (mtcrf), moving its value
|
||||
* to a general-purpose register (mfcr) and comparing this value
|
||||
* with the expected one.
|
||||
* The mcrxr instruction is tested by loading a fixed value
|
||||
* into the XER register (mtspr), moving XER value to the
|
||||
* condition register (mcrxr), moving it to a general-purpose
|
||||
* register (mfcr) and comparing the value of this register with
|
||||
* the expected one.
|
||||
* The rest of instructions is tested by loading a fixed
|
||||
* value into the condition register (mtcrf), executing each
|
||||
* instruction several times to modify all 4-bit condition
|
||||
* fields, moving the value of the conditional register to a
|
||||
* general-purpose register (mfcr) and comparing it with the
|
||||
* expected one.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern void cpu_post_exec_11 (ulong *code, ulong *res, ulong op1);
|
||||
extern void cpu_post_exec_21x (ulong *code, ulong *op1, ulong *op2, ulong op3);
|
||||
|
||||
static ulong cpu_post_cr_table1[] =
|
||||
{
|
||||
0xaaaaaaaa,
|
||||
0x55555555,
|
||||
};
|
||||
static unsigned int cpu_post_cr_size1 = ARRAY_SIZE(cpu_post_cr_table1);
|
||||
|
||||
static struct cpu_post_cr_s2 {
|
||||
ulong xer;
|
||||
ulong cr;
|
||||
} cpu_post_cr_table2[] =
|
||||
{
|
||||
{
|
||||
0xa0000000,
|
||||
1
|
||||
},
|
||||
{
|
||||
0x40000000,
|
||||
5
|
||||
},
|
||||
};
|
||||
static unsigned int cpu_post_cr_size2 = ARRAY_SIZE(cpu_post_cr_table2);
|
||||
|
||||
static struct cpu_post_cr_s3 {
|
||||
ulong cr;
|
||||
ulong cs;
|
||||
ulong cd;
|
||||
ulong res;
|
||||
} cpu_post_cr_table3[] =
|
||||
{
|
||||
{
|
||||
0x01234567,
|
||||
0,
|
||||
4,
|
||||
0x01230567
|
||||
},
|
||||
{
|
||||
0x01234567,
|
||||
7,
|
||||
0,
|
||||
0x71234567
|
||||
},
|
||||
};
|
||||
static unsigned int cpu_post_cr_size3 = ARRAY_SIZE(cpu_post_cr_table3);
|
||||
|
||||
static struct cpu_post_cr_s4 {
|
||||
ulong cmd;
|
||||
ulong cr;
|
||||
ulong op1;
|
||||
ulong op2;
|
||||
ulong op3;
|
||||
ulong res;
|
||||
} cpu_post_cr_table4[] =
|
||||
{
|
||||
{
|
||||
OP_CRAND,
|
||||
0x0000ffff,
|
||||
0,
|
||||
16,
|
||||
0,
|
||||
0x0000ffff
|
||||
},
|
||||
{
|
||||
OP_CRAND,
|
||||
0x0000ffff,
|
||||
16,
|
||||
17,
|
||||
0,
|
||||
0x8000ffff
|
||||
},
|
||||
{
|
||||
OP_CRANDC,
|
||||
0x0000ffff,
|
||||
0,
|
||||
16,
|
||||
0,
|
||||
0x0000ffff
|
||||
},
|
||||
{
|
||||
OP_CRANDC,
|
||||
0x0000ffff,
|
||||
16,
|
||||
0,
|
||||
0,
|
||||
0x8000ffff
|
||||
},
|
||||
{
|
||||
OP_CROR,
|
||||
0x0000ffff,
|
||||
0,
|
||||
16,
|
||||
0,
|
||||
0x8000ffff
|
||||
},
|
||||
{
|
||||
OP_CROR,
|
||||
0x0000ffff,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0x0000ffff
|
||||
},
|
||||
{
|
||||
OP_CRORC,
|
||||
0x0000ffff,
|
||||
0,
|
||||
16,
|
||||
0,
|
||||
0x0000ffff
|
||||
},
|
||||
{
|
||||
OP_CRORC,
|
||||
0x0000ffff,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x8000ffff
|
||||
},
|
||||
{
|
||||
OP_CRXOR,
|
||||
0x0000ffff,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x0000ffff
|
||||
},
|
||||
{
|
||||
OP_CRXOR,
|
||||
0x0000ffff,
|
||||
0,
|
||||
16,
|
||||
0,
|
||||
0x8000ffff
|
||||
},
|
||||
{
|
||||
OP_CRNAND,
|
||||
0x0000ffff,
|
||||
0,
|
||||
16,
|
||||
0,
|
||||
0x8000ffff
|
||||
},
|
||||
{
|
||||
OP_CRNAND,
|
||||
0x0000ffff,
|
||||
16,
|
||||
17,
|
||||
0,
|
||||
0x0000ffff
|
||||
},
|
||||
{
|
||||
OP_CRNOR,
|
||||
0x0000ffff,
|
||||
0,
|
||||
16,
|
||||
0,
|
||||
0x0000ffff
|
||||
},
|
||||
{
|
||||
OP_CRNOR,
|
||||
0x0000ffff,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0x8000ffff
|
||||
},
|
||||
{
|
||||
OP_CREQV,
|
||||
0x0000ffff,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x8000ffff
|
||||
},
|
||||
{
|
||||
OP_CREQV,
|
||||
0x0000ffff,
|
||||
0,
|
||||
16,
|
||||
0,
|
||||
0x0000ffff
|
||||
},
|
||||
};
|
||||
static unsigned int cpu_post_cr_size4 = ARRAY_SIZE(cpu_post_cr_table4);
|
||||
|
||||
int cpu_post_test_cr (void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i;
|
||||
unsigned long cr_sav;
|
||||
int flag = disable_interrupts();
|
||||
|
||||
asm ( "mfcr %0" : "=r" (cr_sav) : );
|
||||
|
||||
for (i = 0; i < cpu_post_cr_size1 && ret == 0; i++)
|
||||
{
|
||||
ulong cr = cpu_post_cr_table1[i];
|
||||
ulong res;
|
||||
|
||||
unsigned long code[] =
|
||||
{
|
||||
ASM_MTCR(3),
|
||||
ASM_MFCR(3),
|
||||
ASM_BLR,
|
||||
};
|
||||
|
||||
cpu_post_exec_11 (code, &res, cr);
|
||||
|
||||
ret = res == cr ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at cr1 test %d !\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < cpu_post_cr_size2 && ret == 0; i++)
|
||||
{
|
||||
struct cpu_post_cr_s2 *test = cpu_post_cr_table2 + i;
|
||||
ulong res;
|
||||
ulong xer;
|
||||
|
||||
unsigned long code[] =
|
||||
{
|
||||
ASM_MTXER(3),
|
||||
ASM_MCRXR(test->cr),
|
||||
ASM_MFCR(3),
|
||||
ASM_MFXER(4),
|
||||
ASM_BLR,
|
||||
};
|
||||
|
||||
cpu_post_exec_21x (code, &res, &xer, test->xer);
|
||||
|
||||
ret = xer == 0 && ((res << (4 * test->cr)) & 0xe0000000) == test->xer ?
|
||||
0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at cr2 test %d !\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < cpu_post_cr_size3 && ret == 0; i++)
|
||||
{
|
||||
struct cpu_post_cr_s3 *test = cpu_post_cr_table3 + i;
|
||||
ulong res;
|
||||
|
||||
unsigned long code[] =
|
||||
{
|
||||
ASM_MTCR(3),
|
||||
ASM_MCRF(test->cd, test->cs),
|
||||
ASM_MFCR(3),
|
||||
ASM_BLR,
|
||||
};
|
||||
|
||||
cpu_post_exec_11 (code, &res, test->cr);
|
||||
|
||||
ret = res == test->res ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at cr3 test %d !\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < cpu_post_cr_size4 && ret == 0; i++)
|
||||
{
|
||||
struct cpu_post_cr_s4 *test = cpu_post_cr_table4 + i;
|
||||
ulong res;
|
||||
|
||||
unsigned long code[] =
|
||||
{
|
||||
ASM_MTCR(3),
|
||||
ASM_12F(test->cmd, test->op3, test->op1, test->op2),
|
||||
ASM_MFCR(3),
|
||||
ASM_BLR,
|
||||
};
|
||||
|
||||
cpu_post_exec_11 (code, &res, test->cr);
|
||||
|
||||
ret = res == test->res ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at cr4 test %d !\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
asm ( "mtcr %0" : : "r" (cr_sav));
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (C) 2007
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
/*
|
||||
* This file is originally a part of the GCC testsuite.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#include <post.h>
|
||||
|
||||
GNU_FPOST_ATTR
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_FPU
|
||||
|
||||
int fpu_post_test_math1 (void)
|
||||
{
|
||||
volatile double a;
|
||||
double c, d;
|
||||
volatile double b;
|
||||
|
||||
d = 1.0;
|
||||
|
||||
do
|
||||
{
|
||||
c = d;
|
||||
d = c * 0.5;
|
||||
b = 1 + d;
|
||||
} while (b != 1.0);
|
||||
|
||||
a = 1.0 + c;
|
||||
|
||||
if (a == 1.0) {
|
||||
post_log ("Error in FPU math1 test\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_FPU */
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (C) 2007
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
/*
|
||||
* This file is originally a part of the GCC testsuite.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#include <post.h>
|
||||
|
||||
GNU_FPOST_ATTR
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_FPU
|
||||
|
||||
static float rintf (float x)
|
||||
{
|
||||
volatile float TWO23 = 8388608.0;
|
||||
|
||||
if (__builtin_fabs (x) < TWO23)
|
||||
{
|
||||
if (x > 0.0)
|
||||
{
|
||||
x += TWO23;
|
||||
x -= TWO23;
|
||||
}
|
||||
else if (x < 0.0)
|
||||
{
|
||||
x = TWO23 - x;
|
||||
x = -(x - TWO23);
|
||||
}
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
int fpu_post_test_math2 (void)
|
||||
{
|
||||
if (rintf (-1.5) != -2.0) {
|
||||
post_log ("Error in FPU math2 test\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_FPU */
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (C) 2007
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
/*
|
||||
* This file is originally a part of the GCC testsuite.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#include <post.h>
|
||||
|
||||
GNU_FPOST_ATTR
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_FPU
|
||||
|
||||
int fpu_post_test_math3 (void)
|
||||
{
|
||||
volatile long double dfrom = 1.1;
|
||||
volatile long double m1;
|
||||
volatile long double m2;
|
||||
volatile unsigned long mant_long;
|
||||
|
||||
m1 = dfrom / 2.0;
|
||||
m2 = m1 * 4294967296.0;
|
||||
mant_long = ((unsigned long) m2) & 0xffffffff;
|
||||
|
||||
if (mant_long != 0x8ccccccc) {
|
||||
post_log ("Error in FPU math3 test\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_FPU */
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (C) 2007
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
/*
|
||||
* This file is originally a part of the GCC testsuite.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#include <post.h>
|
||||
|
||||
GNU_FPOST_ATTR
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_FPU
|
||||
|
||||
int fpu_post_test_math4 (void)
|
||||
{
|
||||
volatile float reale = 1.0f;
|
||||
volatile float oneplus;
|
||||
int i;
|
||||
|
||||
if (sizeof (float) != 4)
|
||||
return 0;
|
||||
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
oneplus = 1.0f + reale;
|
||||
if (oneplus == 1.0f)
|
||||
break;
|
||||
reale = reale / 2.0f;
|
||||
}
|
||||
/* Assumes ieee754 accurate arithmetic above. */
|
||||
if (i != 24) {
|
||||
post_log ("Error in FPU math4 test\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_FPU */
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
#
|
||||
# (C) Copyright 2007
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = libpost$(ARCH)fpu.o
|
||||
|
||||
COBJS-$(CONFIG_HAS_POST) += 20001122-1.o
|
||||
COBJS-$(CONFIG_HAS_POST) += 20010114-2.o
|
||||
COBJS-$(CONFIG_HAS_POST) += 20010226-1.o
|
||||
COBJS-$(CONFIG_HAS_POST) += 980619-1.o
|
||||
COBJS-$(CONFIG_HAS_POST) += acc1.o
|
||||
COBJS-$(CONFIG_HAS_POST) += compare-fp-1.o
|
||||
COBJS-$(CONFIG_HAS_POST) += fpu.o
|
||||
COBJS-$(CONFIG_HAS_POST) += mul-subnormal-single-1.o
|
||||
|
||||
COBJS-$(CONFIG_HAS_POST) += darwin-ldouble.o
|
||||
|
||||
include $(TOPDIR)/post/rules.mk
|
||||
|
||||
CFLAGS := $(shell echo $(CFLAGS) | sed s/-msoft-float//)
|
||||
CFLAGS += -mhard-float -fkeep-inline-functions
|
||||
|
||||
$(obj)%.o: %.c
|
||||
$(CC) $(ALL_CFLAGS) -o $@.fp $< -c
|
||||
$(OBJCOPY) -R .gnu.attributes $@.fp $@
|
||||
rm -f $@.fp
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (C) 2007
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
/*
|
||||
* This file is originally a part of the GCC testsuite.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#include <post.h>
|
||||
|
||||
GNU_FPOST_ATTR
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_FPU
|
||||
|
||||
static double func (const double *array)
|
||||
{
|
||||
double d = *array;
|
||||
|
||||
if (d == 0.0)
|
||||
return d;
|
||||
else
|
||||
return d + func (array + 1);
|
||||
}
|
||||
|
||||
int fpu_post_test_math5 (void)
|
||||
{
|
||||
double values[] = { 0.1e-100, 1.0, -1.0, 0.0 };
|
||||
|
||||
if (func (values) != 0.1e-100) {
|
||||
post_log ("Error in FPU math5 test\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_FPU */
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* Copyright (C) 2007
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
/*
|
||||
* Test for correctness of composite floating-point comparisons.
|
||||
* Written by Paolo Bonzini, 26th May 2004.
|
||||
* This file is originally a part of the GCC testsuite.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#include <post.h>
|
||||
|
||||
GNU_FPOST_ATTR
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_FPU
|
||||
|
||||
static int failed;
|
||||
|
||||
#define TEST(c) if ((c) != ok) failed++
|
||||
#define ORD(a, b) (!__builtin_isunordered ((a), (b)))
|
||||
#define UNORD(a, b) (__builtin_isunordered ((a), (b)))
|
||||
#define UNEQ(a, b) (__builtin_isunordered ((a), (b)) || ((a) == (b)))
|
||||
#define UNLT(a, b) (__builtin_isunordered ((a), (b)) || ((a) < (b)))
|
||||
#define UNLE(a, b) (__builtin_isunordered ((a), (b)) || ((a) <= (b)))
|
||||
#define UNGT(a, b) (__builtin_isunordered ((a), (b)) || ((a) > (b)))
|
||||
#define UNGE(a, b) (__builtin_isunordered ((a), (b)) || ((a) >= (b)))
|
||||
#define LTGT(a, b) (__builtin_islessgreater ((a), (b)))
|
||||
|
||||
static float pinf;
|
||||
static float ninf;
|
||||
static float NaN;
|
||||
|
||||
static void iuneq (float x, float y, int ok)
|
||||
{
|
||||
TEST (UNEQ (x, y));
|
||||
TEST (!LTGT (x, y));
|
||||
TEST (UNLE (x, y) && UNGE (x,y));
|
||||
}
|
||||
|
||||
static void ieq (float x, float y, int ok)
|
||||
{
|
||||
TEST (ORD (x, y) && UNEQ (x, y));
|
||||
}
|
||||
|
||||
static void iltgt (float x, float y, int ok)
|
||||
{
|
||||
TEST (!UNEQ (x, y)); /* Not optimizable. */
|
||||
TEST (LTGT (x, y)); /* Same, __builtin_islessgreater does not trap. */
|
||||
TEST (ORD (x, y) && (UNLT (x, y) || UNGT (x,y)));
|
||||
}
|
||||
|
||||
static void ine (float x, float y, int ok)
|
||||
{
|
||||
TEST (UNLT (x, y) || UNGT (x, y));
|
||||
}
|
||||
|
||||
static void iunlt (float x, float y, int ok)
|
||||
{
|
||||
TEST (UNLT (x, y));
|
||||
TEST (UNORD (x, y) || (x < y));
|
||||
}
|
||||
|
||||
static void ilt (float x, float y, int ok)
|
||||
{
|
||||
TEST (ORD (x, y) && UNLT (x, y)); /* Not optimized */
|
||||
TEST ((x <= y) && (x != y));
|
||||
TEST ((x <= y) && (y != x));
|
||||
TEST ((x != y) && (x <= y)); /* Not optimized */
|
||||
TEST ((y != x) && (x <= y)); /* Not optimized */
|
||||
}
|
||||
|
||||
static void iunle (float x, float y, int ok)
|
||||
{
|
||||
TEST (UNLE (x, y));
|
||||
TEST (UNORD (x, y) || (x <= y));
|
||||
}
|
||||
|
||||
static void ile (float x, float y, int ok)
|
||||
{
|
||||
TEST (ORD (x, y) && UNLE (x, y)); /* Not optimized */
|
||||
TEST ((x < y) || (x == y));
|
||||
TEST ((y > x) || (x == y));
|
||||
TEST ((x == y) || (x < y)); /* Not optimized */
|
||||
TEST ((y == x) || (x < y)); /* Not optimized */
|
||||
}
|
||||
|
||||
static void iungt (float x, float y, int ok)
|
||||
{
|
||||
TEST (UNGT (x, y));
|
||||
TEST (UNORD (x, y) || (x > y));
|
||||
}
|
||||
|
||||
static void igt (float x, float y, int ok)
|
||||
{
|
||||
TEST (ORD (x, y) && UNGT (x, y)); /* Not optimized */
|
||||
TEST ((x >= y) && (x != y));
|
||||
TEST ((x >= y) && (y != x));
|
||||
TEST ((x != y) && (x >= y)); /* Not optimized */
|
||||
TEST ((y != x) && (x >= y)); /* Not optimized */
|
||||
}
|
||||
|
||||
static void iunge (float x, float y, int ok)
|
||||
{
|
||||
TEST (UNGE (x, y));
|
||||
TEST (UNORD (x, y) || (x >= y));
|
||||
}
|
||||
|
||||
static void ige (float x, float y, int ok)
|
||||
{
|
||||
TEST (ORD (x, y) && UNGE (x, y)); /* Not optimized */
|
||||
TEST ((x > y) || (x == y));
|
||||
TEST ((y < x) || (x == y));
|
||||
TEST ((x == y) || (x > y)); /* Not optimized */
|
||||
TEST ((y == x) || (x > y)); /* Not optimized */
|
||||
}
|
||||
|
||||
int fpu_post_test_math6 (void)
|
||||
{
|
||||
pinf = __builtin_inf ();
|
||||
ninf = -__builtin_inf ();
|
||||
NaN = __builtin_nan ("");
|
||||
|
||||
iuneq (ninf, pinf, 0);
|
||||
iuneq (NaN, NaN, 1);
|
||||
iuneq (pinf, ninf, 0);
|
||||
iuneq (1, 4, 0);
|
||||
iuneq (3, 3, 1);
|
||||
iuneq (5, 2, 0);
|
||||
|
||||
ieq (1, 4, 0);
|
||||
ieq (3, 3, 1);
|
||||
ieq (5, 2, 0);
|
||||
|
||||
iltgt (ninf, pinf, 1);
|
||||
iltgt (NaN, NaN, 0);
|
||||
iltgt (pinf, ninf, 1);
|
||||
iltgt (1, 4, 1);
|
||||
iltgt (3, 3, 0);
|
||||
iltgt (5, 2, 1);
|
||||
|
||||
ine (1, 4, 1);
|
||||
ine (3, 3, 0);
|
||||
ine (5, 2, 1);
|
||||
|
||||
iunlt (NaN, ninf, 1);
|
||||
iunlt (pinf, NaN, 1);
|
||||
iunlt (pinf, ninf, 0);
|
||||
iunlt (pinf, pinf, 0);
|
||||
iunlt (ninf, ninf, 0);
|
||||
iunlt (1, 4, 1);
|
||||
iunlt (3, 3, 0);
|
||||
iunlt (5, 2, 0);
|
||||
|
||||
ilt (1, 4, 1);
|
||||
ilt (3, 3, 0);
|
||||
ilt (5, 2, 0);
|
||||
|
||||
iunle (NaN, ninf, 1);
|
||||
iunle (pinf, NaN, 1);
|
||||
iunle (pinf, ninf, 0);
|
||||
iunle (pinf, pinf, 1);
|
||||
iunle (ninf, ninf, 1);
|
||||
iunle (1, 4, 1);
|
||||
iunle (3, 3, 1);
|
||||
iunle (5, 2, 0);
|
||||
|
||||
ile (1, 4, 1);
|
||||
ile (3, 3, 1);
|
||||
ile (5, 2, 0);
|
||||
|
||||
iungt (NaN, ninf, 1);
|
||||
iungt (pinf, NaN, 1);
|
||||
iungt (pinf, ninf, 1);
|
||||
iungt (pinf, pinf, 0);
|
||||
iungt (ninf, ninf, 0);
|
||||
iungt (1, 4, 0);
|
||||
iungt (3, 3, 0);
|
||||
iungt (5, 2, 1);
|
||||
|
||||
igt (1, 4, 0);
|
||||
igt (3, 3, 0);
|
||||
igt (5, 2, 1);
|
||||
|
||||
iunge (NaN, ninf, 1);
|
||||
iunge (pinf, NaN, 1);
|
||||
iunge (ninf, pinf, 0);
|
||||
iunge (pinf, pinf, 1);
|
||||
iunge (ninf, ninf, 1);
|
||||
iunge (1, 4, 0);
|
||||
iunge (3, 3, 1);
|
||||
iunge (5, 2, 1);
|
||||
|
||||
ige (1, 4, 0);
|
||||
ige (3, 3, 1);
|
||||
ige (5, 2, 1);
|
||||
|
||||
if (failed) {
|
||||
post_log ("Error in FPU math6 test\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_FPU */
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Borrowed from GCC 4.2.2 (which still was GPL v2+)
|
||||
*/
|
||||
/* 128-bit long double support routines for Darwin.
|
||||
Copyright (C) 1993, 2003, 2004, 2005, 2006, 2007
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2, or (at your option) any later
|
||||
version.
|
||||
|
||||
In addition to the permissions in the GNU General Public License, the
|
||||
Free Software Foundation gives you unlimited permission to link the
|
||||
compiled version of this file into combinations with other programs,
|
||||
and to distribute those combinations without any restriction coming
|
||||
from the use of this file. (The General Public License restrictions
|
||||
do apply in other respects; for example, they cover modification of
|
||||
the file, and distribution when not linked into a combine
|
||||
executable.)
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
/*
|
||||
* Implementations of floating-point long double basic arithmetic
|
||||
* functions called by the IBM C compiler when generating code for
|
||||
* PowerPC platforms. In particular, the following functions are
|
||||
* implemented: __gcc_qadd, __gcc_qsub, __gcc_qmul, and __gcc_qdiv.
|
||||
* Double-double algorithms are based on the paper "Doubled-Precision
|
||||
* IEEE Standard 754 Floating-Point Arithmetic" by W. Kahan, February 26,
|
||||
* 1987. An alternative published reference is "Software for
|
||||
* Doubled-Precision Floating-Point Computations", by Seppo Linnainmaa,
|
||||
* ACM TOMS vol 7 no 3, September 1981, pages 272-283.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Each long double is made up of two IEEE doubles. The value of the
|
||||
* long double is the sum of the values of the two parts. The most
|
||||
* significant part is required to be the value of the long double
|
||||
* rounded to the nearest double, as specified by IEEE. For Inf
|
||||
* values, the least significant part is required to be one of +0.0 or
|
||||
* -0.0. No other requirements are made; so, for example, 1.0 may be
|
||||
* represented as (1.0, +0.0) or (1.0, -0.0), and the low part of a
|
||||
* NaN is don't-care.
|
||||
*
|
||||
* This code currently assumes big-endian.
|
||||
*/
|
||||
|
||||
#define fabs(x) __builtin_fabs(x)
|
||||
#define isless(x, y) __builtin_isless(x, y)
|
||||
#define inf() __builtin_inf()
|
||||
#define unlikely(x) __builtin_expect((x), 0)
|
||||
#define nonfinite(a) unlikely(!isless(fabs(a), inf()))
|
||||
|
||||
typedef union {
|
||||
long double ldval;
|
||||
double dval[2];
|
||||
} longDblUnion;
|
||||
|
||||
/* Add two 'long double' values and return the result. */
|
||||
long double __gcc_qadd(double a, double aa, double c, double cc)
|
||||
{
|
||||
longDblUnion x;
|
||||
double z, q, zz, xh;
|
||||
|
||||
z = a + c;
|
||||
|
||||
if (nonfinite(z)) {
|
||||
z = cc + aa + c + a;
|
||||
if (nonfinite(z))
|
||||
return z;
|
||||
x.dval[0] = z; /* Will always be DBL_MAX. */
|
||||
zz = aa + cc;
|
||||
if (fabs(a) > fabs(c))
|
||||
x.dval[1] = a - z + c + zz;
|
||||
else
|
||||
x.dval[1] = c - z + a + zz;
|
||||
} else {
|
||||
q = a - z;
|
||||
zz = q + c + (a - (q + z)) + aa + cc;
|
||||
|
||||
/* Keep -0 result. */
|
||||
if (zz == 0.0)
|
||||
return z;
|
||||
|
||||
xh = z + zz;
|
||||
if (nonfinite(xh))
|
||||
return xh;
|
||||
|
||||
x.dval[0] = xh;
|
||||
x.dval[1] = z - xh + zz;
|
||||
}
|
||||
return x.ldval;
|
||||
}
|
||||
|
||||
long double __gcc_qsub(double a, double b, double c, double d)
|
||||
{
|
||||
return __gcc_qadd(a, b, -c, -d);
|
||||
}
|
||||
|
||||
long double __gcc_qmul(double a, double b, double c, double d)
|
||||
{
|
||||
longDblUnion z;
|
||||
double t, tau, u, v, w;
|
||||
|
||||
t = a * c; /* Highest order double term. */
|
||||
|
||||
if (unlikely(t == 0) /* Preserve -0. */
|
||||
|| nonfinite(t))
|
||||
return t;
|
||||
|
||||
/* Sum terms of two highest orders. */
|
||||
|
||||
/* Use fused multiply-add to get low part of a * c. */
|
||||
#ifndef __NO_FPRS__
|
||||
asm("fmsub %0,%1,%2,%3" : "=f"(tau) : "f"(a), "f"(c), "f"(t));
|
||||
#else
|
||||
tau = fmsub(a, c, t);
|
||||
#endif
|
||||
v = a * d;
|
||||
w = b * c;
|
||||
tau += v + w; /* Add in other second-order terms. */
|
||||
u = t + tau;
|
||||
|
||||
/* Construct long double result. */
|
||||
if (nonfinite(u))
|
||||
return u;
|
||||
z.dval[0] = u;
|
||||
z.dval[1] = (t - u) + tau;
|
||||
return z.ldval;
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (C) 2007
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* Author: Sergei Poselenov <sposelenov@emcraft.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* FPU test
|
||||
*
|
||||
* This test checks the arithmetic logic unit (ALU) of CPU.
|
||||
* It tests independently various groups of instructions using
|
||||
* run-time modification of the code to reduce the memory footprint.
|
||||
* For more details refer to post/cpu/ *.c files.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
|
||||
GNU_FPOST_ATTR
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_FPU
|
||||
|
||||
#include <watchdog.h>
|
||||
|
||||
extern int fpu_status (void);
|
||||
extern void fpu_enable (void);
|
||||
extern void fpu_disable (void);
|
||||
|
||||
extern int fpu_post_test_math1 (void);
|
||||
extern int fpu_post_test_math2 (void);
|
||||
extern int fpu_post_test_math3 (void);
|
||||
extern int fpu_post_test_math4 (void);
|
||||
extern int fpu_post_test_math5 (void);
|
||||
extern int fpu_post_test_math6 (void);
|
||||
extern int fpu_post_test_math7 (void);
|
||||
|
||||
int fpu_post_test (int flags)
|
||||
{
|
||||
int fpu = fpu_status ();
|
||||
|
||||
int ret = 0;
|
||||
|
||||
WATCHDOG_RESET ();
|
||||
|
||||
if (!fpu)
|
||||
fpu_enable ();
|
||||
|
||||
if (ret == 0)
|
||||
ret = fpu_post_test_math1 ();
|
||||
if (ret == 0)
|
||||
ret = fpu_post_test_math2 ();
|
||||
if (ret == 0)
|
||||
ret = fpu_post_test_math3 ();
|
||||
if (ret == 0)
|
||||
ret = fpu_post_test_math4 ();
|
||||
if (ret == 0)
|
||||
ret = fpu_post_test_math5 ();
|
||||
if (ret == 0)
|
||||
ret = fpu_post_test_math6 ();
|
||||
if (ret == 0)
|
||||
ret = fpu_post_test_math7 ();
|
||||
|
||||
if (!fpu)
|
||||
fpu_disable ();
|
||||
|
||||
WATCHDOG_RESET ();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_FPU */
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (C) 2007
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
/*
|
||||
* This file is originally a part of the GCC testsuite.
|
||||
* Check that certain subnormal numbers (formerly known as denormalized
|
||||
* numbers) are rounded to within 0.5 ulp. PR other/14354.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#include <post.h>
|
||||
|
||||
GNU_FPOST_ATTR
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_FPU
|
||||
|
||||
union uf
|
||||
{
|
||||
unsigned int u;
|
||||
float f;
|
||||
};
|
||||
|
||||
static float
|
||||
u2f (unsigned int v)
|
||||
{
|
||||
union uf u;
|
||||
u.u = v;
|
||||
return u.f;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
f2u (float v)
|
||||
{
|
||||
union uf u;
|
||||
u.f = v;
|
||||
return u.u;
|
||||
}
|
||||
|
||||
static int ok = 1;
|
||||
|
||||
static void
|
||||
tstmul (unsigned int ux, unsigned int uy, unsigned int ur)
|
||||
{
|
||||
float x = u2f (ux);
|
||||
float y = u2f (uy);
|
||||
|
||||
if (f2u (x * y) != ur)
|
||||
/* Set a variable rather than aborting here, to simplify tracing when
|
||||
several computations are wrong. */
|
||||
ok = 0;
|
||||
}
|
||||
|
||||
/* We don't want to make this const and static, or else we risk inlining
|
||||
causing the test to fold as constants at compile-time. */
|
||||
struct
|
||||
{
|
||||
unsigned int p1, p2, res;
|
||||
} static volatile expected[] =
|
||||
{
|
||||
{0xfff, 0x3f800400, 0xfff},
|
||||
{0xf, 0x3fc88888, 0x17},
|
||||
{0xf, 0x3f844444, 0xf}
|
||||
};
|
||||
|
||||
int fpu_post_test_math7 (void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(expected); i++)
|
||||
{
|
||||
tstmul (expected[i].p1, expected[i].p2, expected[i].res);
|
||||
tstmul (expected[i].p2, expected[i].p1, expected[i].res);
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
post_log ("Error in FPU math7 test\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_POST & CONFIG_SYS_POST_FPU */
|
||||
255
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/load.c
Normal file
255
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/load.c
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Load instructions: lbz(x)(u), lhz(x)(u), lha(x)(u), lwz(x)(u)
|
||||
*
|
||||
* All operations are performed on a 16-byte array. The array
|
||||
* is 4-byte aligned. The base register points to offset 8.
|
||||
* The immediate offset (index register) ranges in [-8 ... +7].
|
||||
* The test cases are composed so that they do not
|
||||
* cause alignment exceptions.
|
||||
* The test contains a pre-built table describing all test cases.
|
||||
* The table entry contains:
|
||||
* the instruction opcode, the array contents, the value of the index
|
||||
* register and the expected value of the destination register.
|
||||
* After executing the instruction, the test verifies the
|
||||
* value of the destination register and the value of the base
|
||||
* register (it must change for "load with update" instructions).
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern void cpu_post_exec_22w (ulong *code, ulong *op1, ulong op2, ulong *op3);
|
||||
extern void cpu_post_exec_21w (ulong *code, ulong *op1, ulong *op2);
|
||||
|
||||
static struct cpu_post_load_s
|
||||
{
|
||||
ulong cmd;
|
||||
uint width;
|
||||
int update;
|
||||
int index;
|
||||
ulong offset;
|
||||
} cpu_post_load_table[] =
|
||||
{
|
||||
{
|
||||
OP_LWZ,
|
||||
4,
|
||||
0,
|
||||
0,
|
||||
4
|
||||
},
|
||||
{
|
||||
OP_LHA,
|
||||
3,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
},
|
||||
{
|
||||
OP_LHZ,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
},
|
||||
{
|
||||
OP_LBZ,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
},
|
||||
{
|
||||
OP_LWZU,
|
||||
4,
|
||||
1,
|
||||
0,
|
||||
4
|
||||
},
|
||||
{
|
||||
OP_LHAU,
|
||||
3,
|
||||
1,
|
||||
0,
|
||||
2
|
||||
},
|
||||
{
|
||||
OP_LHZU,
|
||||
2,
|
||||
1,
|
||||
0,
|
||||
2
|
||||
},
|
||||
{
|
||||
OP_LBZU,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1
|
||||
},
|
||||
{
|
||||
OP_LWZX,
|
||||
4,
|
||||
0,
|
||||
1,
|
||||
4
|
||||
},
|
||||
{
|
||||
OP_LHAX,
|
||||
3,
|
||||
0,
|
||||
1,
|
||||
2
|
||||
},
|
||||
{
|
||||
OP_LHZX,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
2
|
||||
},
|
||||
{
|
||||
OP_LBZX,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1
|
||||
},
|
||||
{
|
||||
OP_LWZUX,
|
||||
4,
|
||||
1,
|
||||
1,
|
||||
4
|
||||
},
|
||||
{
|
||||
OP_LHAUX,
|
||||
3,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
},
|
||||
{
|
||||
OP_LHZUX,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
},
|
||||
{
|
||||
OP_LBZUX,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
},
|
||||
};
|
||||
static unsigned int cpu_post_load_size = ARRAY_SIZE(cpu_post_load_table);
|
||||
|
||||
int cpu_post_test_load (void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i;
|
||||
int flag = disable_interrupts();
|
||||
|
||||
for (i = 0; i < cpu_post_load_size && ret == 0; i++)
|
||||
{
|
||||
struct cpu_post_load_s *test = cpu_post_load_table + i;
|
||||
uchar data[16] =
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
ulong base0 = (ulong) (data + 8);
|
||||
ulong base = base0;
|
||||
ulong value;
|
||||
|
||||
if (test->index)
|
||||
{
|
||||
ulong code[] =
|
||||
{
|
||||
ASM_12(test->cmd, 5, 3, 4),
|
||||
ASM_BLR,
|
||||
};
|
||||
|
||||
cpu_post_exec_22w (code, &base, test->offset, &value);
|
||||
}
|
||||
else
|
||||
{
|
||||
ulong code[] =
|
||||
{
|
||||
ASM_11I(test->cmd, 4, 3, test->offset),
|
||||
ASM_BLR,
|
||||
};
|
||||
|
||||
cpu_post_exec_21w (code, &base, &value);
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
if (test->update)
|
||||
ret = base == base0 + test->offset ? 0 : -1;
|
||||
else
|
||||
ret = base == base0 ? 0 : -1;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
switch (test->width)
|
||||
{
|
||||
case 1:
|
||||
ret = *(uchar *)(base0 + test->offset) == value ?
|
||||
0 : -1;
|
||||
break;
|
||||
case 2:
|
||||
ret = *(ushort *)(base0 + test->offset) == value ?
|
||||
0 : -1;
|
||||
break;
|
||||
case 3:
|
||||
ret = *(short *)(base0 + test->offset) == value ?
|
||||
0 : -1;
|
||||
break;
|
||||
case 4:
|
||||
ret = *(ulong *)(base0 + test->offset) == value ?
|
||||
0 : -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at load test %d !\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Load/store multiple word instructions: lmw, stmw
|
||||
*
|
||||
* 27 consecutive words are loaded from a source memory buffer
|
||||
* into GPRs r5 through r31. After that, 27 consecutive words are stored
|
||||
* from the GPRs r5 through r31 into a target memory buffer. The contents
|
||||
* of the source and target buffers are then compared.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern void cpu_post_exec_02(ulong *code, ulong op1, ulong op2);
|
||||
|
||||
int cpu_post_test_multi(void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i;
|
||||
ulong src[27], dst[27];
|
||||
int flag = disable_interrupts();
|
||||
|
||||
ulong code[] = {
|
||||
ASM_LMW(5, 3, 0), /* lmw r5, 0(r3) */
|
||||
ASM_STMW(5, 4, 0), /* stmr r5, 0(r4) */
|
||||
ASM_BLR, /* blr */
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(src); ++i) {
|
||||
src[i] = i;
|
||||
dst[i] = 0;
|
||||
}
|
||||
|
||||
cpu_post_exec_02(code, (ulong) src, (ulong) dst);
|
||||
|
||||
ret = memcmp(src, dst, sizeof(dst)) == 0 ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
post_log("Error at multi test !\n");
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
158
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/rlwimi.c
Normal file
158
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/rlwimi.c
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Shift instructions: rlwimi
|
||||
*
|
||||
* The test contains a pre-built table of instructions, operands and
|
||||
* expected results. For each table entry, the test will cyclically use
|
||||
* different sets of operand registers and result registers.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern void cpu_post_exec_22 (ulong *code, ulong *cr, ulong *res, ulong op1,
|
||||
ulong op2);
|
||||
extern ulong cpu_post_makecr (long v);
|
||||
|
||||
static struct cpu_post_rlwimi_s
|
||||
{
|
||||
ulong cmd;
|
||||
ulong op0;
|
||||
ulong op1;
|
||||
uchar op2;
|
||||
uchar mb;
|
||||
uchar me;
|
||||
ulong res;
|
||||
} cpu_post_rlwimi_table[] =
|
||||
{
|
||||
{
|
||||
OP_RLWIMI,
|
||||
0xff00ffff,
|
||||
0x0000aa00,
|
||||
8,
|
||||
8,
|
||||
15,
|
||||
0xffaaffff
|
||||
},
|
||||
};
|
||||
static unsigned int cpu_post_rlwimi_size = ARRAY_SIZE(cpu_post_rlwimi_table);
|
||||
|
||||
int cpu_post_test_rlwimi (void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i, reg;
|
||||
int flag = disable_interrupts();
|
||||
|
||||
for (i = 0; i < cpu_post_rlwimi_size && ret == 0; i++)
|
||||
{
|
||||
struct cpu_post_rlwimi_s *test = cpu_post_rlwimi_table + i;
|
||||
|
||||
for (reg = 0; reg < 32 && ret == 0; reg++)
|
||||
{
|
||||
unsigned int reg0 = (reg + 0) % 32;
|
||||
unsigned int reg1 = (reg + 1) % 32;
|
||||
unsigned int stk = reg < 16 ? 31 : 15;
|
||||
unsigned long code[] =
|
||||
{
|
||||
ASM_STW(stk, 1, -4),
|
||||
ASM_ADDI(stk, 1, -20),
|
||||
ASM_STW(3, stk, 8),
|
||||
ASM_STW(4, stk, 12),
|
||||
ASM_STW(reg0, stk, 4),
|
||||
ASM_STW(reg1, stk, 0),
|
||||
ASM_LWZ(reg1, stk, 8),
|
||||
ASM_LWZ(reg0, stk, 12),
|
||||
ASM_113(test->cmd, reg1, reg0, test->op2, test->mb, test->me),
|
||||
ASM_STW(reg1, stk, 8),
|
||||
ASM_LWZ(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 4),
|
||||
ASM_LWZ(3, stk, 8),
|
||||
ASM_ADDI(1, stk, 20),
|
||||
ASM_LWZ(stk, 1, -4),
|
||||
ASM_BLR,
|
||||
};
|
||||
unsigned long codecr[] =
|
||||
{
|
||||
ASM_STW(stk, 1, -4),
|
||||
ASM_ADDI(stk, 1, -20),
|
||||
ASM_STW(3, stk, 8),
|
||||
ASM_STW(4, stk, 12),
|
||||
ASM_STW(reg0, stk, 4),
|
||||
ASM_STW(reg1, stk, 0),
|
||||
ASM_LWZ(reg1, stk, 8),
|
||||
ASM_LWZ(reg0, stk, 12),
|
||||
ASM_113(test->cmd, reg1, reg0, test->op2, test->mb, test->me) |
|
||||
BIT_C,
|
||||
ASM_STW(reg1, stk, 8),
|
||||
ASM_LWZ(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 4),
|
||||
ASM_LWZ(3, stk, 8),
|
||||
ASM_ADDI(1, stk, 20),
|
||||
ASM_LWZ(stk, 1, -4),
|
||||
ASM_BLR,
|
||||
};
|
||||
ulong res;
|
||||
ulong cr;
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
cr = 0;
|
||||
cpu_post_exec_22 (code, & cr, & res, test->op0, test->op1);
|
||||
|
||||
ret = res == test->res && cr == 0 ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at rlwimi test %d !\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
cpu_post_exec_22 (codecr, & cr, & res, test->op0, test->op1);
|
||||
|
||||
ret = res == test->res &&
|
||||
(cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at rlwimi test %d !\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
151
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/rlwinm.c
Normal file
151
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/rlwinm.c
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Shift instructions: rlwinm
|
||||
*
|
||||
* The test contains a pre-built table of instructions, operands and
|
||||
* expected results. For each table entry, the test will cyclically use
|
||||
* different sets of operand registers and result registers.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op1);
|
||||
extern ulong cpu_post_makecr (long v);
|
||||
|
||||
static struct cpu_post_rlwinm_s
|
||||
{
|
||||
ulong cmd;
|
||||
ulong op1;
|
||||
uchar op2;
|
||||
uchar mb;
|
||||
uchar me;
|
||||
ulong res;
|
||||
} cpu_post_rlwinm_table[] =
|
||||
{
|
||||
{
|
||||
OP_RLWINM,
|
||||
0xffff0000,
|
||||
24,
|
||||
16,
|
||||
23,
|
||||
0x0000ff00
|
||||
},
|
||||
};
|
||||
static unsigned int cpu_post_rlwinm_size = ARRAY_SIZE(cpu_post_rlwinm_table);
|
||||
|
||||
int cpu_post_test_rlwinm (void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i, reg;
|
||||
int flag = disable_interrupts();
|
||||
|
||||
for (i = 0; i < cpu_post_rlwinm_size && ret == 0; i++)
|
||||
{
|
||||
struct cpu_post_rlwinm_s *test = cpu_post_rlwinm_table + i;
|
||||
|
||||
for (reg = 0; reg < 32 && ret == 0; reg++)
|
||||
{
|
||||
unsigned int reg0 = (reg + 0) % 32;
|
||||
unsigned int reg1 = (reg + 1) % 32;
|
||||
unsigned int stk = reg < 16 ? 31 : 15;
|
||||
unsigned long code[] =
|
||||
{
|
||||
ASM_STW(stk, 1, -4),
|
||||
ASM_ADDI(stk, 1, -16),
|
||||
ASM_STW(3, stk, 8),
|
||||
ASM_STW(reg0, stk, 4),
|
||||
ASM_STW(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 8),
|
||||
ASM_113(test->cmd, reg1, reg0, test->op2, test->mb, test->me),
|
||||
ASM_STW(reg1, stk, 8),
|
||||
ASM_LWZ(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 4),
|
||||
ASM_LWZ(3, stk, 8),
|
||||
ASM_ADDI(1, stk, 16),
|
||||
ASM_LWZ(stk, 1, -4),
|
||||
ASM_BLR,
|
||||
};
|
||||
unsigned long codecr[] =
|
||||
{
|
||||
ASM_STW(stk, 1, -4),
|
||||
ASM_ADDI(stk, 1, -16),
|
||||
ASM_STW(3, stk, 8),
|
||||
ASM_STW(reg0, stk, 4),
|
||||
ASM_STW(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 8),
|
||||
ASM_113(test->cmd, reg1, reg0, test->op2, test->mb,
|
||||
test->me) | BIT_C,
|
||||
ASM_STW(reg1, stk, 8),
|
||||
ASM_LWZ(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 4),
|
||||
ASM_LWZ(3, stk, 8),
|
||||
ASM_ADDI(1, stk, 16),
|
||||
ASM_LWZ(stk, 1, -4),
|
||||
ASM_BLR,
|
||||
};
|
||||
ulong res;
|
||||
ulong cr;
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
cr = 0;
|
||||
cpu_post_exec_21 (code, & cr, & res, test->op1);
|
||||
|
||||
ret = res == test->res && cr == 0 ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at rlwinm test %d !\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
cpu_post_exec_21 (codecr, & cr, & res, test->op1);
|
||||
|
||||
ret = res == test->res &&
|
||||
(cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at rlwinm test %d !\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
161
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/rlwnm.c
Normal file
161
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/rlwnm.c
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Shift instructions: rlwnm
|
||||
*
|
||||
* The test contains a pre-built table of instructions, operands and
|
||||
* expected results. For each table entry, the test will cyclically use
|
||||
* different sets of operand registers and result registers.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern void cpu_post_exec_22 (ulong *code, ulong *cr, ulong *res, ulong op1,
|
||||
ulong op2);
|
||||
extern ulong cpu_post_makecr (long v);
|
||||
|
||||
static struct cpu_post_rlwnm_s
|
||||
{
|
||||
ulong cmd;
|
||||
ulong op1;
|
||||
ulong op2;
|
||||
uchar mb;
|
||||
uchar me;
|
||||
ulong res;
|
||||
} cpu_post_rlwnm_table[] =
|
||||
{
|
||||
{
|
||||
OP_RLWNM,
|
||||
0xffff0000,
|
||||
24,
|
||||
16,
|
||||
23,
|
||||
0x0000ff00
|
||||
},
|
||||
};
|
||||
static unsigned int cpu_post_rlwnm_size = ARRAY_SIZE(cpu_post_rlwnm_table);
|
||||
|
||||
int cpu_post_test_rlwnm (void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i, reg;
|
||||
int flag = disable_interrupts();
|
||||
|
||||
for (i = 0; i < cpu_post_rlwnm_size && ret == 0; i++)
|
||||
{
|
||||
struct cpu_post_rlwnm_s *test = cpu_post_rlwnm_table + i;
|
||||
|
||||
for (reg = 0; reg < 32 && ret == 0; reg++)
|
||||
{
|
||||
unsigned int reg0 = (reg + 0) % 32;
|
||||
unsigned int reg1 = (reg + 1) % 32;
|
||||
unsigned int reg2 = (reg + 2) % 32;
|
||||
unsigned int stk = reg < 16 ? 31 : 15;
|
||||
unsigned long code[] =
|
||||
{
|
||||
ASM_STW(stk, 1, -4),
|
||||
ASM_ADDI(stk, 1, -24),
|
||||
ASM_STW(3, stk, 12),
|
||||
ASM_STW(4, stk, 16),
|
||||
ASM_STW(reg0, stk, 8),
|
||||
ASM_STW(reg1, stk, 4),
|
||||
ASM_STW(reg2, stk, 0),
|
||||
ASM_LWZ(reg1, stk, 12),
|
||||
ASM_LWZ(reg0, stk, 16),
|
||||
ASM_122(test->cmd, reg2, reg1, reg0, test->mb, test->me),
|
||||
ASM_STW(reg2, stk, 12),
|
||||
ASM_LWZ(reg2, stk, 0),
|
||||
ASM_LWZ(reg1, stk, 4),
|
||||
ASM_LWZ(reg0, stk, 8),
|
||||
ASM_LWZ(3, stk, 12),
|
||||
ASM_ADDI(1, stk, 24),
|
||||
ASM_LWZ(stk, 1, -4),
|
||||
ASM_BLR,
|
||||
};
|
||||
unsigned long codecr[] =
|
||||
{
|
||||
ASM_STW(stk, 1, -4),
|
||||
ASM_ADDI(stk, 1, -24),
|
||||
ASM_STW(3, stk, 12),
|
||||
ASM_STW(4, stk, 16),
|
||||
ASM_STW(reg0, stk, 8),
|
||||
ASM_STW(reg1, stk, 4),
|
||||
ASM_STW(reg2, stk, 0),
|
||||
ASM_LWZ(reg1, stk, 12),
|
||||
ASM_LWZ(reg0, stk, 16),
|
||||
ASM_122(test->cmd, reg2, reg1, reg0, test->mb, test->me) |
|
||||
BIT_C,
|
||||
ASM_STW(reg2, stk, 12),
|
||||
ASM_LWZ(reg2, stk, 0),
|
||||
ASM_LWZ(reg1, stk, 4),
|
||||
ASM_LWZ(reg0, stk, 8),
|
||||
ASM_LWZ(3, stk, 12),
|
||||
ASM_ADDI(1, stk, 24),
|
||||
ASM_LWZ(stk, 1, -4),
|
||||
ASM_BLR,
|
||||
};
|
||||
ulong res;
|
||||
ulong cr;
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
cr = 0;
|
||||
cpu_post_exec_22 (code, & cr, & res, test->op1, test->op2);
|
||||
|
||||
ret = res == test->res && cr == 0 ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at rlwnm test %d !\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
cpu_post_exec_22 (codecr, & cr, & res, test->op1, test->op2);
|
||||
|
||||
ret = res == test->res &&
|
||||
(cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at rlwnm test %d !\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
152
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/srawi.c
Normal file
152
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/srawi.c
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Shift instructions: srawi
|
||||
*
|
||||
* The test contains a pre-built table of instructions, operands and
|
||||
* expected results. For each table entry, the test will cyclically use
|
||||
* different sets of operand registers and result registers.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op);
|
||||
extern ulong cpu_post_makecr (long v);
|
||||
|
||||
static struct cpu_post_srawi_s
|
||||
{
|
||||
ulong cmd;
|
||||
ulong op1;
|
||||
uchar op2;
|
||||
ulong res;
|
||||
} cpu_post_srawi_table[] =
|
||||
{
|
||||
{
|
||||
OP_SRAWI,
|
||||
0x8000,
|
||||
3,
|
||||
0x1000
|
||||
},
|
||||
{
|
||||
OP_SRAWI,
|
||||
0x80000000,
|
||||
3,
|
||||
0xf0000000
|
||||
},
|
||||
};
|
||||
static unsigned int cpu_post_srawi_size = ARRAY_SIZE(cpu_post_srawi_table);
|
||||
|
||||
int cpu_post_test_srawi (void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i, reg;
|
||||
int flag = disable_interrupts();
|
||||
|
||||
for (i = 0; i < cpu_post_srawi_size && ret == 0; i++)
|
||||
{
|
||||
struct cpu_post_srawi_s *test = cpu_post_srawi_table + i;
|
||||
|
||||
for (reg = 0; reg < 32 && ret == 0; reg++)
|
||||
{
|
||||
unsigned int reg0 = (reg + 0) % 32;
|
||||
unsigned int reg1 = (reg + 1) % 32;
|
||||
unsigned int stk = reg < 16 ? 31 : 15;
|
||||
unsigned long code[] =
|
||||
{
|
||||
ASM_STW(stk, 1, -4),
|
||||
ASM_ADDI(stk, 1, -16),
|
||||
ASM_STW(3, stk, 8),
|
||||
ASM_STW(reg0, stk, 4),
|
||||
ASM_STW(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 8),
|
||||
ASM_11S(test->cmd, reg1, reg0, test->op2),
|
||||
ASM_STW(reg1, stk, 8),
|
||||
ASM_LWZ(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 4),
|
||||
ASM_LWZ(3, stk, 8),
|
||||
ASM_ADDI(1, stk, 16),
|
||||
ASM_LWZ(stk, 1, -4),
|
||||
ASM_BLR,
|
||||
};
|
||||
unsigned long codecr[] =
|
||||
{
|
||||
ASM_STW(stk, 1, -4),
|
||||
ASM_ADDI(stk, 1, -16),
|
||||
ASM_STW(3, stk, 8),
|
||||
ASM_STW(reg0, stk, 4),
|
||||
ASM_STW(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 8),
|
||||
ASM_11S(test->cmd, reg1, reg0, test->op2) | BIT_C,
|
||||
ASM_STW(reg1, stk, 8),
|
||||
ASM_LWZ(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 4),
|
||||
ASM_LWZ(3, stk, 8),
|
||||
ASM_ADDI(1, stk, 16),
|
||||
ASM_LWZ(stk, 1, -4),
|
||||
ASM_BLR,
|
||||
};
|
||||
ulong res;
|
||||
ulong cr;
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
cr = 0;
|
||||
cpu_post_exec_21 (code, & cr, & res, test->op1);
|
||||
|
||||
ret = res == test->res && cr == 0 ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at srawi test %d !\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
cpu_post_exec_21 (codecr, & cr, & res, test->op1);
|
||||
|
||||
ret = res == test->res &&
|
||||
(cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at srawi test %d !\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
235
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/store.c
Normal file
235
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/store.c
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Store instructions: stb(x)(u), sth(x)(u), stw(x)(u)
|
||||
*
|
||||
* All operations are performed on a 16-byte array. The array
|
||||
* is 4-byte aligned. The base register points to offset 8.
|
||||
* The immediate offset (index register) ranges in [-8 ... +7].
|
||||
* The test cases are composed so that they do not
|
||||
* cause alignment exceptions.
|
||||
* The test contains a pre-built table describing all test cases.
|
||||
* The table entry contains:
|
||||
* the instruction opcode, the value of the index register and
|
||||
* the value of the source register. After executing the
|
||||
* instruction, the test verifies the contents of the array
|
||||
* and the value of the base register (it must change for "store
|
||||
* with update" instructions).
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern void cpu_post_exec_12w (ulong *code, ulong *op1, ulong op2, ulong op3);
|
||||
extern void cpu_post_exec_11w (ulong *code, ulong *op1, ulong op2);
|
||||
|
||||
static struct cpu_post_store_s
|
||||
{
|
||||
ulong cmd;
|
||||
uint width;
|
||||
int update;
|
||||
int index;
|
||||
ulong offset;
|
||||
ulong value;
|
||||
} cpu_post_store_table[] =
|
||||
{
|
||||
{
|
||||
OP_STW,
|
||||
4,
|
||||
0,
|
||||
0,
|
||||
-4,
|
||||
0xff00ff00
|
||||
},
|
||||
{
|
||||
OP_STH,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
-2,
|
||||
0xff00
|
||||
},
|
||||
{
|
||||
OP_STB,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
-1,
|
||||
0xff
|
||||
},
|
||||
{
|
||||
OP_STWU,
|
||||
4,
|
||||
1,
|
||||
0,
|
||||
-4,
|
||||
0xff00ff00
|
||||
},
|
||||
{
|
||||
OP_STHU,
|
||||
2,
|
||||
1,
|
||||
0,
|
||||
-2,
|
||||
0xff00
|
||||
},
|
||||
{
|
||||
OP_STBU,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
-1,
|
||||
0xff
|
||||
},
|
||||
{
|
||||
OP_STWX,
|
||||
4,
|
||||
0,
|
||||
1,
|
||||
-4,
|
||||
0xff00ff00
|
||||
},
|
||||
{
|
||||
OP_STHX,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
-2,
|
||||
0xff00
|
||||
},
|
||||
{
|
||||
OP_STBX,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
-1,
|
||||
0xff
|
||||
},
|
||||
{
|
||||
OP_STWUX,
|
||||
4,
|
||||
1,
|
||||
1,
|
||||
-4,
|
||||
0xff00ff00
|
||||
},
|
||||
{
|
||||
OP_STHUX,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
-2,
|
||||
0xff00
|
||||
},
|
||||
{
|
||||
OP_STBUX,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
-1,
|
||||
0xff
|
||||
},
|
||||
};
|
||||
static unsigned int cpu_post_store_size = ARRAY_SIZE(cpu_post_store_table);
|
||||
|
||||
int cpu_post_test_store (void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i;
|
||||
int flag = disable_interrupts();
|
||||
|
||||
for (i = 0; i < cpu_post_store_size && ret == 0; i++)
|
||||
{
|
||||
struct cpu_post_store_s *test = cpu_post_store_table + i;
|
||||
uchar data[16] =
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
ulong base0 = (ulong) (data + 8);
|
||||
ulong base = base0;
|
||||
|
||||
if (test->index)
|
||||
{
|
||||
ulong code[] =
|
||||
{
|
||||
ASM_12(test->cmd, 5, 3, 4),
|
||||
ASM_BLR,
|
||||
};
|
||||
|
||||
cpu_post_exec_12w (code, &base, test->offset, test->value);
|
||||
}
|
||||
else
|
||||
{
|
||||
ulong code[] =
|
||||
{
|
||||
ASM_11I(test->cmd, 4, 3, test->offset),
|
||||
ASM_BLR,
|
||||
};
|
||||
|
||||
cpu_post_exec_11w (code, &base, test->value);
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
if (test->update)
|
||||
ret = base == base0 + test->offset ? 0 : -1;
|
||||
else
|
||||
ret = base == base0 ? 0 : -1;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
switch (test->width)
|
||||
{
|
||||
case 1:
|
||||
ret = *(uchar *)(base0 + test->offset) == test->value ?
|
||||
0 : -1;
|
||||
break;
|
||||
case 2:
|
||||
ret = *(ushort *)(base0 + test->offset) == test->value ?
|
||||
0 : -1;
|
||||
break;
|
||||
case 4:
|
||||
ret = *(ulong *)(base0 + test->offset) == test->value ?
|
||||
0 : -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at store test %d !\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
107
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/string.c
Normal file
107
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/string.c
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Load/store string instructions: lswi, stswi, lswx, stswx
|
||||
*
|
||||
* Several consecutive bytes from a source memory buffer are loaded
|
||||
* left to right into GPRs. After that, the bytes are stored
|
||||
* from the GPRs into a target memory buffer. The contents
|
||||
* of the source and target buffers are then compared.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern void cpu_post_exec_02 (ulong *code, ulong op1, ulong op2);
|
||||
extern void cpu_post_exec_04 (ulong *code, ulong op1, ulong op2, ulong op3,
|
||||
ulong op4);
|
||||
|
||||
#include <bedbug/regs.h>
|
||||
int cpu_post_test_string (void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i;
|
||||
int flag = disable_interrupts();
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
char src [31], dst [31];
|
||||
|
||||
ulong code[] =
|
||||
{
|
||||
ASM_LSWI(5, 3, 31),
|
||||
ASM_STSWI(5, 4, 31),
|
||||
ASM_BLR,
|
||||
};
|
||||
|
||||
for (i = 0; i < sizeof(src); i ++)
|
||||
{
|
||||
src[i] = (char) i;
|
||||
dst[i] = 0;
|
||||
}
|
||||
|
||||
cpu_post_exec_02(code, (ulong)src, (ulong)dst);
|
||||
|
||||
ret = memcmp(src, dst, sizeof(dst)) == 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
char src [95], dst [95];
|
||||
|
||||
ulong code[] =
|
||||
{
|
||||
ASM_LSWX(8, 3, 5),
|
||||
ASM_STSWX(8, 4, 5),
|
||||
ASM_BLR,
|
||||
};
|
||||
|
||||
for (i = 0; i < sizeof(src); i ++)
|
||||
{
|
||||
src[i] = (char) i;
|
||||
dst[i] = 0;
|
||||
}
|
||||
|
||||
cpu_post_exec_04(code, (ulong)src, (ulong)dst, 0, sizeof(src));
|
||||
|
||||
ret = memcmp(src, dst, sizeof(dst)) == 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at string test !\n");
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
255
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/three.c
Normal file
255
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/three.c
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Ternary instructions instr rD,rA,rB
|
||||
*
|
||||
* Arithmetic instructions: add, addc, adde, subf, subfc, subfe,
|
||||
* mullw, mulhw, mulhwu, divw, divwu
|
||||
*
|
||||
* The test contains a pre-built table of instructions, operands and
|
||||
* expected results. For each table entry, the test will cyclically use
|
||||
* different sets of operand registers and result registers.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern void cpu_post_exec_22 (ulong *code, ulong *cr, ulong *res, ulong op1,
|
||||
ulong op2);
|
||||
extern ulong cpu_post_makecr (long v);
|
||||
|
||||
static struct cpu_post_three_s
|
||||
{
|
||||
ulong cmd;
|
||||
ulong op1;
|
||||
ulong op2;
|
||||
ulong res;
|
||||
} cpu_post_three_table[] =
|
||||
{
|
||||
{
|
||||
OP_ADD,
|
||||
100,
|
||||
200,
|
||||
300
|
||||
},
|
||||
{
|
||||
OP_ADD,
|
||||
100,
|
||||
-200,
|
||||
-100
|
||||
},
|
||||
{
|
||||
OP_ADDC,
|
||||
100,
|
||||
200,
|
||||
300
|
||||
},
|
||||
{
|
||||
OP_ADDC,
|
||||
100,
|
||||
-200,
|
||||
-100
|
||||
},
|
||||
{
|
||||
OP_ADDE,
|
||||
100,
|
||||
200,
|
||||
300
|
||||
},
|
||||
{
|
||||
OP_ADDE,
|
||||
100,
|
||||
-200,
|
||||
-100
|
||||
},
|
||||
{
|
||||
OP_SUBF,
|
||||
100,
|
||||
200,
|
||||
100
|
||||
},
|
||||
{
|
||||
OP_SUBF,
|
||||
300,
|
||||
200,
|
||||
-100
|
||||
},
|
||||
{
|
||||
OP_SUBFC,
|
||||
100,
|
||||
200,
|
||||
100
|
||||
},
|
||||
{
|
||||
OP_SUBFC,
|
||||
300,
|
||||
200,
|
||||
-100
|
||||
},
|
||||
{
|
||||
OP_SUBFE,
|
||||
100,
|
||||
200,
|
||||
200 + ~100
|
||||
},
|
||||
{
|
||||
OP_SUBFE,
|
||||
300,
|
||||
200,
|
||||
200 + ~300
|
||||
},
|
||||
{
|
||||
OP_MULLW,
|
||||
200,
|
||||
300,
|
||||
200 * 300
|
||||
},
|
||||
{
|
||||
OP_MULHW,
|
||||
0x10000000,
|
||||
0x10000000,
|
||||
0x1000000
|
||||
},
|
||||
{
|
||||
OP_MULHWU,
|
||||
0x80000000,
|
||||
0x80000000,
|
||||
0x40000000
|
||||
},
|
||||
{
|
||||
OP_DIVW,
|
||||
-20,
|
||||
5,
|
||||
-4
|
||||
},
|
||||
{
|
||||
OP_DIVWU,
|
||||
0x8000,
|
||||
0x200,
|
||||
0x40
|
||||
},
|
||||
};
|
||||
static unsigned int cpu_post_three_size = ARRAY_SIZE(cpu_post_three_table);
|
||||
|
||||
int cpu_post_test_three (void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i, reg;
|
||||
int flag = disable_interrupts();
|
||||
|
||||
for (i = 0; i < cpu_post_three_size && ret == 0; i++)
|
||||
{
|
||||
struct cpu_post_three_s *test = cpu_post_three_table + i;
|
||||
|
||||
for (reg = 0; reg < 32 && ret == 0; reg++)
|
||||
{
|
||||
unsigned int reg0 = (reg + 0) % 32;
|
||||
unsigned int reg1 = (reg + 1) % 32;
|
||||
unsigned int reg2 = (reg + 2) % 32;
|
||||
unsigned int stk = reg < 16 ? 31 : 15;
|
||||
unsigned long code[] =
|
||||
{
|
||||
ASM_STW(stk, 1, -4),
|
||||
ASM_ADDI(stk, 1, -24),
|
||||
ASM_STW(3, stk, 12),
|
||||
ASM_STW(4, stk, 16),
|
||||
ASM_STW(reg0, stk, 8),
|
||||
ASM_STW(reg1, stk, 4),
|
||||
ASM_STW(reg2, stk, 0),
|
||||
ASM_LWZ(reg1, stk, 12),
|
||||
ASM_LWZ(reg0, stk, 16),
|
||||
ASM_12(test->cmd, reg2, reg1, reg0),
|
||||
ASM_STW(reg2, stk, 12),
|
||||
ASM_LWZ(reg2, stk, 0),
|
||||
ASM_LWZ(reg1, stk, 4),
|
||||
ASM_LWZ(reg0, stk, 8),
|
||||
ASM_LWZ(3, stk, 12),
|
||||
ASM_ADDI(1, stk, 24),
|
||||
ASM_LWZ(stk, 1, -4),
|
||||
ASM_BLR,
|
||||
};
|
||||
unsigned long codecr[] =
|
||||
{
|
||||
ASM_STW(stk, 1, -4),
|
||||
ASM_ADDI(stk, 1, -24),
|
||||
ASM_STW(3, stk, 12),
|
||||
ASM_STW(4, stk, 16),
|
||||
ASM_STW(reg0, stk, 8),
|
||||
ASM_STW(reg1, stk, 4),
|
||||
ASM_STW(reg2, stk, 0),
|
||||
ASM_LWZ(reg1, stk, 12),
|
||||
ASM_LWZ(reg0, stk, 16),
|
||||
ASM_12(test->cmd, reg2, reg1, reg0) | BIT_C,
|
||||
ASM_STW(reg2, stk, 12),
|
||||
ASM_LWZ(reg2, stk, 0),
|
||||
ASM_LWZ(reg1, stk, 4),
|
||||
ASM_LWZ(reg0, stk, 8),
|
||||
ASM_LWZ(3, stk, 12),
|
||||
ASM_ADDI(1, stk, 24),
|
||||
ASM_LWZ(stk, 1, -4),
|
||||
ASM_BLR,
|
||||
};
|
||||
ulong res;
|
||||
ulong cr;
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
cr = 0;
|
||||
cpu_post_exec_22 (code, & cr, & res, test->op1, test->op2);
|
||||
|
||||
ret = res == test->res && cr == 0 ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at three test %d !\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
cpu_post_exec_22 (codecr, & cr, & res, test->op1, test->op2);
|
||||
|
||||
ret = res == test->res &&
|
||||
(cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at three test %d !\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
133
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/threei.c
Normal file
133
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/threei.c
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Ternary instructions instr rA,rS,UIMM
|
||||
*
|
||||
* Logic instructions: ori, oris, xori, xoris
|
||||
*
|
||||
* The test contains a pre-built table of instructions, operands and
|
||||
* expected results. For each table entry, the test will cyclically use
|
||||
* different sets of operand registers and result registers.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op);
|
||||
extern ulong cpu_post_makecr (long v);
|
||||
|
||||
static struct cpu_post_threei_s
|
||||
{
|
||||
ulong cmd;
|
||||
ulong op1;
|
||||
ushort op2;
|
||||
ulong res;
|
||||
} cpu_post_threei_table[] =
|
||||
{
|
||||
{
|
||||
OP_ORI,
|
||||
0x80000000,
|
||||
0xffff,
|
||||
0x8000ffff
|
||||
},
|
||||
{
|
||||
OP_ORIS,
|
||||
0x00008000,
|
||||
0xffff,
|
||||
0xffff8000
|
||||
},
|
||||
{
|
||||
OP_XORI,
|
||||
0x8000ffff,
|
||||
0xffff,
|
||||
0x80000000
|
||||
},
|
||||
{
|
||||
OP_XORIS,
|
||||
0x00008000,
|
||||
0xffff,
|
||||
0xffff8000
|
||||
},
|
||||
};
|
||||
static unsigned int cpu_post_threei_size = ARRAY_SIZE(cpu_post_threei_table);
|
||||
|
||||
int cpu_post_test_threei (void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i, reg;
|
||||
int flag = disable_interrupts();
|
||||
|
||||
for (i = 0; i < cpu_post_threei_size && ret == 0; i++)
|
||||
{
|
||||
struct cpu_post_threei_s *test = cpu_post_threei_table + i;
|
||||
|
||||
for (reg = 0; reg < 32 && ret == 0; reg++)
|
||||
{
|
||||
unsigned int reg0 = (reg + 0) % 32;
|
||||
unsigned int reg1 = (reg + 1) % 32;
|
||||
unsigned int stk = reg < 16 ? 31 : 15;
|
||||
unsigned long code[] =
|
||||
{
|
||||
ASM_STW(stk, 1, -4),
|
||||
ASM_ADDI(stk, 1, -16),
|
||||
ASM_STW(3, stk, 8),
|
||||
ASM_STW(reg0, stk, 4),
|
||||
ASM_STW(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 8),
|
||||
ASM_11IX(test->cmd, reg1, reg0, test->op2),
|
||||
ASM_STW(reg1, stk, 8),
|
||||
ASM_LWZ(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 4),
|
||||
ASM_LWZ(3, stk, 8),
|
||||
ASM_ADDI(1, stk, 16),
|
||||
ASM_LWZ(stk, 1, -4),
|
||||
ASM_BLR,
|
||||
};
|
||||
ulong res;
|
||||
ulong cr;
|
||||
|
||||
cr = 0;
|
||||
cpu_post_exec_21 (code, & cr, & res, test->op1);
|
||||
|
||||
ret = res == test->res && cr == 0 ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at threei test %d !\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
225
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/threex.c
Normal file
225
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/threex.c
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Ternary instructions instr rA,rS,rB
|
||||
*
|
||||
* Logic instructions: or, orc, xor, nand, nor, eqv
|
||||
* Shift instructions: slw, srw, sraw
|
||||
*
|
||||
* The test contains a pre-built table of instructions, operands and
|
||||
* expected results. For each table entry, the test will cyclically use
|
||||
* different sets of operand registers and result registers.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern void cpu_post_exec_22 (ulong *code, ulong *cr, ulong *res, ulong op1,
|
||||
ulong op2);
|
||||
extern ulong cpu_post_makecr (long v);
|
||||
|
||||
static struct cpu_post_threex_s
|
||||
{
|
||||
ulong cmd;
|
||||
ulong op1;
|
||||
ulong op2;
|
||||
ulong res;
|
||||
} cpu_post_threex_table[] =
|
||||
{
|
||||
{
|
||||
OP_OR,
|
||||
0x1234,
|
||||
0x5678,
|
||||
0x1234 | 0x5678
|
||||
},
|
||||
{
|
||||
OP_ORC,
|
||||
0x1234,
|
||||
0x5678,
|
||||
0x1234 | ~0x5678
|
||||
},
|
||||
{
|
||||
OP_XOR,
|
||||
0x1234,
|
||||
0x5678,
|
||||
0x1234 ^ 0x5678
|
||||
},
|
||||
{
|
||||
OP_NAND,
|
||||
0x1234,
|
||||
0x5678,
|
||||
~(0x1234 & 0x5678)
|
||||
},
|
||||
{
|
||||
OP_NOR,
|
||||
0x1234,
|
||||
0x5678,
|
||||
~(0x1234 | 0x5678)
|
||||
},
|
||||
{
|
||||
OP_EQV,
|
||||
0x1234,
|
||||
0x5678,
|
||||
~(0x1234 ^ 0x5678)
|
||||
},
|
||||
{
|
||||
OP_SLW,
|
||||
0x80,
|
||||
16,
|
||||
0x800000
|
||||
},
|
||||
{
|
||||
OP_SLW,
|
||||
0x80,
|
||||
32,
|
||||
0
|
||||
},
|
||||
{
|
||||
OP_SRW,
|
||||
0x800000,
|
||||
16,
|
||||
0x80
|
||||
},
|
||||
{
|
||||
OP_SRW,
|
||||
0x800000,
|
||||
32,
|
||||
0
|
||||
},
|
||||
{
|
||||
OP_SRAW,
|
||||
0x80000000,
|
||||
3,
|
||||
0xf0000000
|
||||
},
|
||||
{
|
||||
OP_SRAW,
|
||||
0x8000,
|
||||
3,
|
||||
0x1000
|
||||
},
|
||||
};
|
||||
static unsigned int cpu_post_threex_size = ARRAY_SIZE(cpu_post_threex_table);
|
||||
|
||||
int cpu_post_test_threex (void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i, reg;
|
||||
int flag = disable_interrupts();
|
||||
|
||||
for (i = 0; i < cpu_post_threex_size && ret == 0; i++)
|
||||
{
|
||||
struct cpu_post_threex_s *test = cpu_post_threex_table + i;
|
||||
|
||||
for (reg = 0; reg < 32 && ret == 0; reg++)
|
||||
{
|
||||
unsigned int reg0 = (reg + 0) % 32;
|
||||
unsigned int reg1 = (reg + 1) % 32;
|
||||
unsigned int reg2 = (reg + 2) % 32;
|
||||
unsigned int stk = reg < 16 ? 31 : 15;
|
||||
unsigned long code[] =
|
||||
{
|
||||
ASM_STW(stk, 1, -4),
|
||||
ASM_ADDI(stk, 1, -24),
|
||||
ASM_STW(3, stk, 12),
|
||||
ASM_STW(4, stk, 16),
|
||||
ASM_STW(reg0, stk, 8),
|
||||
ASM_STW(reg1, stk, 4),
|
||||
ASM_STW(reg2, stk, 0),
|
||||
ASM_LWZ(reg1, stk, 12),
|
||||
ASM_LWZ(reg0, stk, 16),
|
||||
ASM_12X(test->cmd, reg2, reg1, reg0),
|
||||
ASM_STW(reg2, stk, 12),
|
||||
ASM_LWZ(reg2, stk, 0),
|
||||
ASM_LWZ(reg1, stk, 4),
|
||||
ASM_LWZ(reg0, stk, 8),
|
||||
ASM_LWZ(3, stk, 12),
|
||||
ASM_ADDI(1, stk, 24),
|
||||
ASM_LWZ(stk, 1, -4),
|
||||
ASM_BLR,
|
||||
};
|
||||
unsigned long codecr[] =
|
||||
{
|
||||
ASM_STW(stk, 1, -4),
|
||||
ASM_ADDI(stk, 1, -24),
|
||||
ASM_STW(3, stk, 12),
|
||||
ASM_STW(4, stk, 16),
|
||||
ASM_STW(reg0, stk, 8),
|
||||
ASM_STW(reg1, stk, 4),
|
||||
ASM_STW(reg2, stk, 0),
|
||||
ASM_LWZ(reg1, stk, 12),
|
||||
ASM_LWZ(reg0, stk, 16),
|
||||
ASM_12X(test->cmd, reg2, reg1, reg0) | BIT_C,
|
||||
ASM_STW(reg2, stk, 12),
|
||||
ASM_LWZ(reg2, stk, 0),
|
||||
ASM_LWZ(reg1, stk, 4),
|
||||
ASM_LWZ(reg0, stk, 8),
|
||||
ASM_LWZ(3, stk, 12),
|
||||
ASM_ADDI(1, stk, 24),
|
||||
ASM_LWZ(stk, 1, -4),
|
||||
ASM_BLR,
|
||||
};
|
||||
ulong res;
|
||||
ulong cr;
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
cr = 0;
|
||||
cpu_post_exec_22 (code, & cr, & res, test->op1, test->op2);
|
||||
|
||||
ret = res == test->res && cr == 0 ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at threex test %d !\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
cpu_post_exec_22 (codecr, & cr, & res, test->op1, test->op2);
|
||||
|
||||
ret = res == test->res &&
|
||||
(cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at threex test %d !\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
172
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/two.c
Normal file
172
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/two.c
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Binary instructions instr rD,rA
|
||||
*
|
||||
* Logic instructions: neg
|
||||
* Arithmetic instructions: addme, addze, subfme, subfze
|
||||
|
||||
* The test contains a pre-built table of instructions, operands and
|
||||
* expected results. For each table entry, the test will cyclically use
|
||||
* different sets of operand registers and result registers.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op1);
|
||||
extern ulong cpu_post_makecr (long v);
|
||||
|
||||
static struct cpu_post_two_s
|
||||
{
|
||||
ulong cmd;
|
||||
ulong op;
|
||||
ulong res;
|
||||
} cpu_post_two_table[] =
|
||||
{
|
||||
{
|
||||
OP_NEG,
|
||||
3,
|
||||
-3
|
||||
},
|
||||
{
|
||||
OP_NEG,
|
||||
5,
|
||||
-5
|
||||
},
|
||||
{
|
||||
OP_ADDME,
|
||||
6,
|
||||
5
|
||||
},
|
||||
{
|
||||
OP_ADDZE,
|
||||
5,
|
||||
5
|
||||
},
|
||||
{
|
||||
OP_SUBFME,
|
||||
6,
|
||||
~6 - 1
|
||||
},
|
||||
{
|
||||
OP_SUBFZE,
|
||||
5,
|
||||
~5
|
||||
},
|
||||
};
|
||||
static unsigned int cpu_post_two_size = ARRAY_SIZE(cpu_post_two_table);
|
||||
|
||||
int cpu_post_test_two (void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i, reg;
|
||||
int flag = disable_interrupts();
|
||||
|
||||
for (i = 0; i < cpu_post_two_size && ret == 0; i++)
|
||||
{
|
||||
struct cpu_post_two_s *test = cpu_post_two_table + i;
|
||||
|
||||
for (reg = 0; reg < 32 && ret == 0; reg++)
|
||||
{
|
||||
unsigned int reg0 = (reg + 0) % 32;
|
||||
unsigned int reg1 = (reg + 1) % 32;
|
||||
unsigned int stk = reg < 16 ? 31 : 15;
|
||||
unsigned long code[] =
|
||||
{
|
||||
ASM_STW(stk, 1, -4),
|
||||
ASM_ADDI(stk, 1, -16),
|
||||
ASM_STW(3, stk, 8),
|
||||
ASM_STW(reg0, stk, 4),
|
||||
ASM_STW(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 8),
|
||||
ASM_11(test->cmd, reg1, reg0),
|
||||
ASM_STW(reg1, stk, 8),
|
||||
ASM_LWZ(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 4),
|
||||
ASM_LWZ(3, stk, 8),
|
||||
ASM_ADDI(1, stk, 16),
|
||||
ASM_LWZ(stk, 1, -4),
|
||||
ASM_BLR,
|
||||
};
|
||||
unsigned long codecr[] =
|
||||
{
|
||||
ASM_STW(stk, 1, -4),
|
||||
ASM_ADDI(stk, 1, -16),
|
||||
ASM_STW(3, stk, 8),
|
||||
ASM_STW(reg0, stk, 4),
|
||||
ASM_STW(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 8),
|
||||
ASM_11(test->cmd, reg1, reg0) | BIT_C,
|
||||
ASM_STW(reg1, stk, 8),
|
||||
ASM_LWZ(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 4),
|
||||
ASM_LWZ(3, stk, 8),
|
||||
ASM_ADDI(1, stk, 16),
|
||||
ASM_LWZ(stk, 1, -4),
|
||||
ASM_BLR,
|
||||
};
|
||||
ulong res;
|
||||
ulong cr;
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
cr = 0;
|
||||
cpu_post_exec_21 (code, & cr, & res, test->op);
|
||||
|
||||
ret = res == test->res && cr == 0 ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at two test %d !\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
cpu_post_exec_21 (codecr, & cr, & res, test->op);
|
||||
|
||||
ret = res == test->res &&
|
||||
(cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at two test %d !\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
172
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/twox.c
Normal file
172
common/package/boot/uboot-ipq40xx/src/post/lib_powerpc/twox.c
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/*
|
||||
* CPU test
|
||||
* Binary instructions instr rA,rS
|
||||
*
|
||||
* Logic instructions: cntlzw
|
||||
* Arithmetic instructions: extsb, extsh
|
||||
|
||||
* The test contains a pre-built table of instructions, operands and
|
||||
* expected results. For each table entry, the test will cyclically use
|
||||
* different sets of operand registers and result registers.
|
||||
*/
|
||||
|
||||
#include <post.h>
|
||||
#include "cpu_asm.h"
|
||||
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
|
||||
extern void cpu_post_exec_21 (ulong *code, ulong *cr, ulong *res, ulong op1);
|
||||
extern ulong cpu_post_makecr (long v);
|
||||
|
||||
static struct cpu_post_twox_s
|
||||
{
|
||||
ulong cmd;
|
||||
ulong op;
|
||||
ulong res;
|
||||
} cpu_post_twox_table[] =
|
||||
{
|
||||
{
|
||||
OP_EXTSB,
|
||||
3,
|
||||
3
|
||||
},
|
||||
{
|
||||
OP_EXTSB,
|
||||
0xff,
|
||||
-1
|
||||
},
|
||||
{
|
||||
OP_EXTSH,
|
||||
3,
|
||||
3
|
||||
},
|
||||
{
|
||||
OP_EXTSH,
|
||||
0xff,
|
||||
0xff
|
||||
},
|
||||
{
|
||||
OP_EXTSH,
|
||||
0xffff,
|
||||
-1
|
||||
},
|
||||
{
|
||||
OP_CNTLZW,
|
||||
0x000fffff,
|
||||
12
|
||||
},
|
||||
};
|
||||
static unsigned int cpu_post_twox_size = ARRAY_SIZE(cpu_post_twox_table);
|
||||
|
||||
int cpu_post_test_twox (void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int i, reg;
|
||||
int flag = disable_interrupts();
|
||||
|
||||
for (i = 0; i < cpu_post_twox_size && ret == 0; i++)
|
||||
{
|
||||
struct cpu_post_twox_s *test = cpu_post_twox_table + i;
|
||||
|
||||
for (reg = 0; reg < 32 && ret == 0; reg++)
|
||||
{
|
||||
unsigned int reg0 = (reg + 0) % 32;
|
||||
unsigned int reg1 = (reg + 1) % 32;
|
||||
unsigned int stk = reg < 16 ? 31 : 15;
|
||||
unsigned long code[] =
|
||||
{
|
||||
ASM_STW(stk, 1, -4),
|
||||
ASM_ADDI(stk, 1, -16),
|
||||
ASM_STW(3, stk, 8),
|
||||
ASM_STW(reg0, stk, 4),
|
||||
ASM_STW(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 8),
|
||||
ASM_11X(test->cmd, reg1, reg0),
|
||||
ASM_STW(reg1, stk, 8),
|
||||
ASM_LWZ(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 4),
|
||||
ASM_LWZ(3, stk, 8),
|
||||
ASM_ADDI(1, stk, 16),
|
||||
ASM_LWZ(stk, 1, -4),
|
||||
ASM_BLR,
|
||||
};
|
||||
unsigned long codecr[] =
|
||||
{
|
||||
ASM_STW(stk, 1, -4),
|
||||
ASM_ADDI(stk, 1, -16),
|
||||
ASM_STW(3, stk, 8),
|
||||
ASM_STW(reg0, stk, 4),
|
||||
ASM_STW(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 8),
|
||||
ASM_11X(test->cmd, reg1, reg0) | BIT_C,
|
||||
ASM_STW(reg1, stk, 8),
|
||||
ASM_LWZ(reg1, stk, 0),
|
||||
ASM_LWZ(reg0, stk, 4),
|
||||
ASM_LWZ(3, stk, 8),
|
||||
ASM_ADDI(1, stk, 16),
|
||||
ASM_LWZ(stk, 1, -4),
|
||||
ASM_BLR,
|
||||
};
|
||||
ulong res;
|
||||
ulong cr;
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
cr = 0;
|
||||
cpu_post_exec_21 (code, & cr, & res, test->op);
|
||||
|
||||
ret = res == test->res && cr == 0 ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at twox test %d !\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
cpu_post_exec_21 (codecr, & cr, & res, test->op);
|
||||
|
||||
ret = res == test->res &&
|
||||
(cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
post_log ("Error at twox test %d !\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
505
common/package/boot/uboot-ipq40xx/src/post/post.c
Normal file
505
common/package/boot/uboot-ipq40xx/src/post/post.c
Normal file
|
|
@ -0,0 +1,505 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <stdio_dev.h>
|
||||
#include <watchdog.h>
|
||||
#include <div64.h>
|
||||
#include <post.h>
|
||||
|
||||
#ifdef CONFIG_SYS_POST_HOTKEYS_GPIO
|
||||
#include <asm/gpio.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LOGBUFFER
|
||||
#include <logbuff.h>
|
||||
#endif
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define POST_MAX_NUMBER 32
|
||||
|
||||
#define BOOTMODE_MAGIC 0xDEAD0000
|
||||
|
||||
int post_init_f(void)
|
||||
{
|
||||
int res = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < post_list_size; i++) {
|
||||
struct post_test *test = post_list + i;
|
||||
|
||||
if (test->init_f && test->init_f())
|
||||
res = -1;
|
||||
}
|
||||
|
||||
gd->post_init_f_time = post_time_ms(0);
|
||||
if (!gd->post_init_f_time)
|
||||
printf("%s: post_time_ms not implemented\n", __FILE__);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Supply a default implementation for post_hotkeys_pressed() for boards
|
||||
* without hotkey support. We always return 0 here, so that the
|
||||
* long-running tests won't be started.
|
||||
*
|
||||
* Boards with hotkey support can override this weak default function
|
||||
* by defining one in their board specific code.
|
||||
*/
|
||||
int __post_hotkeys_pressed(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_POST_HOTKEYS_GPIO
|
||||
int ret;
|
||||
unsigned gpio = CONFIG_SYS_POST_HOTKEYS_GPIO;
|
||||
|
||||
ret = gpio_request(gpio, "hotkeys");
|
||||
if (ret) {
|
||||
printf("POST: gpio hotkey request failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
gpio_direction_input(gpio);
|
||||
ret = gpio_get_value(gpio);
|
||||
gpio_free(gpio);
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
return 0; /* No hotkeys supported */
|
||||
}
|
||||
int post_hotkeys_pressed(void)
|
||||
__attribute__((weak, alias("__post_hotkeys_pressed")));
|
||||
|
||||
|
||||
void post_bootmode_init(void)
|
||||
{
|
||||
int bootmode = post_bootmode_get(0);
|
||||
int newword;
|
||||
|
||||
if (post_hotkeys_pressed() && !(bootmode & POST_POWERTEST))
|
||||
newword = BOOTMODE_MAGIC | POST_SLOWTEST;
|
||||
else if (bootmode == 0)
|
||||
newword = BOOTMODE_MAGIC | POST_POWERON;
|
||||
else if (bootmode == POST_POWERON || bootmode == POST_SLOWTEST)
|
||||
newword = BOOTMODE_MAGIC | POST_NORMAL;
|
||||
else
|
||||
/* Use old value */
|
||||
newword = post_word_load() & ~POST_COLDBOOT;
|
||||
|
||||
if (bootmode == 0)
|
||||
/* We are booting after power-on */
|
||||
newword |= POST_COLDBOOT;
|
||||
|
||||
post_word_store(newword);
|
||||
|
||||
/* Reset activity record */
|
||||
gd->post_log_word = 0;
|
||||
gd->post_log_res = 0;
|
||||
}
|
||||
|
||||
int post_bootmode_get(unsigned int *last_test)
|
||||
{
|
||||
unsigned long word = post_word_load();
|
||||
int bootmode;
|
||||
|
||||
if ((word & 0xFFFF0000) != BOOTMODE_MAGIC)
|
||||
return 0;
|
||||
|
||||
bootmode = word & 0x7F;
|
||||
|
||||
if (last_test && (bootmode & POST_POWERTEST))
|
||||
*last_test = (word >> 8) & 0xFF;
|
||||
|
||||
return bootmode;
|
||||
}
|
||||
|
||||
/* POST tests run before relocation only mark status bits .... */
|
||||
static void post_log_mark_start(unsigned long testid)
|
||||
{
|
||||
gd->post_log_word |= testid;
|
||||
}
|
||||
|
||||
static void post_log_mark_succ(unsigned long testid)
|
||||
{
|
||||
gd->post_log_res |= testid;
|
||||
}
|
||||
|
||||
/* ... and the messages are output once we are relocated */
|
||||
void post_output_backlog(void)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < post_list_size; j++) {
|
||||
if (gd->post_log_word & (post_list[j].testid)) {
|
||||
post_log("POST %s ", post_list[j].cmd);
|
||||
if (gd->post_log_res & post_list[j].testid)
|
||||
post_log("PASSED\n");
|
||||
else {
|
||||
post_log("FAILED\n");
|
||||
bootstage_error(BOOTSTAGE_ID_POST_FAIL_R);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void post_bootmode_test_on(unsigned int last_test)
|
||||
{
|
||||
unsigned long word = post_word_load();
|
||||
|
||||
word |= POST_POWERTEST;
|
||||
|
||||
word |= (last_test & 0xFF) << 8;
|
||||
|
||||
post_word_store(word);
|
||||
}
|
||||
|
||||
static void post_bootmode_test_off(void)
|
||||
{
|
||||
unsigned long word = post_word_load();
|
||||
|
||||
word &= ~POST_POWERTEST;
|
||||
|
||||
post_word_store(word);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_POST_SKIP_ENV_FLAGS
|
||||
static void post_get_env_flags(int *test_flags)
|
||||
{
|
||||
int flag[] = { POST_POWERON, POST_NORMAL, POST_SLOWTEST,
|
||||
POST_CRITICAL };
|
||||
char *var[] = { "post_poweron", "post_normal", "post_slowtest",
|
||||
"post_critical" };
|
||||
int varnum = ARRAY_SIZE(var);
|
||||
char list[128]; /* long enough for POST list */
|
||||
char *name;
|
||||
char *s;
|
||||
int last;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < varnum; i++) {
|
||||
if (getenv_f(var[i], list, sizeof(list)) <= 0)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < post_list_size; j++)
|
||||
test_flags[j] &= ~flag[i];
|
||||
|
||||
last = 0;
|
||||
name = list;
|
||||
while (!last) {
|
||||
while (*name && *name == ' ')
|
||||
name++;
|
||||
if (*name == 0)
|
||||
break;
|
||||
s = name + 1;
|
||||
while (*s && *s != ' ')
|
||||
s++;
|
||||
if (*s == 0)
|
||||
last = 1;
|
||||
else
|
||||
*s = 0;
|
||||
|
||||
for (j = 0; j < post_list_size; j++) {
|
||||
if (strcmp(post_list[j].cmd, name) == 0) {
|
||||
test_flags[j] |= flag[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == post_list_size)
|
||||
printf("No such test: %s\n", name);
|
||||
|
||||
name = s + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void post_get_flags(int *test_flags)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < post_list_size; j++)
|
||||
test_flags[j] = post_list[j].flags;
|
||||
|
||||
#ifndef CONFIG_POST_SKIP_ENV_FLAGS
|
||||
post_get_env_flags(test_flags);
|
||||
#endif
|
||||
|
||||
for (j = 0; j < post_list_size; j++)
|
||||
if (test_flags[j] & POST_POWERON)
|
||||
test_flags[j] |= POST_SLOWTEST;
|
||||
}
|
||||
|
||||
void __show_post_progress(unsigned int test_num, int before, int result)
|
||||
{
|
||||
}
|
||||
void show_post_progress(unsigned int, int, int)
|
||||
__attribute__((weak, alias("__show_post_progress")));
|
||||
|
||||
static int post_run_single(struct post_test *test,
|
||||
int test_flags, int flags, unsigned int i)
|
||||
{
|
||||
if ((flags & test_flags & POST_ALWAYS) &&
|
||||
(flags & test_flags & POST_MEM)) {
|
||||
WATCHDOG_RESET();
|
||||
|
||||
if (!(flags & POST_REBOOT)) {
|
||||
if ((test_flags & POST_REBOOT) &&
|
||||
!(flags & POST_MANUAL)) {
|
||||
post_bootmode_test_on(
|
||||
(gd->flags & GD_FLG_POSTFAIL) ?
|
||||
POST_FAIL_SAVE | i : i);
|
||||
}
|
||||
|
||||
if (test_flags & POST_PREREL)
|
||||
post_log_mark_start(test->testid);
|
||||
else
|
||||
post_log("POST %s ", test->cmd);
|
||||
}
|
||||
|
||||
show_post_progress(i, POST_BEFORE, POST_FAILED);
|
||||
|
||||
if (test_flags & POST_PREREL) {
|
||||
if ((*test->test)(flags) == 0) {
|
||||
post_log_mark_succ(test->testid);
|
||||
show_post_progress(i, POST_AFTER, POST_PASSED);
|
||||
} else {
|
||||
show_post_progress(i, POST_AFTER, POST_FAILED);
|
||||
if (test_flags & POST_CRITICAL)
|
||||
gd->flags |= GD_FLG_POSTFAIL;
|
||||
if (test_flags & POST_STOP)
|
||||
gd->flags |= GD_FLG_POSTSTOP;
|
||||
}
|
||||
} else {
|
||||
if ((*test->test)(flags) != 0) {
|
||||
post_log("FAILED\n");
|
||||
bootstage_error(BOOTSTAGE_ID_POST_FAIL_R);
|
||||
show_post_progress(i, POST_AFTER, POST_FAILED);
|
||||
if (test_flags & POST_CRITICAL)
|
||||
gd->flags |= GD_FLG_POSTFAIL;
|
||||
if (test_flags & POST_STOP)
|
||||
gd->flags |= GD_FLG_POSTSTOP;
|
||||
} else {
|
||||
post_log("PASSED\n");
|
||||
show_post_progress(i, POST_AFTER, POST_PASSED);
|
||||
}
|
||||
}
|
||||
|
||||
if ((test_flags & POST_REBOOT) && !(flags & POST_MANUAL))
|
||||
post_bootmode_test_off();
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int post_run(char *name, int flags)
|
||||
{
|
||||
unsigned int i;
|
||||
int test_flags[POST_MAX_NUMBER];
|
||||
|
||||
post_get_flags(test_flags);
|
||||
|
||||
if (name == NULL) {
|
||||
unsigned int last;
|
||||
|
||||
if (gd->flags & GD_FLG_POSTSTOP)
|
||||
return 0;
|
||||
|
||||
if (post_bootmode_get(&last) & POST_POWERTEST) {
|
||||
if (last & POST_FAIL_SAVE) {
|
||||
last &= ~POST_FAIL_SAVE;
|
||||
gd->flags |= GD_FLG_POSTFAIL;
|
||||
}
|
||||
if (last < post_list_size &&
|
||||
(flags & test_flags[last] & POST_ALWAYS) &&
|
||||
(flags & test_flags[last] & POST_MEM)) {
|
||||
|
||||
post_run_single(post_list + last,
|
||||
test_flags[last],
|
||||
flags | POST_REBOOT, last);
|
||||
|
||||
for (i = last + 1; i < post_list_size; i++) {
|
||||
if (gd->flags & GD_FLG_POSTSTOP)
|
||||
break;
|
||||
post_run_single(post_list + i,
|
||||
test_flags[i],
|
||||
flags, i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < post_list_size; i++) {
|
||||
if (gd->flags & GD_FLG_POSTSTOP)
|
||||
break;
|
||||
post_run_single(post_list + i,
|
||||
test_flags[i],
|
||||
flags, i);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
for (i = 0; i < post_list_size; i++) {
|
||||
if (strcmp(post_list[i].cmd, name) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < post_list_size) {
|
||||
WATCHDOG_RESET();
|
||||
return post_run_single(post_list + i,
|
||||
test_flags[i],
|
||||
flags, i);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int post_info_single(struct post_test *test, int full)
|
||||
{
|
||||
if (test->flags & POST_MANUAL) {
|
||||
if (full)
|
||||
printf("%s - %s\n"
|
||||
" %s\n", test->cmd, test->name, test->desc);
|
||||
else
|
||||
printf(" %-15s - %s\n", test->cmd, test->name);
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int post_info(char *name)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (name == NULL) {
|
||||
for (i = 0; i < post_list_size; i++)
|
||||
post_info_single(post_list + i, 0);
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
for (i = 0; i < post_list_size; i++) {
|
||||
if (strcmp(post_list[i].cmd, name) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < post_list_size)
|
||||
return post_info_single(post_list + i, 1);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int post_log(char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char printbuffer[CONFIG_SYS_PBSIZE];
|
||||
|
||||
va_start(args, format);
|
||||
|
||||
/* For this to work, printbuffer must be larger than
|
||||
* anything we ever want to print.
|
||||
*/
|
||||
vsprintf(printbuffer, format, args);
|
||||
va_end(args);
|
||||
|
||||
#ifdef CONFIG_LOGBUFFER
|
||||
/* Send to the logbuffer */
|
||||
logbuff_log(printbuffer);
|
||||
#else
|
||||
/* Send to the stdout file */
|
||||
puts(printbuffer);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NEEDS_MANUAL_RELOC
|
||||
void post_reloc(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/*
|
||||
* We have to relocate the test table manually
|
||||
*/
|
||||
for (i = 0; i < post_list_size; i++) {
|
||||
ulong addr;
|
||||
struct post_test *test = post_list + i;
|
||||
|
||||
if (test->name) {
|
||||
addr = (ulong)(test->name) + gd->reloc_off;
|
||||
test->name = (char *)addr;
|
||||
}
|
||||
|
||||
if (test->cmd) {
|
||||
addr = (ulong)(test->cmd) + gd->reloc_off;
|
||||
test->cmd = (char *)addr;
|
||||
}
|
||||
|
||||
if (test->desc) {
|
||||
addr = (ulong)(test->desc) + gd->reloc_off;
|
||||
test->desc = (char *)addr;
|
||||
}
|
||||
|
||||
if (test->test) {
|
||||
addr = (ulong)(test->test) + gd->reloc_off;
|
||||
test->test = (int (*)(int flags)) addr;
|
||||
}
|
||||
|
||||
if (test->init_f) {
|
||||
addr = (ulong)(test->init_f) + gd->reloc_off;
|
||||
test->init_f = (int (*)(void)) addr;
|
||||
}
|
||||
|
||||
if (test->reloc) {
|
||||
addr = (ulong)(test->reloc) + gd->reloc_off;
|
||||
test->reloc = (void (*)(void)) addr;
|
||||
|
||||
test->reloc();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Some tests (e.g. SYSMON) need the time when post_init_f started,
|
||||
* but we cannot use get_timer() at this point.
|
||||
*
|
||||
* On PowerPC we implement it using the timebase register.
|
||||
*/
|
||||
unsigned long post_time_ms(unsigned long base)
|
||||
{
|
||||
#if defined(CONFIG_PPC) || defined(CONFIG_BLACKFIN) || defined(CONFIG_ARM)
|
||||
return (unsigned long)lldiv(get_ticks(), get_tbclk() / CONFIG_SYS_HZ)
|
||||
- base;
|
||||
#else
|
||||
#warning "Not implemented yet"
|
||||
return 0; /* Not implemented yet */
|
||||
#endif
|
||||
}
|
||||
46
common/package/boot/uboot-ipq40xx/src/post/rules.mk
Normal file
46
common/package/boot/uboot-ipq40xx/src/post/rules.mk
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#
|
||||
# (C) Copyright 2002-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
COBJS := $(COBJS-y)
|
||||
AOBJS := $(AOBJS-y)
|
||||
SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS))
|
||||
LIB := $(obj)$(LIB)
|
||||
|
||||
CPPFLAGS += -I$(TOPDIR)
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
336
common/package/boot/uboot-ipq40xx/src/post/tests.c
Normal file
336
common/package/boot/uboot-ipq40xx/src/post/tests.c
Normal file
|
|
@ -0,0 +1,336 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*
|
||||
* Be sure to mark tests to be run before relocation as such with the
|
||||
* CONFIG_SYS_POST_PREREL flag so that logging is done correctly if the
|
||||
* logbuffer support is enabled.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#include <post.h>
|
||||
|
||||
extern int ocm_post_test (int flags);
|
||||
extern int cache_post_test (int flags);
|
||||
extern int watchdog_post_test (int flags);
|
||||
extern int i2c_post_test (int flags);
|
||||
extern int rtc_post_test (int flags);
|
||||
extern int memory_post_test (int flags);
|
||||
extern int cpu_post_test (int flags);
|
||||
extern int fpu_post_test (int flags);
|
||||
extern int uart_post_test (int flags);
|
||||
extern int ether_post_test (int flags);
|
||||
extern int spi_post_test (int flags);
|
||||
extern int usb_post_test (int flags);
|
||||
extern int spr_post_test (int flags);
|
||||
extern int sysmon_post_test (int flags);
|
||||
extern int dsp_post_test (int flags);
|
||||
extern int codec_post_test (int flags);
|
||||
extern int ecc_post_test (int flags);
|
||||
extern int flash_post_test(int flags);
|
||||
|
||||
extern int dspic_init_post_test (int flags);
|
||||
extern int dspic_post_test (int flags);
|
||||
extern int gdc_post_test (int flags);
|
||||
extern int fpga_post_test (int flags);
|
||||
extern int lwmon5_watchdog_post_test(int flags);
|
||||
extern int sysmon1_post_test(int flags);
|
||||
extern int coprocessor_post_test(int flags);
|
||||
extern int led_post_test(int flags);
|
||||
extern int button_post_test(int flags);
|
||||
extern int memory_regions_post_test(int flags);
|
||||
|
||||
extern int sysmon_init_f (void);
|
||||
|
||||
extern void sysmon_reloc (void);
|
||||
|
||||
|
||||
struct post_test post_list[] =
|
||||
{
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_OCM
|
||||
{
|
||||
"OCM test",
|
||||
"ocm",
|
||||
"This test checks on chip memory (OCM).",
|
||||
POST_ROM | POST_ALWAYS | POST_PREREL | POST_CRITICAL | POST_STOP,
|
||||
&ocm_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_OCM
|
||||
},
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CACHE
|
||||
{
|
||||
"Cache test",
|
||||
"cache",
|
||||
"This test verifies the CPU cache operation.",
|
||||
POST_RAM | POST_ALWAYS,
|
||||
&cache_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_CACHE
|
||||
},
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_WATCHDOG
|
||||
#if defined(CONFIG_POST_WATCHDOG)
|
||||
CONFIG_POST_WATCHDOG,
|
||||
#else
|
||||
{
|
||||
"Watchdog timer test",
|
||||
"watchdog",
|
||||
"This test checks the watchdog timer.",
|
||||
POST_RAM | POST_POWERON | POST_SLOWTEST | POST_MANUAL | POST_REBOOT,
|
||||
&watchdog_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_WATCHDOG
|
||||
},
|
||||
#endif
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_I2C
|
||||
{
|
||||
"I2C test",
|
||||
"i2c",
|
||||
"This test verifies the I2C operation.",
|
||||
POST_RAM | POST_ALWAYS,
|
||||
&i2c_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_I2C
|
||||
},
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_RTC
|
||||
{
|
||||
"RTC test",
|
||||
"rtc",
|
||||
"This test verifies the RTC operation.",
|
||||
POST_RAM | POST_SLOWTEST | POST_MANUAL,
|
||||
&rtc_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_RTC
|
||||
},
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_MEMORY
|
||||
{
|
||||
"Memory test",
|
||||
"memory",
|
||||
"This test checks RAM.",
|
||||
POST_ROM | POST_POWERON | POST_SLOWTEST | POST_PREREL,
|
||||
&memory_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_MEMORY
|
||||
},
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CPU
|
||||
{
|
||||
"CPU test",
|
||||
"cpu",
|
||||
"This test verifies the arithmetic logic unit of"
|
||||
" CPU.",
|
||||
POST_RAM | POST_ALWAYS,
|
||||
&cpu_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_CPU
|
||||
},
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_FPU
|
||||
{
|
||||
"FPU test",
|
||||
"fpu",
|
||||
"This test verifies the arithmetic logic unit of"
|
||||
" FPU.",
|
||||
POST_RAM | POST_ALWAYS,
|
||||
&fpu_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_FPU
|
||||
},
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_UART
|
||||
#if defined(CONFIG_POST_UART)
|
||||
CONFIG_POST_UART,
|
||||
#else
|
||||
{
|
||||
"UART test",
|
||||
"uart",
|
||||
"This test verifies the UART operation.",
|
||||
POST_RAM | POST_SLOWTEST | POST_MANUAL,
|
||||
&uart_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_UART
|
||||
},
|
||||
#endif /* CONFIG_POST_UART */
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_ETHER
|
||||
{
|
||||
"ETHERNET test",
|
||||
"ethernet",
|
||||
"This test verifies the ETHERNET operation.",
|
||||
POST_RAM | POST_ALWAYS | POST_MANUAL,
|
||||
ðer_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_ETHER
|
||||
},
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_SPI
|
||||
{
|
||||
"SPI test",
|
||||
"spi",
|
||||
"This test verifies the SPI operation.",
|
||||
POST_RAM | POST_ALWAYS | POST_MANUAL,
|
||||
&spi_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_SPI
|
||||
},
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_USB
|
||||
{
|
||||
"USB test",
|
||||
"usb",
|
||||
"This test verifies the USB operation.",
|
||||
POST_RAM | POST_ALWAYS | POST_MANUAL,
|
||||
&usb_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_USB
|
||||
},
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_SPR
|
||||
{
|
||||
"SPR test",
|
||||
"spr",
|
||||
"This test checks SPR contents.",
|
||||
POST_RAM | POST_ALWAYS,
|
||||
&spr_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_SPR
|
||||
},
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_SYSMON
|
||||
{
|
||||
"SYSMON test",
|
||||
"sysmon",
|
||||
"This test monitors system hardware.",
|
||||
POST_RAM | POST_ALWAYS,
|
||||
&sysmon_post_test,
|
||||
&sysmon_init_f,
|
||||
&sysmon_reloc,
|
||||
CONFIG_SYS_POST_SYSMON
|
||||
},
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_DSP
|
||||
{
|
||||
"DSP test",
|
||||
"dsp",
|
||||
"This test checks any connected DSP(s).",
|
||||
POST_RAM | POST_ALWAYS | POST_MANUAL,
|
||||
&dsp_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_DSP
|
||||
},
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_CODEC
|
||||
{
|
||||
"CODEC test",
|
||||
"codec",
|
||||
"This test checks any connected codec(s).",
|
||||
POST_RAM | POST_MANUAL,
|
||||
&codec_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_CODEC
|
||||
},
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_ECC
|
||||
{
|
||||
"ECC test",
|
||||
"ecc",
|
||||
"This test checks the ECC facility of memory.",
|
||||
POST_ROM | POST_ALWAYS | POST_PREREL,
|
||||
&ecc_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_ECC
|
||||
},
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_BSPEC1
|
||||
CONFIG_POST_BSPEC1,
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_BSPEC2
|
||||
CONFIG_POST_BSPEC2,
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_BSPEC3
|
||||
CONFIG_POST_BSPEC3,
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_BSPEC4
|
||||
CONFIG_POST_BSPEC4,
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_BSPEC5
|
||||
CONFIG_POST_BSPEC5,
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_COPROC
|
||||
{
|
||||
"Coprocessors communication test",
|
||||
"coproc_com",
|
||||
"This test checks communication with coprocessors.",
|
||||
POST_RAM | POST_ALWAYS | POST_CRITICAL,
|
||||
&coprocessor_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_COPROC
|
||||
},
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_FLASH
|
||||
{
|
||||
"Parallel NOR flash test",
|
||||
"flash",
|
||||
"This test verifies parallel flash operations.",
|
||||
POST_RAM | POST_SLOWTEST | POST_MANUAL,
|
||||
&flash_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_FLASH
|
||||
},
|
||||
#endif
|
||||
#if CONFIG_POST & CONFIG_SYS_POST_MEM_REGIONS
|
||||
{
|
||||
"Memory regions test",
|
||||
"mem_regions",
|
||||
"This test checks regularly placed regions of the RAM.",
|
||||
POST_ROM | POST_SLOWTEST | POST_PREREL,
|
||||
&memory_regions_post_test,
|
||||
NULL,
|
||||
NULL,
|
||||
CONFIG_SYS_POST_MEM_REGIONS
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
unsigned int post_list_size = ARRAY_SIZE(post_list);
|
||||
Loading…
Add table
Add a link
Reference in a new issue