Merge with /home/wd/git/u-boot/custodian/u-boot-ppc4xx

This commit is contained in:
Wolfgang Denk 2007-07-06 02:50:34 +02:00
commit e80955f07d
30 changed files with 1861 additions and 113 deletions

View file

@ -214,6 +214,8 @@ LIBS += drivers/sk98lin/libsk98lin.a
LIBS += post/libpost.a post/drivers/libpostdrivers.a
LIBS += $(shell if [ -d post/lib_$(ARCH) ]; then echo \
"post/lib_$(ARCH)/libpost$(ARCH).a"; fi)
LIBS += $(shell if [ -d post/lib_$(ARCH)/fpu ]; then echo \
"post/lib_$(ARCH)/fpu/libpost$(ARCH)fpu.a"; fi)
LIBS += $(shell if [ -d post/cpu/$(CPU) ]; then echo \
"post/cpu/$(CPU)/libpost$(CPU).a"; fi)
LIBS += $(shell if [ -d post/board/$(BOARDDIR) ]; then echo \

View file

@ -25,7 +25,6 @@
#include <common.h>
#include <asm/processor.h>
#include <ppc440.h>
#include "sequoia.h"
DECLARE_GLOBAL_DATA_PTR;
@ -226,7 +225,7 @@ int misc_init_r(void)
if (act == NULL || strcmp(act, "hostdev") == 0) {
/* SDR Setting */
mfsdr(SDR0_PFC1, sdr0_pfc1);
mfsdr(SDR0_USB0, usb2d0cr);
mfsdr(SDR0_USB2D0CR, usb2d0cr);
mfsdr(SDR0_USB2PHY0CR, usb2phy0cr);
mfsdr(SDR0_USB2H0CR, usb2h0cr);
@ -254,7 +253,7 @@ int misc_init_r(void)
sdr0_pfc1 = sdr0_pfc1 | SDR0_PFC1_UES_USB2D_SEL; /*0*/
mtsdr(SDR0_PFC1, sdr0_pfc1);
mtsdr(SDR0_USB0, usb2d0cr);
mtsdr(SDR0_USB2D0CR, usb2d0cr);
mtsdr(SDR0_USB2PHY0CR, usb2phy0cr);
mtsdr(SDR0_USB2H0CR, usb2h0cr);
@ -298,7 +297,7 @@ int misc_init_r(void)
/* SDR Setting */
mfsdr(SDR0_USB2PHY0CR, usb2phy0cr);
mfsdr(SDR0_USB2H0CR, usb2h0cr);
mfsdr(SDR0_USB0, usb2d0cr);
mfsdr(SDR0_USB2D0CR, usb2d0cr);
mfsdr(SDR0_PFC1, sdr0_pfc1);
usb2phy0cr = usb2phy0cr &~SDR0_USB2PHY0CR_XOCLK_MASK;
@ -323,7 +322,7 @@ int misc_init_r(void)
mtsdr(SDR0_USB2H0CR, usb2h0cr);
mtsdr(SDR0_USB2PHY0CR, usb2phy0cr);
mtsdr(SDR0_USB0, usb2d0cr);
mtsdr(SDR0_USB2D0CR, usb2d0cr);
mtsdr(SDR0_PFC1, sdr0_pfc1);
/*clear resets*/

View file

@ -1,67 +0,0 @@
/*
* (C) Copyright 2006
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* (C) Copyright 2006
* Jacqueline Pira-Ferriol, AMCC/IBM, jpira-ferriol@fr.ibm.com
* Alain Saurel, AMCC/IBM, alain.saurel@fr.ibm.com
*
* 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
*/
/*----------------------------------------------------------------------------+
| EBC Configuration Register - EBC0_CFG
+----------------------------------------------------------------------------*/
/* External Bus Three-State Control */
#define EBC0_CFG_EBTC_DRIVEN 0x80000000
/* Device-Paced Time-out Disable */
#define EBC0_CFG_PTD_ENABLED 0x00000000
/* Ready Timeout Count */
#define EBC0_CFG_RTC_MASK 0x38000000
#define EBC0_CFG_RTC_16PERCLK 0x00000000
#define EBC0_CFG_RTC_32PERCLK 0x08000000
#define EBC0_CFG_RTC_64PERCLK 0x10000000
#define EBC0_CFG_RTC_128PERCLK 0x18000000
#define EBC0_CFG_RTC_256PERCLK 0x20000000
#define EBC0_CFG_RTC_512PERCLK 0x28000000
#define EBC0_CFG_RTC_1024PERCLK 0x30000000
#define EBC0_CFG_RTC_2048PERCLK 0x38000000
/* External Master Priority Low */
#define EBC0_CFG_EMPL_LOW 0x00000000
#define EBC0_CFG_EMPL_MEDIUM_LOW 0x02000000
#define EBC0_CFG_EMPL_MEDIUM_HIGH 0x04000000
#define EBC0_CFG_EMPL_HIGH 0x06000000
/* External Master Priority High */
#define EBC0_CFG_EMPH_LOW 0x00000000
#define EBC0_CFG_EMPH_MEDIUM_LOW 0x00800000
#define EBC0_CFG_EMPH_MEDIUM_HIGH 0x01000000
#define EBC0_CFG_EMPH_HIGH 0x01800000
/* Chip Select Three-State Control */
#define EBC0_CFG_CSTC_DRIVEN 0x00400000
/* Burst Prefetch */
#define EBC0_CFG_BPF_ONEDW 0x00000000
#define EBC0_CFG_BPF_TWODW 0x00100000
#define EBC0_CFG_BPF_FOURDW 0x00200000
/* External Master Size */
#define EBC0_CFG_EMS_8BIT 0x00000000
/* Power Management Enable */
#define EBC0_CFG_PME_DISABLED 0x00000000
#define EBC0_CFG_PME_ENABLED 0x00020000
/* Power Management Timer */
#define EBC0_CFG_PMT_ENCODE(n) ((((unsigned long)(n))&0x1F)<<12)
#define SDR0_USB0 0x0320 /* USB Control Register */

View file

@ -19,9 +19,10 @@
*/
#include <common.h>
#include <asm/processor.h>
#include <ppc440.h>
#include <asm/processor.h>
#include <asm/gpio.h>
#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
@ -220,6 +221,13 @@ int misc_init_r(void)
udelay(500);
gpio_write_bit(CFG_GPIO_LIME_RST, 1);
/* Lime memory clock adjusted to 133MHz */
out_be32((void *)CFG_LIME_SDRAM_CLOCK, CFG_LIME_CLOCK_133MHZ);
/* Wait untill time expired. Because of requirements in lime manual */
udelay(300);
/* Write lime controller memory parameters */
out_be32((void *)CFG_LIME_MMR, CFG_LIME_MMR_VALUE);
/*
* Reset PHY's
*/
@ -229,13 +237,6 @@ int misc_init_r(void)
gpio_write_bit(CFG_GPIO_PHY0_RST, 1);
gpio_write_bit(CFG_GPIO_PHY1_RST, 1);
/*
* Reset USB hub
*/
gpio_write_bit(CFG_GPIO_HUB_RST, 0);
udelay(100);
gpio_write_bit(CFG_GPIO_HUB_RST, 1);
return 0;
}

View file

@ -474,8 +474,27 @@ static void program_ecc(u32 start_address,
blank_string(strlen(str));
} else {
/* ECC bit set method for cached memory */
#if 1 /* test-only: will remove this define later, when ECC problems are solved! */
/*
* Some boards (like lwmon5) need to preserve the memory
* content upon ECC generation (for the log-buffer).
* Therefore we don't fill the memory with a pattern or
* just zero it, but write the same values back that are
* already in the memory cells.
*/
address_increment = CFG_CACHELINE_SIZE;
end_address = current_address + num_bytes;
current_address = start_address;
while (current_address < end_address) {
ppcDcbi(current_address);
ppcDcbf(current_address);
current_address += CFG_CACHELINE_SIZE;
}
#else
dcbz_area(start_address, num_bytes);
dflush();
#endif
}
sync();
@ -518,6 +537,8 @@ long int initdram (int board_type)
{
u32 val;
#if 0 /* test-only: will remove this define later, when ECC problems are solved! */
/* CL=3 */
mtsdram(DDR0_02, 0x00000000);
mtsdram(DDR0_00, 0x0000190A);
@ -558,6 +579,49 @@ long int initdram (int board_type)
mtsdram(DDR0_43, 0x030A0200);
mtsdram(DDR0_44, 0x00000003);
mtsdram(DDR0_02, 0x00000001); /* Activate the denali core */
#else
/* CL=4 */
mtsdram(DDR0_02, 0x00000000);
mtsdram(DDR0_00, 0x0000190A);
mtsdram(DDR0_01, 0x01000000);
mtsdram(DDR0_03, 0x02040803); /* A suitable burst length was taken. CAS is right for our board */
mtsdram(DDR0_04, 0x0B030300);
mtsdram(DDR0_05, 0x02020308);
mtsdram(DDR0_06, 0x0003C812);
mtsdram(DDR0_07, 0x00090100);
mtsdram(DDR0_08, 0x03c80001);
mtsdram(DDR0_09, 0x00011D5F);
mtsdram(DDR0_10, 0x00000300);
mtsdram(DDR0_11, 0x000CC800);
mtsdram(DDR0_12, 0x00000003);
mtsdram(DDR0_14, 0x00000000);
mtsdram(DDR0_17, 0x1e000000);
mtsdram(DDR0_18, 0x1e1e1e1e);
mtsdram(DDR0_19, 0x1e1e1e1e);
mtsdram(DDR0_20, 0x0B0B0B0B);
mtsdram(DDR0_21, 0x0B0B0B0B);
#ifdef CONFIG_DDR_ECC
mtsdram(DDR0_22, 0x00267F0B | DDR0_22_CTRL_RAW_ECC_ENABLE); /* enable ECC */
#else
mtsdram(DDR0_22, 0x00267F0B);
#endif
mtsdram(DDR0_23, 0x01000000);
mtsdram(DDR0_24, 0x01010001);
mtsdram(DDR0_26, 0x2D93028A);
mtsdram(DDR0_27, 0x0784682B);
mtsdram(DDR0_28, 0x00000080);
mtsdram(DDR0_31, 0x00000000);
mtsdram(DDR0_42, 0x01000008);
mtsdram(DDR0_43, 0x050A0200);
mtsdram(DDR0_44, 0x00000005);
mtsdram(DDR0_02, 0x00000001); /* Activate the denali core */
#endif
wait_for_dlllock();

View file

@ -1217,15 +1217,23 @@ mck_return:
* NOTE: currently the 440s run with dcache _disabled_ once relocated to DRAM,
* although for some cache-ralated calls stubs have to be provided to satisfy
* symbols resolution.
* Icache-related functions are used in POST framework.
*
*/
#ifdef CONFIG_440
.globl dcache_disable
.globl icache_disable
.globl icache_enable
dcache_disable:
icache_disable:
icache_enable:
blr
.globl dcache_status
.globl icache_status
dcache_status:
icache_status:
mr r3, 0
blr
#else
flush_dcache:

View file

@ -326,13 +326,25 @@
#define CFG_EBC_CFG 0xb8400000
/*-----------------------------------------------------------------------
* Graphics (Fujitsu Lime)
*----------------------------------------------------------------------*/
/* SDRAM Clock frequency adjustment register */
#define CFG_LIME_SDRAM_CLOCK 0xC1FC0000
/* Lime Clock frequency is to set 133MHz */
#define CFG_LIME_CLOCK_133MHZ 0x10000
/* SDRAM Parameter register */
#define CFG_LIME_MMR 0xC1FCFFFC
/* SDRAM parameter value */
#define CFG_LIME_MMR_VALUE 0x414FB7F2
/*-----------------------------------------------------------------------
* GPIO Setup
*----------------------------------------------------------------------*/
#define CFG_GPIO_PHY1_RST 12
#define CFG_GPIO_FLASH_WP 14
#define CFG_GPIO_PHY0_RST 22
#define CFG_GPIO_HUB_RST 50
#define CFG_GPIO_WATCHDOG 58
#define CFG_GPIO_LIME_S 59
#define CFG_GPIO_LIME_RST 60
@ -396,7 +408,7 @@
{GPIO1_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO47 UIC_IRQ(8) DMA_ACK(0) */ \
{GPIO1_BASE, GPIO_IN , GPIO_ALT1, GPIO_OUT_0}, /* GPIO48 UIC_IRQ(9) DMA_EOT/TC(0) */ \
{GPIO1_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_1}, /* GPIO49 Unselect via TraceSelect Bit */ \
{GPIO1_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_0}, /* GPIO50 Unselect via TraceSelect Bit */ \
{GPIO1_BASE, GPIO_IN, GPIO_SEL , GPIO_OUT_0}, /* GPIO50 Unselect via TraceSelect Bit */ \
{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO51 Unselect via TraceSelect Bit */ \
{GPIO1_BASE, GPIO_IN , GPIO_SEL , GPIO_OUT_0}, /* GPIO52 Unselect via TraceSelect Bit */ \
{GPIO1_BASE, GPIO_OUT, GPIO_SEL , GPIO_OUT_1}, /* GPIO53 Unselect via TraceSelect Bit */ \

View file

@ -334,10 +334,14 @@
CFG_POST_CPU | \
CFG_POST_UART | \
CFG_POST_I2C | \
CFG_POST_CACHE | \
CFG_POST_FPU | \
CFG_POST_ETHER | \
CFG_POST_SPR)
#define CFG_POST_WORD_ADDR (CFG_GBL_DATA_OFFSET - 0x4)
#define CONFIG_LOGBUFFER
#define CFG_POST_CACHE_ADDR 0x10000000 /* free virtual address */
#define CFG_CONSOLE_IS_IN_ENV /* Otherwise it catches logbuffer as output */

View file

@ -282,7 +282,6 @@
#define sdr_sdstp3 0x4003
#endif /* CONFIG_440GX */
#ifdef CONFIG_440
/*----------------------------------------------------------------------------+
| Core Configuration/MMU configuration for 440 (CCR1 for 440x5 only).
+----------------------------------------------------------------------------*/
@ -306,7 +305,6 @@
#define MMUCR_IULXE 0x00400000
#define MMUCR_STS 0x00100000
#define MMUCR_STID_MASK 0x000000FF
#endif /* CONFIG_440 */
#ifdef CONFIG_440SPE
#undef sdr_sdstp2
@ -1025,7 +1023,7 @@
#endif /* defined(CONFIG_440EP) || defined(CONFIG_440GR) */
#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
#define SDR_USB2D0CR 0x0320
#define SDR0_USB2D0CR 0x0320
#define SDR0_USB2D0CR_USB2DEV_EBC_SEL_MASK 0x00000004 /* USB 2.0 Device/EBC Master Selection */
#define SDR0_USB2D0CR_USB2DEV_SELECTION 0x00000004 /* USB 2.0 Device Selection */
#define SDR0_USB2D0CR_EBC_SELECTION 0x00000000 /* EBC Selection */
@ -1423,7 +1421,7 @@
#define uicvr uic0vr
#define uicvcr uic0vcr
#if defined(CONFIG_440SPE)
#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX)
/*----------------------------------------------------------------------------+
| Clock / Power-on-reset DCR's.
+----------------------------------------------------------------------------*/
@ -1492,9 +1490,11 @@
#define CPR0_OPBD_OPBDV0_DECODE(n) ((((((unsigned long)(n))>>24)-1)&0x03)+1)
#define CPR0_PERD 0xE0
#if !defined(CONFIG_440EPX)
#define CPR0_PERD_PERDV0_MASK 0x03000000
#define CPR0_PERD_PERDV0_ENCODE(n) ((((unsigned long)(n))&0x03)<<24)
#define CPR0_PERD_PERDV0_DECODE(n) ((((((unsigned long)(n))>>24)-1)&0x03)+1)
#endif
#define CPR0_MALD 0x100
#define CPR0_MALD_MALDV0_MASK 0x03000000

View file

@ -24,6 +24,6 @@
LIB = libpostmpc8xx.a
AOBJS = cache_8xx.o
COBJS = ether.o spr.o uart.o usb.o watchdog.o
COBJS = cache.o ether.o spr.o uart.o usb.o watchdog.o
include $(TOPDIR)/post/rules.mk

View file

@ -23,6 +23,7 @@
LIB = libpostppc4xx.a
COBJS = fpu.o spr.o uart.o watchdog.o
AOBJS = cache_4xx.o
COBJS = cache.o ether.o fpu.o spr.o uart.o watchdog.o
include $(TOPDIR)/post/rules.mk

114
post/cpu/ppc4xx/cache.c Normal file
View file

@ -0,0 +1,114 @@
/*
* (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.
*/
#ifdef CONFIG_POST
#include <post.h>
#if CONFIG_POST & CFG_POST_CACHE
#include <asm/mmu.h>
#include <watchdog.h>
#define CACHE_POST_SIZE 1024
void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value);
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);
static int tlb = -1; /* index to the victim TLB entry */
static unsigned char testarea[CACHE_POST_SIZE]
__attribute__((__aligned__(CACHE_POST_SIZE)));
int cache_post_test (int flags)
{
void* virt = (void*)CFG_POST_CACHE_ADDR;
int ints, i, res = 0;
u32 word0;
if (tlb < 0) {
/*
* 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;
}
}
}
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 ();
return res;
}
#endif /* CONFIG_POST & CFG_POST_CACHE */
#endif /* CONFIG_POST */

448
post/cpu/ppc4xx/cache_4xx.S Normal file
View file

@ -0,0 +1,448 @@
/*
* (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>
#ifdef CONFIG_POST
#include <post.h>
#include <ppc_asm.tmpl>
#include <ppc_defs.h>
#include <asm/cache.h>
#include <asm/mmu.h>
#if CONFIG_POST & CFG_POST_CACHE
.text
/* 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
/* void cache_post_dinvalidate (void *p, int size)
*/
cache_post_dinvalidate:
dcbi r0, r3
addi r3, r3, CFG_CACHELINE_SIZE
subic. r4, r4, CFG_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, CFG_CACHELINE_SIZE
subic. r4, r4, CFG_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, CFG_CACHELINE_SIZE
subic. r4, r4, CFG_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 & CFG_POST_CACHE */
#endif /* CONFIG_POST */

395
post/cpu/ppc4xx/ether.c Normal file
View file

@ -0,0 +1,395 @@
/*
* (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
* TEST_NUM - number of tests
*/
#ifdef CONFIG_POST
#include <post.h>
#if CONFIG_POST & CFG_POST_ETHER
#include <asm/cache.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <405_mal.h>
#include <ppc4xx_enet.h>
#include <malloc.h>
DECLARE_GLOBAL_DATA_PTR;
#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 256
#define TEST_NUM 1
static volatile mal_desc_t tx __cacheline_aligned;
static volatile mal_desc_t rx __cacheline_aligned;
static char *tx_buf;
static char *rx_buf;
static void ether_post_init (int devnum, int hw_addr)
{
int i;
unsigned mode_reg;
#if defined(CONFIG_440GX) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
defined(CONFIG_440SP) || defined(CONFIG_440SPE)
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 (sdr_mfr, mfr);
mfr |= SDR0_MFR_ETH_CLK_SEL_V(devnum);
mtsdr (sdr_mfr, mfr);
sync ();
#endif
/* reset emac */
out32 (EMAC_M0 + hw_addr, EMAC_M0_SRST);
sync ();
for (i = 0;; i++) {
if (!(in32 (EMAC_M0 + hw_addr) & EMAC_M0_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_M1_OBCI_66;
else if (sysinfo.freqOPB <= 83333333)
mode_reg |= EMAC_M1_OBCI_83;
else if (sysinfo.freqOPB <= 100000000)
mode_reg |= EMAC_M1_OBCI_100;
else
mode_reg |= EMAC_M1_OBCI_GT100;
out32 (EMAC_M1 + 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 (malmcr, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA |
MAL_CR_PLBLT_DEFAULT | 0x00330000);
#else
mtdcr (malmcr, 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 (malmcr, mfdcr(malmcr) & ~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);
switch (devnum) {
case 1:
/* setup MAL tx & rx channel pointers */
#if defined (CONFIG_405EP) || defined (CONFIG_440EP) || defined (CONFIG_440GR)
mtdcr (maltxctp2r, &tx);
#else
mtdcr (maltxctp1r, &tx);
#endif
#if defined(CONFIG_440)
mtdcr (maltxbattr, 0x0);
mtdcr (malrxbattr, 0x0);
#endif
mtdcr (malrxctp1r, &rx);
/* set RX buffer size */
mtdcr (malrcbs1, PKTSIZE_ALIGN / 16);
break;
case 0:
default:
/* setup MAL tx & rx channel pointers */
#if defined(CONFIG_440)
mtdcr (maltxbattr, 0x0);
mtdcr (malrxbattr, 0x0);
#endif
mtdcr (maltxctp0r, &tx);
mtdcr (malrxctp0r, &rx);
/* set RX buffer size */
mtdcr (malrcbs0, PKTSIZE_ALIGN / 16);
break;
}
/* Enable MAL transmit and receive channels */
#if defined(CONFIG_405EP) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
mtdcr (maltxcasr, (MAL_TXRX_CASR >> (devnum*2)));
#else
mtdcr (maltxcasr, (MAL_TXRX_CASR >> devnum));
#endif
mtdcr (malrxcasr, (MAL_TXRX_CASR >> devnum));
/* set internal loopback mode */
out32 (EMAC_M1 + hw_addr, EMAC_M1_FDE | EMAC_M1_ILE |
EMAC_M1_RFS_4K | EMAC_M1_TX_FIFO_2K |
EMAC_M1_MF_100MBPS | EMAC_M1_IST |
in32 (EMAC_M1));
/* set transmit enable & receive enable */
out32 (EMAC_M0 + hw_addr, EMAC_M0_TXE | EMAC_M0_RXE);
/* enable broadcast address */
out32 (EMAC_RXM + hw_addr, EMAC_RMR_BAE);
/* set transmit request threshold register */
out32 (EMAC_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 */
out32 (EMAC_RX_HI_LO_WMARK + hw_addr, 0x80009000);
#else
/* 405s have a 16 byte burst length */
out32 (EMAC_RX_HI_LO_WMARK + hw_addr, 0x0f002000);
#endif /* defined(CONFIG_440) */
out32 (EMAC_TXM1 + hw_addr, 0xf8640000);
/* Set fifo limit entry in tx mode 0 */
out32 (EMAC_TXM0 + hw_addr, 0x00000003);
/* Frame gap set */
out32 (EMAC_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 (maltxcarr, MAL_TXRX_CASR >> (devnum * 2));
#else
mtdcr (maltxcarr, MAL_TXRX_CASR >> devnum);
#endif
mtdcr (malrxcarr, MAL_TXRX_CASR >> devnum);
/* wait for reset */
while (mfdcr (malrxcasr) & (MAL_TXRX_CASR >> devnum)) {
if (i++ >= 1000)
break;
udelay (1000);
}
/* emac reset */
out32 (EMAC_M0 + hw_addr, EMAC_M0_SRST);
#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
/* remove clocks for EMAC internal loopback */
mfsdr (sdr_mfr, mfr);
mfr &= ~SDR0_MFR_ETH_CLK_SEL_V(devnum);
mtsdr (sdr_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);
}
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);
sync ();
out32 (EMAC_TXM0 + hw_addr, in32 (EMAC_TXM0 + hw_addr) | EMAC_TXM0_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);
}
length = rx.data_len - 4;
if (length <= max_length)
memcpy(packet, rx.data_ptr, length);
sync ();
rx.ctrl |= MAL_RX_CTRL_EMPTY;
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;
}
static int test_ctlr (int devnum, int hw_addr)
{
int res = -1;
char packet_send[MAX_PACKET_LENGTH];
char packet_recv[MAX_PACKET_LENGTH];
int length;
int i;
int l;
ether_post_init (devnum, hw_addr);
for (i = 0; i < TEST_NUM; i++) {
for (l = MIN_PACKET_LENGTH; l <= MAX_PACKET_LENGTH; l++) {
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;
/* Allocate tx & rx packet buffers */
tx_buf = malloc (PKTSIZE_ALIGN + CFG_CACHELINE_SIZE);
rx_buf = malloc (PKTSIZE_ALIGN + CFG_CACHELINE_SIZE);
if (!tx_buf || !rx_buf) {
printf ("Failed to allocate packet buffers\n");
res = -1;
goto out_free;
}
/* EMAC0 */
if (test_ctlr (0, 0))
res = -1;
/* EMAC1 */
if (test_ctlr (1, 0x100))
res = -1;
out_free:
free (tx_buf);
free (rx_buf);
return res;
}
#endif /* CONFIG_POST & CFG_POST_ETHER */
#endif /* CONFIG_POST */

View file

@ -1,5 +1,8 @@
/*
* Copyright (C) 2007 Wolfgang Denk <wd@denx.de>
* (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.
@ -34,7 +37,7 @@ int fpu_status(void)
{
if (mfspr(ccr0) & CCR0_DAPUIB)
return 0; /* Disabled */
else
else
return 1; /* Enabled */
}
@ -51,5 +54,6 @@ void fpu_enable(void)
mtspr(ccr0, mfspr(ccr0) & ~CCR0_DAPUIB);
mtmsr(mfmsr() | MSR_FP);
}
#endif
#endif
#endif /* CONFIG_POST */

View file

@ -2,6 +2,8 @@
* (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.
*
@ -39,6 +41,8 @@
#if CONFIG_POST & CFG_POST_SPR
#include <asm/processor.h>
static struct
{
int number;
@ -60,8 +64,10 @@ static struct
{0x113, "SPRG3", 0x00000000, 0x00000000},
{0x11f, "PVR", 0x00000000, 0x00000000},
/* Additional Special-Purpose Registers */
/* Additional Special-Purpose Registers.
* The values must match the initialization
* values from cpu/ppc4xx/start.S
*/
{0x30, "PID", 0x00000000, 0x00000000},
{0x3a, "CSRR0", 0x00000000, 0x00000000},
{0x3b, "CSRR1", 0x00000000, 0x00000000},
@ -90,22 +96,22 @@ static struct
{0x13f, "DVC2", 0x00000000, 0x00000000},
{0x150, "TSR", 0x00000000, 0x00000000},
{0x154, "TCR", 0x00000000, 0x00000000},
{0x190, "IVOR0", 0x00000000, 0x00000000},
{0x191, "IVOR1", 0x00000000, 0x00000000},
{0x192, "IVOR2", 0x00000000, 0x00000000},
{0x193, "IVOR3", 0x00000000, 0x00000000},
{0x194, "IVOR4", 0x00000000, 0x00000000},
{0x195, "IVOR5", 0x00000000, 0x00000000},
{0x196, "IVOR6", 0x00000000, 0x00000000},
{0x197, "IVOR7", 0x00000000, 0x00000000},
{0x198, "IVOR8", 0x00000000, 0x00000000},
{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", 0x00000000, 0x00000000},
{0x19a, "IVOR10", 0x0000fff0, 0x00000900},
{0x19b, "IVOR11", 0x00000000, 0x00000000},
{0x19c, "IVOR12", 0x00000000, 0x00000000},
{0x19d, "IVOR13", 0x00000000, 0x00000000},
{0x19e, "IVOR14", 0x00000000, 0x00000000},
{0x19f, "IVOR15", 0x00000000, 0x00000000},
{0x19d, "IVOR13", 0x0000fff0, 0x00001300},
{0x19e, "IVOR14", 0x0000fff0, 0x00001400},
{0x19f, "IVOR15", 0x0000fff0, 0x00002000},
{0x23a, "MCSRR0", 0x00000000, 0x00000000},
{0x23b, "MCSRR1", 0x00000000, 0x00000000},
{0x23c, "MCSR", 0x00000000, 0x00000000},
@ -126,8 +132,8 @@ static struct
{0x395, "DTV1", 0x00000000, 0x00000000},
{0x396, "DTV2", 0x00000000, 0x00000000},
{0x397, "DTV3", 0x00000000, 0x00000000},
{0x398, "DVLIM", 0x00000000, 0x00000000},
{0x399, "IVLIM", 0x00000000, 0x00000000},
{0x398, "DVLIM", 0x0fc1f83f, 0x0001f800},
{0x399, "IVLIM", 0x0fc1f83f, 0x0001f800},
{0x39b, "RSTCFG", 0x00000000, 0x00000000},
{0x39c, "DCDBTRL", 0x00000000, 0x00000000},
{0x39d, "DCDBTRH", 0x00000000, 0x00000000},
@ -172,5 +178,6 @@ int spr_post_test (int flags)
return ret;
}
#endif /* CONFIG_POST & CFG_POST_SPR */
#endif /* CONFIG_POST */

View file

@ -2,6 +2,8 @@
* (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.
*
@ -210,5 +212,4 @@ int uart_post_test (int flags)
}
#endif /* CONFIG_POST & CFG_POST_UART */
#endif /* CONFIG_POST */

View file

@ -2,6 +2,8 @@
* (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.
*
@ -36,17 +38,18 @@
#ifdef CONFIG_POST
#include <post.h>
#include <watchdog.h>
#if CONFIG_POST & CFG_POST_WATCHDOG
#include <watchdog.h>
int watchdog_post_test (int flags)
{
if (flags & POST_REBOOT) {
/* Test passed */
return 0;
} else {
}
else {
/* 10-second delay */
int ints = disable_interrupts ();
ulong base = post_time_ms (0);

View file

@ -26,6 +26,6 @@ SUBDIRS =
LIB = libpostdrivers.a
COBJS = cache.o i2c.o memory.o rtc.o
COBJS = i2c.o memory.o rtc.o
include $(TOPDIR)/post/rules.mk

View file

@ -21,6 +21,7 @@
# MA 02111-1307 USA
#
SUBDIRS = fpu
LIB = libpostppc.a

View file

@ -0,0 +1,62 @@
/*
* 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>
#ifdef CONFIG_POST
#include <post.h>
#if CONFIG_POST & CFG_POST_FPU
int fpu_post_test_math1 (void)
{
volatile double a, *p;
double c, d;
volatile double b;
d = 1.0;
p = &b;
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 & CFG_POST_FPU */
#endif /* CONFIG_POST */

View file

@ -0,0 +1,66 @@
/*
* 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>
#ifdef CONFIG_POST
#include <post.h>
#if CONFIG_POST & CFG_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 & CFG_POST_FPU */
#endif /* CONFIG_POST */

View file

@ -0,0 +1,54 @@
/*
* 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>
#ifdef CONFIG_POST
#include <post.h>
#if CONFIG_POST & CFG_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 & CFG_POST_FPU */
#endif /* CONFIG_POST */

View file

@ -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>
#ifdef CONFIG_POST
#include <post.h>
#if CONFIG_POST & CFG_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 & CFG_POST_FPU */
#endif /* CONFIG_POST */

32
post/lib_ppc/fpu/Makefile Normal file
View file

@ -0,0 +1,32 @@
#
# (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
#
LIB = libpostppcfpu.a
COBJS += fpu.o 20001122-1.o 20010114-2.o 20010226-1.o 980619-1.o
COBJS += acc1.o compare-fp-1.o mul-subnormal-single-1.o
include $(TOPDIR)/post/rules.mk
CFLAGS += -mhard-float -fkeep-inline-functions

57
post/lib_ppc/fpu/acc1.c Normal file
View file

@ -0,0 +1,57 @@
/*
* 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>
#ifdef CONFIG_POST
#include <post.h>
#if CONFIG_POST & CFG_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 & CFG_POST_FPU */
#endif /* CONFIG_POST */

View file

@ -0,0 +1,225 @@
/*
* 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>
#ifdef CONFIG_POST
#include <post.h>
#if CONFIG_POST & CFG_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 & CFG_POST_FPU */
#endif /* CONFIG_POST */

92
post/lib_ppc/fpu/fpu.c Normal file
View file

@ -0,0 +1,92 @@
/*
* 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.
*/
#ifdef CONFIG_POST
#include <post.h>
#if CONFIG_POST & CFG_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 & CFG_POST_FPU */
#endif /* CONFIG_POST */

View file

@ -0,0 +1,103 @@
/*
* 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>
#ifdef CONFIG_POST
#include <post.h>
#if CONFIG_POST & CFG_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 < sizeof (expected) / sizeof (expected[0]); 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 & CFG_POST_FPU */
#endif /* CONFIG_POST */