Skip to content
Snippets Groups Projects
Commit b4489621 authored by Sergei Poselenov's avatar Sergei Poselenov Committed by Stefan Roese
Browse files

Merged POST framework with the current TOT.

parent f780b833
No related branches found
No related tags found
No related merge requests found
Showing
with 1257 additions and 29 deletions
...@@ -214,6 +214,8 @@ LIBS += drivers/sk98lin/libsk98lin.a ...@@ -214,6 +214,8 @@ LIBS += drivers/sk98lin/libsk98lin.a
LIBS += post/libpost.a post/drivers/libpostdrivers.a LIBS += post/libpost.a post/drivers/libpostdrivers.a
LIBS += $(shell if [ -d post/lib_$(ARCH) ]; then echo \ LIBS += $(shell if [ -d post/lib_$(ARCH) ]; then echo \
"post/lib_$(ARCH)/libpost$(ARCH).a"; fi) "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 \ LIBS += $(shell if [ -d post/cpu/$(CPU) ]; then echo \
"post/cpu/$(CPU)/libpost$(CPU).a"; fi) "post/cpu/$(CPU)/libpost$(CPU).a"; fi)
LIBS += $(shell if [ -d post/board/$(BOARDDIR) ]; then echo \ LIBS += $(shell if [ -d post/board/$(BOARDDIR) ]; then echo \
......
...@@ -1217,15 +1217,23 @@ mck_return: ...@@ -1217,15 +1217,23 @@ mck_return:
* NOTE: currently the 440s run with dcache _disabled_ once relocated to DRAM, * 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 * although for some cache-ralated calls stubs have to be provided to satisfy
* symbols resolution. * symbols resolution.
* Icache-related functions are used in POST framework.
* *
*/ */
#ifdef CONFIG_440 #ifdef CONFIG_440
.globl dcache_disable .globl dcache_disable
.globl icache_disable
.globl icache_enable
dcache_disable: dcache_disable:
icache_disable:
icache_enable:
blr blr
.globl dcache_status .globl dcache_status
.globl icache_status
dcache_status: dcache_status:
icache_status:
mr r3, 0
blr blr
#else #else
flush_dcache: flush_dcache:
......
...@@ -334,10 +334,14 @@ ...@@ -334,10 +334,14 @@
CFG_POST_CPU | \ CFG_POST_CPU | \
CFG_POST_UART | \ CFG_POST_UART | \
CFG_POST_I2C | \ CFG_POST_I2C | \
CFG_POST_CACHE | \
CFG_POST_FPU | \
CFG_POST_ETHER | \
CFG_POST_SPR) CFG_POST_SPR)
#define CFG_POST_WORD_ADDR (CFG_GBL_DATA_OFFSET - 0x4) #define CFG_POST_WORD_ADDR (CFG_GBL_DATA_OFFSET - 0x4)
#define CONFIG_LOGBUFFER #define CONFIG_LOGBUFFER
#define CFG_POST_CACHE_ADDR 0x10000000 /* free virtual address */
#define CFG_CONSOLE_IS_IN_ENV /* Otherwise it catches logbuffer as output */ #define CFG_CONSOLE_IS_IN_ENV /* Otherwise it catches logbuffer as output */
......
...@@ -282,7 +282,6 @@ ...@@ -282,7 +282,6 @@
#define sdr_sdstp3 0x4003 #define sdr_sdstp3 0x4003
#endif /* CONFIG_440GX */ #endif /* CONFIG_440GX */
#ifdef CONFIG_440
/*----------------------------------------------------------------------------+ /*----------------------------------------------------------------------------+
| Core Configuration/MMU configuration for 440 (CCR1 for 440x5 only). | Core Configuration/MMU configuration for 440 (CCR1 for 440x5 only).
+----------------------------------------------------------------------------*/ +----------------------------------------------------------------------------*/
...@@ -306,7 +305,6 @@ ...@@ -306,7 +305,6 @@
#define MMUCR_IULXE 0x00400000 #define MMUCR_IULXE 0x00400000
#define MMUCR_STS 0x00100000 #define MMUCR_STS 0x00100000
#define MMUCR_STID_MASK 0x000000FF #define MMUCR_STID_MASK 0x000000FF
#endif /* CONFIG_440 */
#ifdef CONFIG_440SPE #ifdef CONFIG_440SPE
#undef sdr_sdstp2 #undef sdr_sdstp2
......
...@@ -24,6 +24,6 @@ ...@@ -24,6 +24,6 @@
LIB = libpostmpc8xx.a LIB = libpostmpc8xx.a
AOBJS = cache_8xx.o 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 include $(TOPDIR)/post/rules.mk
File moved
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
LIB = libpostppc4xx.a 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 include $(TOPDIR)/post/rules.mk
/*
* (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 */
/*
* (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 */
/*
* (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 */
/* /*
* 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 * See file CREDITS for list of people who contributed to this
* project. * project.
...@@ -51,5 +54,6 @@ void fpu_enable(void) ...@@ -51,5 +54,6 @@ void fpu_enable(void)
mtspr(ccr0, mfspr(ccr0) & ~CCR0_DAPUIB); mtspr(ccr0, mfspr(ccr0) & ~CCR0_DAPUIB);
mtmsr(mfmsr() | MSR_FP); mtmsr(mfmsr() | MSR_FP);
} }
#endif #endif
#endif #endif /* CONFIG_POST */
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
* (C) Copyright 2007 * (C) Copyright 2007
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. * 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 * See file CREDITS for list of people who contributed to this
* project. * project.
* *
...@@ -39,6 +41,8 @@ ...@@ -39,6 +41,8 @@
#if CONFIG_POST & CFG_POST_SPR #if CONFIG_POST & CFG_POST_SPR
#include <asm/processor.h>
static struct static struct
{ {
int number; int number;
...@@ -60,8 +64,10 @@ static struct ...@@ -60,8 +64,10 @@ static struct
{0x113, "SPRG3", 0x00000000, 0x00000000}, {0x113, "SPRG3", 0x00000000, 0x00000000},
{0x11f, "PVR", 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}, {0x30, "PID", 0x00000000, 0x00000000},
{0x3a, "CSRR0", 0x00000000, 0x00000000}, {0x3a, "CSRR0", 0x00000000, 0x00000000},
{0x3b, "CSRR1", 0x00000000, 0x00000000}, {0x3b, "CSRR1", 0x00000000, 0x00000000},
...@@ -90,22 +96,22 @@ static struct ...@@ -90,22 +96,22 @@ static struct
{0x13f, "DVC2", 0x00000000, 0x00000000}, {0x13f, "DVC2", 0x00000000, 0x00000000},
{0x150, "TSR", 0x00000000, 0x00000000}, {0x150, "TSR", 0x00000000, 0x00000000},
{0x154, "TCR", 0x00000000, 0x00000000}, {0x154, "TCR", 0x00000000, 0x00000000},
{0x190, "IVOR0", 0x00000000, 0x00000000}, {0x190, "IVOR0", 0x0000fff0, 0x00000100},
{0x191, "IVOR1", 0x00000000, 0x00000000}, {0x191, "IVOR1", 0x0000fff0, 0x00000200},
{0x192, "IVOR2", 0x00000000, 0x00000000}, {0x192, "IVOR2", 0x0000fff0, 0x00000300},
{0x193, "IVOR3", 0x00000000, 0x00000000}, {0x193, "IVOR3", 0x0000fff0, 0x00000400},
{0x194, "IVOR4", 0x00000000, 0x00000000}, {0x194, "IVOR4", 0x0000fff0, 0x00000500},
{0x195, "IVOR5", 0x00000000, 0x00000000}, {0x195, "IVOR5", 0x0000fff0, 0x00000600},
{0x196, "IVOR6", 0x00000000, 0x00000000}, {0x196, "IVOR6", 0x0000fff0, 0x00000700},
{0x197, "IVOR7", 0x00000000, 0x00000000}, {0x197, "IVOR7", 0x0000fff0, 0x00000800},
{0x198, "IVOR8", 0x00000000, 0x00000000}, {0x198, "IVOR8", 0x0000fff0, 0x00000c00},
{0x199, "IVOR9", 0x00000000, 0x00000000}, {0x199, "IVOR9", 0x00000000, 0x00000000},
{0x19a, "IVOR10", 0x00000000, 0x00000000}, {0x19a, "IVOR10", 0x0000fff0, 0x00000900},
{0x19b, "IVOR11", 0x00000000, 0x00000000}, {0x19b, "IVOR11", 0x00000000, 0x00000000},
{0x19c, "IVOR12", 0x00000000, 0x00000000}, {0x19c, "IVOR12", 0x00000000, 0x00000000},
{0x19d, "IVOR13", 0x00000000, 0x00000000}, {0x19d, "IVOR13", 0x0000fff0, 0x00001300},
{0x19e, "IVOR14", 0x00000000, 0x00000000}, {0x19e, "IVOR14", 0x0000fff0, 0x00001400},
{0x19f, "IVOR15", 0x00000000, 0x00000000}, {0x19f, "IVOR15", 0x0000fff0, 0x00002000},
{0x23a, "MCSRR0", 0x00000000, 0x00000000}, {0x23a, "MCSRR0", 0x00000000, 0x00000000},
{0x23b, "MCSRR1", 0x00000000, 0x00000000}, {0x23b, "MCSRR1", 0x00000000, 0x00000000},
{0x23c, "MCSR", 0x00000000, 0x00000000}, {0x23c, "MCSR", 0x00000000, 0x00000000},
...@@ -126,8 +132,8 @@ static struct ...@@ -126,8 +132,8 @@ static struct
{0x395, "DTV1", 0x00000000, 0x00000000}, {0x395, "DTV1", 0x00000000, 0x00000000},
{0x396, "DTV2", 0x00000000, 0x00000000}, {0x396, "DTV2", 0x00000000, 0x00000000},
{0x397, "DTV3", 0x00000000, 0x00000000}, {0x397, "DTV3", 0x00000000, 0x00000000},
{0x398, "DVLIM", 0x00000000, 0x00000000}, {0x398, "DVLIM", 0x0fc1f83f, 0x0001f800},
{0x399, "IVLIM", 0x00000000, 0x00000000}, {0x399, "IVLIM", 0x0fc1f83f, 0x0001f800},
{0x39b, "RSTCFG", 0x00000000, 0x00000000}, {0x39b, "RSTCFG", 0x00000000, 0x00000000},
{0x39c, "DCDBTRL", 0x00000000, 0x00000000}, {0x39c, "DCDBTRL", 0x00000000, 0x00000000},
{0x39d, "DCDBTRH", 0x00000000, 0x00000000}, {0x39d, "DCDBTRH", 0x00000000, 0x00000000},
...@@ -172,5 +178,6 @@ int spr_post_test (int flags) ...@@ -172,5 +178,6 @@ int spr_post_test (int flags)
return ret; return ret;
} }
#endif /* CONFIG_POST & CFG_POST_SPR */ #endif /* CONFIG_POST & CFG_POST_SPR */
#endif /* CONFIG_POST */ #endif /* CONFIG_POST */
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
* (C) Copyright 2007 * (C) Copyright 2007
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. * 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 * See file CREDITS for list of people who contributed to this
* project. * project.
* *
...@@ -210,5 +212,4 @@ int uart_post_test (int flags) ...@@ -210,5 +212,4 @@ int uart_post_test (int flags)
} }
#endif /* CONFIG_POST & CFG_POST_UART */ #endif /* CONFIG_POST & CFG_POST_UART */
#endif /* CONFIG_POST */ #endif /* CONFIG_POST */
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
* (C) Copyright 2007 * (C) Copyright 2007
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. * 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 * See file CREDITS for list of people who contributed to this
* project. * project.
* *
...@@ -36,17 +38,18 @@ ...@@ -36,17 +38,18 @@
#ifdef CONFIG_POST #ifdef CONFIG_POST
#include <post.h> #include <post.h>
#include <watchdog.h>
#if CONFIG_POST & CFG_POST_WATCHDOG #if CONFIG_POST & CFG_POST_WATCHDOG
#include <watchdog.h>
int watchdog_post_test (int flags) int watchdog_post_test (int flags)
{ {
if (flags & POST_REBOOT) { if (flags & POST_REBOOT) {
/* Test passed */ /* Test passed */
return 0; return 0;
} else { }
else {
/* 10-second delay */ /* 10-second delay */
int ints = disable_interrupts (); int ints = disable_interrupts ();
ulong base = post_time_ms (0); ulong base = post_time_ms (0);
......
...@@ -26,6 +26,6 @@ SUBDIRS = ...@@ -26,6 +26,6 @@ SUBDIRS =
LIB = libpostdrivers.a LIB = libpostdrivers.a
COBJS = cache.o i2c.o memory.o rtc.o COBJS = i2c.o memory.o rtc.o
include $(TOPDIR)/post/rules.mk include $(TOPDIR)/post/rules.mk
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
# MA 02111-1307 USA # MA 02111-1307 USA
# #
SUBDIRS = fpu
LIB = libpostppc.a LIB = libpostppc.a
......
/*
* 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 */
/*
* 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 */
/*
* 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 */
/*
* 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 */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment