9
0
Fork 0

initial blackfin support

This commit is contained in:
Sascha Hauer 2007-09-11 10:15:32 +02:00
parent 6402a7d5b7
commit 97c0278dc1
38 changed files with 5834 additions and 597 deletions

29
arch/blackfin/Kconfig Normal file
View File

@ -0,0 +1,29 @@
config BLACKFIN
bool
default y
config BF561
bool
config BOARDINFO
default "PII IPE337" if MACH_IPE337
choice
prompt "Select your board"
config MACH_IPE337
bool "PII ipe337"
select BF561
help
Say Y here if you are using the PII IPE337 board
endchoice
source common/Kconfig
source commands/Kconfig
source net/Kconfig
source drivers/Kconfig
source fs/Kconfig
source lib/Kconfig

56
arch/blackfin/Makefile Normal file
View File

@ -0,0 +1,56 @@
CPPFLAGS += -fno-builtin -ffreestanding -nostdinc -Wall \
-isystem $(gccincdir) -pipe \
-fno-strict-aliasing
board-$(CONFIG_MACH_IPE337) := ipe337
cpu-$(CONFIG_BF561) := bf561
TEXT_BASE = $(CONFIG_TEXT_BASE)
CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -P
CFLAGS := -fno-common -Os
LDFLAGS_uboot :=-L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc -Ttext $(TEXT_BASE)
ifeq ($(incdir-y),)
incdir-y := $(machine-y)
endif
INCDIR := arch-$(incdir-y)
# Update machine arch and proc symlinks if something which affects
# them changed. We use .arch to indicate when they were updated
# last, otherwise make uses the target directory mtime.
include/asm-blackfin/.arch: $(wildcard include/config/arch/*.h) include/config/auto.conf
@echo ' SYMLINK include/asm-blackfin/arch -> include/asm-blackfin/$(INCDIR)'
ifneq ($(KBUILD_SRC),)
$(Q)mkdir -p include/asm-blackfin
$(Q)ln -fsn $(srctree)/include/asm-blackfin/$(INCDIR) include/asm-blackfin/arch
else
$(Q)ln -fsn $(INCDIR) include/asm-blackfin/arch
endif
@touch $@
archprepare: maketools
PHONY += maketools
maketools: include/asm-blackfin/.arch
ifneq ($(board-y),)
BOARD := board/$(board-y)/
else
BOARD :=
endif
ifneq ($(cpu-y),)
CPU := arch/blackfin/cpu-$(cpu-y)/
else
CPU :=
endif
common-y += $(BOARD)
common-y += arch/blackfin/lib/ $(CPU)
MRPROPER_FILES += include/asm-arm/arch include/asm-arm/proc

View File

@ -0,0 +1,2 @@
obj-y += start.o
obj-y += init_sdram.o

View File

@ -0,0 +1,167 @@
#define ASSEMBLY
#include <config.h>
#include <asm/blackfin.h>
#include <asm/mem_init.h>
.global init_sdram;
init_sdram:
[--SP] = ASTAT;
[--SP] = RETS;
[--SP] = (R7:0);
[--SP] = (P5:0);
#ifndef BF537_UART_BOOT
#ifdef CONFIG_BF537
/* Enable PHY CLK buffer output */
p0.h = hi(VR_CTL);
p0.l = lo(VR_CTL);
r0.l = w[p0];
bitset(r0, 14);
w[p0] = r0.l;
ssync;
#endif
/*
* PLL_LOCKCNT - how many SCLK Cycles to delay while PLL becomes stable
*/
p0.h = hi(PLL_LOCKCNT);
p0.l = lo(PLL_LOCKCNT);
r0 = 0x300(Z);
w[p0] = r0.l;
ssync;
/*
* Put SDRAM in self-refresh, incase anything is running
*/
P2.H = hi(EBIU_SDGCTL);
P2.L = lo(EBIU_SDGCTL);
R0 = [P2];
BITSET (R0, 24);
[P2] = R0;
SSYNC;
/*
* Set PLL_CTL with the value that we calculate in R0
* - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
* - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK
* - [7] = output delay (add 200ps of delay to mem signals)
* - [6] = input delay (add 200ps of input delay to mem signals)
* - [5] = PDWN : 1=All Clocks off
* - [3] = STOPCK : 1=Core Clock off
* - [1] = PLL_OFF : 1=Disable Power to PLL
* - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
* all other bits set to zero
*/
r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */
r0 = r0 << 9; /* Shift it over, */
r1 = CONFIG_CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/
r0 = r1 | r0;
r1 = CONFIG_PLL_BYPASS; /* Bypass the PLL? */
r1 = r1 << 8; /* Shift it over */
r0 = r1 | r0; /* add them all together */
p0.h = hi(PLL_CTL);
p0.l = lo(PLL_CTL); /* Load the address */
cli r2; /* Disable interrupts */
ssync;
w[p0] = r0.l; /* Set the value */
idle; /* Wait for the PLL to stablize */
sti r2; /* Enable interrupts */
check_again:
p0.h = hi(PLL_STAT);
p0.l = lo(PLL_STAT);
R0 = W[P0](Z);
CC = BITTST(R0,5);
if ! CC jump check_again;
/* Configure SCLK & CCLK Dividers */
r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
p0.h = hi(PLL_DIV);
p0.l = lo(PLL_DIV);
w[p0] = r0.l;
ssync;
#endif
/*
* We now are running at speed, time to set the Async mem bank wait states
* This will speed up execution, since we are normally running from FLASH.
*/
p2.h = (EBIU_AMBCTL1 >> 16);
p2.l = (EBIU_AMBCTL1 & 0xFFFF);
r0.h = (AMBCTL1VAL >> 16);
r0.l = (AMBCTL1VAL & 0xFFFF);
[p2] = r0;
ssync;
p2.h = (EBIU_AMBCTL0 >> 16);
p2.l = (EBIU_AMBCTL0 & 0xFFFF);
r0.h = (AMBCTL0VAL >> 16);
r0.l = (AMBCTL0VAL & 0xFFFF);
[p2] = r0;
ssync;
p2.h = (EBIU_AMGCTL >> 16);
p2.l = (EBIU_AMGCTL & 0xffff);
r0 = AMGCTLVAL;
w[p2] = r0;
ssync;
/*
* Now, Initialize the SDRAM,
* start with the SDRAM Refresh Rate Control Register
*/
p0.l = lo(EBIU_SDRRC);
p0.h = hi(EBIU_SDRRC);
r0 = mem_SDRRC;
w[p0] = r0.l;
ssync;
/*
* SDRAM Memory Bank Control Register - bank specific parameters
*/
p0.l = (EBIU_SDBCTL & 0xFFFF);
p0.h = (EBIU_SDBCTL >> 16);
r0 = mem_SDBCTL;
w[p0] = r0.l;
ssync;
/*
* SDRAM Global Control Register - global programmable parameters
* Disable self-refresh
*/
P2.H = hi(EBIU_SDGCTL);
P2.L = lo(EBIU_SDGCTL);
R0 = [P2];
BITCLR (R0, 24);
/*
* Check if SDRAM is already powered up, if it is, enable self-refresh
*/
p0.h = hi(EBIU_SDSTAT);
p0.l = lo(EBIU_SDSTAT);
r2.l = w[p0];
cc = bittst(r2,3);
if !cc jump skip;
NOP;
BITSET (R0, 23);
skip:
[P2] = R0;
SSYNC;
/* Write in the new value in the register */
R0.L = lo(mem_SDGCTL);
R0.H = hi(mem_SDGCTL);
[P2] = R0;
SSYNC;
nop;
(P5:0) = [SP++];
(R7:0) = [SP++];
RETS = [SP++];
ASTAT = [SP++];
RTS;

View File

@ -0,0 +1,356 @@
/*
* U-boot - start.S Startup file of u-boot for BF533/BF561
*
* Copyright (c) 2005 blackfin.uclinux.org
*
* This file is based on head.S
* Copyright (c) 2003 Metrowerks/Motorola
* Copyright (C) 1998 D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
* Kenneth Albanowski <kjahds@kjahds.com>,
* The Silver Hammer Group, Ltd.
* (c) 1995, Dionne & Associates
* (c) 1995, DKG Display Tech.
*
* 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 <asm/blackfin.h>
#include <asm/cpu/defBF561_extn.h>
#include <asm/cpu/defBF561.h>
.section ".text_entry","ax"
.macro checker
p0.h = FIO0_DIR >> 16;
p0.l = FIO0_DIR & 0xFFFF;
r0 = (1 << 9);
w[p0] = r0;
p0.h = FIO0_FLAG_S >> 16;
p0.l = FIO0_FLAG_S & 0xFFFF;
r0 = (1 << 9);
w[p0] = r0;
1:
jump 1b
.endm
_start:
start:
_stext:
R0 = 0x32;
SYSCFG = R0;
SSYNC;
/* As per HW reference manual DAG registers,
* DATA and Address resgister shall be zero'd
* in initialization, after a reset state
*/
r1 = 0; /* Data registers zero'd */
r2 = 0;
r3 = 0;
r4 = 0;
r5 = 0;
r6 = 0;
r7 = 0;
p0 = 0; /* Address registers zero'd */
p1 = 0;
p2 = 0;
p3 = 0;
p4 = 0;
p5 = 0;
i0 = 0; /* DAG Registers zero'd */
i1 = 0;
i2 = 0;
i3 = 0;
m0 = 0;
m1 = 0;
m3 = 0;
m3 = 0;
l0 = 0;
l1 = 0;
l2 = 0;
l3 = 0;
b0 = 0;
b1 = 0;
b2 = 0;
b3 = 0;
/* Set loop counters to zero, to make sure that
* hw loops are disabled.
*/
r0 = 0;
lc0 = r0;
lc1 = r0;
SSYNC;
/* Check soft reset status */
p0.h = SWRST >> 16;
p0.l = SWRST & 0xFFFF;
r0.l = w[p0];
cc = bittst(r0, 15);
if !cc jump no_soft_reset;
/* Clear Soft reset */
r0 = 0x0000;
w[p0] = r0;
ssync;
no_soft_reset:
nop;
/* Clear EVT registers */
p0.h = hi(EVT_EMULATION_ADDR)
p0.l = lo(EVT_EMULATION_ADDR);
p0 += 8;
p1 = 14;
r1 = 0;
LSETUP(4,4) lc0 = p1;
[ p0 ++ ] = r1;
p0.h = hi(SIC_IWR);
p0.l = lo(SIC_IWR);
r0.l = 0x1;
w[p0] = r0.l;
SSYNC;
sp.l = lo(0xffb01000);
sp.h = hi(0xffb01000);
/* Check if the code is in SDRAM */
/* If the code is in SDRAM, skip SDRAM initializaiton */
call get_pc;
r3.l = 0x0;
r3.h = 0x2000;
cc = r0 < r3 (iu);
if cc jump sdram_initialized;
call init_sdram;
/* relocate into to RAM */
sdram_initialized:
call get_pc;
offset:
r2.l = offset;
r2.h = offset;
r3.l = start;
r3.h = start;
r1 = r2 - r3;
r0 = r0 - r1;
p1 = r0;
p2.l = lo(TEXT_BASE);
p2.h = hi(TEXT_BASE);
p3 = 0x04;
p4.l = __bss_start;
p4.h = __bss_start;
loop1:
r1 = [p1 ++ p3];
[p2 ++ p3] = r1;
cc=p2==p4;
if !cc jump loop1;
/*
* configure STACK
*/
r0.h = hi(CONFIG_STACKBASE);
r0.l = lo(CONFIG_STACKBASE);
sp = r0;
fp = sp;
/*
* This next section keeps the processor in supervisor mode
* during kernel boot. Switches to user mode at end of boot.
* See page 3-9 of Hardware Reference manual for documentation.
*/
/* To keep ourselves in the supervisor mode */
p0.l = lo(EVT_IVG15_ADDR);
p0.h = hi(EVT_IVG15_ADDR);
p1.l = _real_start;
p1.h = _real_start;
[p0] = p1;
p0.l = lo(IMASK);
p0.h = hi(IMASK);
r0.l = lo(IVG15_POS);
r0.h = hi(IVG15_POS);
[p0] = r0;
raise 15;
p0.l = WAIT_HERE;
p0.h = WAIT_HERE;
reti = p0;
rti;
WAIT_HERE:
jump WAIT_HERE;
.global _real_start;
_real_start:
[ -- sp ] = reti;
#if defined(CONFIG_EZKIT533) || defined(CONFIG_EZKIT561)
p0.l = lo(WDOG_CTL);
p0.h = hi(WDOG_CTL);
r0 = WATCHDOG_DISABLE(z);
w[p0] = r0;
#endif
#ifdef CONFIG_BF537
/* Initialise General-Purpose I/O Modules on BF537
* Rev 0.0 Anomaly 05000212 - PORTx_FER,
* PORT_MUX Registers Do Not accept "writes" correctly
*/
p0.h = hi(PORTF_FER);
p0.l = lo(PORTF_FER);
R0.L = W[P0]; /* Read */
nop;
nop;
nop;
ssync;
R0 = 0x000F(Z);
W[P0] = R0.L; /* Write */
nop;
nop;
nop;
ssync;
W[P0] = R0.L; /* Enable peripheral function of PORTF for UART0 and UART1 */
nop;
nop;
nop;
ssync;
p0.h = hi(PORTH_FER);
p0.l = lo(PORTH_FER);
R0.L = W[P0]; /* Read */
nop;
nop;
nop;
ssync;
R0 = 0xFFFF(Z);
W[P0] = R0.L; /* Write */
nop;
nop;
nop;
ssync;
W[P0] = R0.L; /* Enable peripheral function of PORTH for MAC */
nop;
nop;
nop;
ssync;
#endif
/* DMA reset code to Hi of L1 SRAM */
copy:
P1.H = hi(SYSMMR_BASE); /* P1 Points to the beginning of SYSTEM MMR Space */
P1.L = lo(SYSMMR_BASE);
R0.H = reset_start; /* Source Address (high) */
R0.L = reset_start; /* Source Address (low) */
R1.H = reset_end;
R1.L = reset_end;
R2 = R1 - R0; /* Count */
R1.H = hi(L1_ISRAM); /* Destination Address (high) */
R1.L = lo(L1_ISRAM); /* Destination Address (low) */
R3.L = DMAEN; /* Source DMAConfig Value (8-bit words) */
R4.L = (DI_EN | WNR | DMAEN); /* Destination DMAConfig Value (8-bit words) */
DMA:
R6 = 0x1 (Z);
W[P1+OFFSET_(MDMA_S0_X_MODIFY)] = R6; /* Source Modify = 1 */
W[P1+OFFSET_(MDMA_D0_X_MODIFY)] = R6; /* Destination Modify = 1 */
[P1+OFFSET_(MDMA_S0_START_ADDR)] = R0; /* Set Source Base Address */
W[P1+OFFSET_(MDMA_S0_X_COUNT)] = R2; /* Set Source Count */
/* Set Source DMAConfig = DMA Enable,
Memory Read, 8-Bit Transfers, 1-D DMA, Flow - Stop */
W[P1+OFFSET_(MDMA_S0_CONFIG)] = R3;
[P1+OFFSET_(MDMA_D0_START_ADDR)] = R1; /* Set Destination Base Address */
W[P1+OFFSET_(MDMA_D0_X_COUNT)] = R2; /* Set Destination Count */
/* Set Destination DMAConfig = DMA Enable,
Memory Write, 8-Bit Transfers, 1-D DMA, Flow - Stop, IOC */
W[P1+OFFSET_(MDMA_D0_CONFIG)] = R4;
WAIT_DMA_DONE:
p0.h = hi(MDMA_D0_IRQ_STATUS);
p0.l = lo(MDMA_D0_IRQ_STATUS);
R0 = W[P0](Z);
CC = BITTST(R0, 0);
if ! CC jump WAIT_DMA_DONE
R0 = 0x1;
W[P1+OFFSET_(MDMA_D0_IRQ_STATUS)] = R0; /* Write 1 to clear DMA interrupt */
/* Initialize BSS Section with 0 s */
p1.l = __bss_start;
p1.h = __bss_start;
p2.l = _end;
p2.h = _end;
r1 = p1;
r2 = p2;
r3 = r2 - r1;
r3 = r3 >> 2;
p3 = r3;
lsetup (_clear_bss, _clear_bss_end ) lc1 = p3;
CC = p2<=p1;
if CC jump _clear_bss_skip;
r0 = 0;
_clear_bss:
_clear_bss_end:
[p1++] = r0;
_clear_bss_skip:
#if defined(CONFIG_BF537)&&defined(CONFIG_POST)
p0.l = post_flag;
p0.h = post_flag;
r0 = r7;
[p0] = r0;
#endif
p0.l = _start_uboot;
p0.h = _start_uboot;
jump (p0);
reset_start:
p0.h = hi(WDOG_CNT);
p0.l = lo(WDOG_CNT);
r0 = 0x0010;
w[p0] = r0;
p0.h = hi(WDOG_CTL);
p0.l = lo(WDOG_CTL);
r0 = 0x0000;
w[p0] = r0;
reset_wait:
jump reset_wait;
reset_end: nop;
_exit:
jump.s _exit;
get_pc:
r0 = rets;
rts;

View File

@ -0,0 +1,12 @@
obj-y += board.o
obj-y += clock.o
obj-y += muldi3.o
obj-y += udivsi3.o
obj-y += umulsi3_highpart.o
obj-y += smulsi3_highpart.o
obj-y += umodsi3.o
obj-y += lshrdi3.o
obj-y += ashldi3.o
obj-y += divsi3.o
obj-y += modsi3.o

View File

@ -0,0 +1,60 @@
/*
* File: arch/blackfin/lib/ashldi3.c
* Based on:
* Author:
*
* Created:
* Description:
*
* Rev: $Id: ashldi3.c 2775 2007-02-21 13:58:44Z hennerich $
*
* Modified:
* Copyright 2004-2006 Analog Devices Inc.
*
* Bugs: Enter bugs at http://blackfin.uclinux.org/
*
* 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, see the file COPYING, or write
* to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "gcclib.h"
#ifdef CONFIG_ARITHMETIC_OPS_L1
DItype __ashldi3(DItype u, word_type b)__attribute__((l1_text));
#endif
DItype __ashldi3(DItype u, word_type b)
{
DIunion w;
word_type bm;
DIunion uu;
if (b == 0)
return u;
uu.ll = u;
bm = (sizeof(SItype) * BITS_PER_UNIT) - b;
if (bm <= 0) {
w.s.low = 0;
w.s.high = (USItype) uu.s.low << -bm;
} else {
USItype carries = (USItype) uu.s.low >> bm;
w.s.low = (USItype) uu.s.low << b;
w.s.high = ((USItype) uu.s.high << b) | carries;
}
return w.ll;
}

View File

@ -52,7 +52,6 @@
static char *make_command_line(void);
extern image_header_t header;
extern int do_reset(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]);
void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
ulong addr, ulong * len_ptr, int verify)
{

View File

@ -42,12 +42,7 @@ ulong monitor_flash_len;
#define VERSION_STRING_FORMAT "%s (%s - %s)\n"
#define VERSION_STRING U_BOOT_VERSION, __DATE__, __TIME__
char version_string[VERSION_STRING_SIZE];
int *g_addr;
static ulong mem_malloc_start;
static ulong mem_malloc_end;
static ulong mem_malloc_brk;
extern char _sram_in_sdram_start[];
extern char _sram_inst_size[];
#ifdef DEBUG

50
arch/blackfin/lib/board.c Normal file
View File

@ -0,0 +1,50 @@
/*
* U-boot - board.c First C file to be called contains init routines
*
* Copyright (c) 2005 blackfin.uclinux.org
*
* (C) Copyright 2000-2004
* 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 <command.h>
#include <malloc.h>
#include <net.h>
#include <init.h>
#include <environment.h>
#include <mem_malloc.h>
#include "blackfin_board.h"
int blackfin_mem_malloc_init(void)
{
mem_malloc_init((void *)(CONFIG_MALLOC_BASE - CONFIG_MALLOC_LEN),
(void *)CONFIG_MALLOC_BASE);
return 0;
}
core_initcall(blackfin_mem_malloc_init);
void reset_cpu(ulong ignored)
{
printf("do not ave a reset function\n");
while (1);
}

79
arch/blackfin/lib/clock.c Normal file
View File

@ -0,0 +1,79 @@
#include <common.h>
#include <clock.h>
#include <init.h>
#include <asm/blackfin.h>
#include <asm/cpu/cdef_LPBlackfin.h>
static ulong get_vco(void)
{
ulong msel;
ulong vco;
msel = (*pPLL_CTL >> 9) & 0x3F;
if (0 == msel)
msel = 64;
vco = CONFIG_CLKIN_HZ;
vco >>= (1 & *pPLL_CTL); /* DF bit */
vco = msel * vco;
return vco;
}
/* Get the Core clock */
ulong get_cclk(void)
{
ulong csel, ssel;
if (*pPLL_STAT & 0x1)
return CONFIG_CLKIN_HZ;
ssel = *pPLL_DIV;
csel = ((ssel >> 4) & 0x03);
ssel &= 0xf;
if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */
return get_vco() / ssel;
return get_vco() >> csel;
}
/* Get the System clock */
ulong get_sclk(void)
{
ulong ssel;
if (*pPLL_STAT & 0x1)
return CONFIG_CLKIN_HZ;
ssel = (*pPLL_DIV & 0xf);
return get_vco() / ssel;
}
uint64_t blackfin_clocksource_read(void)
{
return ~(*pTCOUNT);
}
static struct clocksource cs = {
.read = blackfin_clocksource_read,
.mask = 0xffffffff,
.shift = 10,
};
static int clocksource_init (void)
{
*pTCNTL = 0x1;
*pTSCALE = 0x0;
*pTCOUNT = ~0;
*pTPERIOD = ~0;
*pTCNTL = 0x7;
asm("CSYNC;");
cs.mult = clocksource_hz2mult(get_cclk(), cs.shift);
init_clock(&cs);
return 0;
}
core_initcall(clocksource_init);

217
arch/blackfin/lib/divsi3.S Normal file
View File

@ -0,0 +1,217 @@
/*
* File: arch/blackfin/lib/divsi3.S
* Based on:
* Author:
*
* Created:
* Description: 16 / 32 bit signed division.
* Special cases :
* 1) If(numerator == 0)
* return 0
* 2) If(denominator ==0)
* return positive max = 0x7fffffff
* 3) If(numerator == denominator)
* return 1
* 4) If(denominator ==1)
* return numerator
* 5) If(denominator == -1)
* return -numerator
*
* Operand : R0 - Numerator (i)
* R1 - Denominator (i)
* R0 - Quotient (o)
* Registers Used : R2-R7,P0-P2
* Rev: $Id: divsi3.S 2794 2007-03-05 05:27:47Z cooloney $
*
* Modified:
* Copyright 2004-2006 Analog Devices Inc.
*
* Bugs: Enter bugs at http://blackfin.uclinux.org/
*
* 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, see the file COPYING, or write
* to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
.global ___divsi3;
#ifdef CONFIG_ARITHMETIC_OPS_L1
.section .l1.text
#else
.text
#endif
.align 2;
___divsi3 :
R3 = R0 ^ R1;
R0 = ABS R0;
CC = V;
r3 = rot r3 by -1;
r1 = abs r1; /* now both positive, r3.30 means "negate result",
** r3.31 means overflow, add one to result
*/
cc = r0 < r1;
if cc jump .Lret_zero;
r2 = r1 >> 15;
cc = r2;
if cc jump .Lidents;
r2 = r1 << 16;
cc = r2 <= r0;
if cc jump .Lidents;
DIVS(R0, R1);
DIVQ(R0, R1);
DIVQ(R0, R1);
DIVQ(R0, R1);
DIVQ(R0, R1);
DIVQ(R0, R1);
DIVQ(R0, R1);
DIVQ(R0, R1);
DIVQ(R0, R1);
DIVQ(R0, R1);
DIVQ(R0, R1);
DIVQ(R0, R1);
DIVQ(R0, R1);
DIVQ(R0, R1);
DIVQ(R0, R1);
DIVQ(R0, R1);
DIVQ(R0, R1);
R0 = R0.L (Z);
r1 = r3 >> 31; /* add overflow issue back in */
r0 = r0 + r1;
r1 = -r0;
cc = bittst(r3, 30);
if cc r0 = r1;
RTS;
/* Can't use the primitives. Test common identities.
** If the identity is true, return the value in R2.
*/
.Lidents:
CC = R1 == 0; /* check for divide by zero */
IF CC JUMP .Lident_return;
CC = R0 == 0; /* check for division of zero */
IF CC JUMP .Lzero_return;
CC = R0 == R1; /* check for identical operands */
IF CC JUMP .Lident_return;
CC = R1 == 1; /* check for divide by 1 */
IF CC JUMP .Lident_return;
R2.L = ONES R1;
R2 = R2.L (Z);
CC = R2 == 1;
IF CC JUMP .Lpower_of_two;
/* Identities haven't helped either.
** Perform the full division process.
*/
P1 = 31; /* Set loop counter */
[--SP] = (R7:5); /* Push registers R5-R7 */
R2 = -R1;
[--SP] = R2;
R2 = R0 << 1; /* R2 lsw of dividend */
R6 = R0 ^ R1; /* Get sign */
R5 = R6 >> 31; /* Shift sign to LSB */
R0 = 0 ; /* Clear msw partial remainder */
R2 = R2 | R5; /* Shift quotient bit */
R6 = R0 ^ R1; /* Get new quotient bit */
LSETUP(.Llst,.Llend) LC0 = P1; /* Setup loop */
.Llst: R7 = R2 >> 31; /* record copy of carry from R2 */
R2 = R2 << 1; /* Shift 64 bit dividend up by 1 bit */
R0 = R0 << 1 || R5 = [SP];
R0 = R0 | R7; /* and add carry */
CC = R6 < 0; /* Check quotient(AQ) */
/* we might be subtracting divisor (AQ==0) */
IF CC R5 = R1; /* or we might be adding divisor (AQ==1)*/
R0 = R0 + R5; /* do add or subtract, as indicated by AQ */
R6 = R0 ^ R1; /* Generate next quotient bit */
R5 = R6 >> 31;
/* Assume AQ==1, shift in zero */
BITTGL(R5,0); /* tweak AQ to be what we want to shift in */
.Llend: R2 = R2 + R5; /* and then set shifted-in value to
** tweaked AQ.
*/
r1 = r3 >> 31;
r2 = r2 + r1;
cc = bittst(r3,30);
r0 = -r2;
if !cc r0 = r2;
SP += 4;
(R7:5)= [SP++]; /* Pop registers R6-R7 */
RTS;
.Lident_return:
CC = R1 == 0; /* check for divide by zero => 0x7fffffff */
R2 = -1 (X);
R2 >>= 1;
IF CC JUMP .Ltrue_ident_return;
CC = R0 == R1; /* check for identical operands => 1 */
R2 = 1 (Z);
IF CC JUMP .Ltrue_ident_return;
R2 = R0; /* assume divide by 1 => numerator */
/*FALLTHRU*/
.Ltrue_ident_return:
R0 = R2; /* Return an identity value */
R2 = -R2;
CC = bittst(R3,30);
IF CC R0 = R2;
.Lzero_return:
RTS; /* ...including zero */
.Lpower_of_two:
/* Y has a single bit set, which means it's a power of two.
** That means we can perform the division just by shifting
** X to the right the appropriate number of bits
*/
/* signbits returns the number of sign bits, minus one.
** 1=>30, 2=>29, ..., 0x40000000=>0. Which means we need
** to shift right n-signbits spaces. It also means 0x80000000
** is a special case, because that *also* gives a signbits of 0
*/
R2 = R0 >> 31;
CC = R1 < 0;
IF CC JUMP .Ltrue_ident_return;
R1.l = SIGNBITS R1;
R1 = R1.L (Z);
R1 += -30;
R0 = LSHIFT R0 by R1.L;
r1 = r3 >> 31;
r0 = r0 + r1;
R2 = -R0; // negate result if necessary
CC = bittst(R3,30);
IF CC R0 = R2;
RTS;
.Lret_zero:
R0 = 0;
RTS;

View File

@ -0,0 +1,49 @@
/*
* File: arch/blackfin/lib/gcclib.h
* Based on:
* Author:
*
* Created:
* Description:
*
* Rev: $Id: gcclib.h 1942 2006-08-03 17:37:22Z vapier $
*
* Modified:
* Copyright 2004-2006 Analog Devices Inc.
*
* Bugs: Enter bugs at http://blackfin.uclinux.org/
*
* 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, see the file COPYING, or write
* to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define BITS_PER_UNIT 8
#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
typedef unsigned int UQItype __attribute__ ((mode(QI)));
typedef int SItype __attribute__ ((mode(SI)));
typedef unsigned int USItype __attribute__ ((mode(SI)));
typedef int DItype __attribute__ ((mode(DI)));
typedef int word_type __attribute__ ((mode(__word__)));
typedef unsigned int UDItype __attribute__ ((mode(DI)));
struct DIstruct {
SItype low, high;
};
typedef union {
struct DIstruct s;
DItype ll;
} DIunion;

View File

@ -0,0 +1,74 @@
/*
* File: arch/blackfin/lib/lshrdi3.c
* Based on:
* Author:
*
* Created:
* Description:
*
* Rev: $Id: lshrdi3.c 2775 2007-02-21 13:58:44Z hennerich $
*
* Modified:
* Copyright 2004-2006 Analog Devices Inc.
*
* Bugs: Enter bugs at http://blackfin.uclinux.org/
*
* 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, see the file COPYING, or write
* to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define BITS_PER_UNIT 8
typedef int SItype __attribute__ ((mode(SI)));
typedef unsigned int USItype __attribute__ ((mode(SI)));
typedef int DItype __attribute__ ((mode(DI)));
typedef int word_type __attribute__ ((mode(__word__)));
struct DIstruct {
SItype high, low;
};
typedef union {
struct DIstruct s;
DItype ll;
} DIunion;
#ifdef CONFIG_ARITHMETIC_OPS_L1
DItype __lshrdi3(DItype u, word_type b)__attribute__((l1_text));
#endif
DItype __lshrdi3(DItype u, word_type b)
{
DIunion w;
word_type bm;
DIunion uu;
if (b == 0)
return u;
uu.ll = u;
bm = (sizeof(SItype) * BITS_PER_UNIT) - b;
if (bm <= 0) {
w.s.high = 0;
w.s.low = (USItype) uu.s.high >> -bm;
} else {
USItype carries = (USItype) uu.s.high << bm;
w.s.high = (USItype) uu.s.high >> b;
w.s.low = ((USItype) uu.s.low >> b) | carries;
}
return w.ll;
}

View File

@ -0,0 +1,81 @@
/*
* File: arch/blackfin/lib/modsi3.S
* Based on:
* Author:
*
* Created:
* Description: This program computes 32 bit signed remainder. It calls div32 function
* for quotient estimation.
*
* Registers used :
* Numerator/ Denominator in R0, R1
* R0 - returns remainder.
* R2-R7
*
* Rev: $Id: modsi3.S 2775 2007-02-21 13:58:44Z hennerich $
*
* Modified:
* Copyright 2004-2006 Analog Devices Inc.
*
* Bugs: Enter bugs at http://blackfin.uclinux.org/
*
* 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, see the file COPYING, or write
* to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
.global ___modsi3;
.type ___modsi3, STT_FUNC;
.extern ___divsi3;
.type ___divsi3, STT_FUNC;
#ifdef CONFIG_ARITHMETIC_OPS_L1
.section .l1.text
#else
.text
#endif
___modsi3:
CC=R0==0;
IF CC JUMP .LRETURN_R0; /* Return 0, if numerator == 0 */
CC=R1==0;
IF CC JUMP .LRETURN_ZERO; /* Return 0, if denominator == 0 */
CC=R0==R1;
IF CC JUMP .LRETURN_ZERO; /* Return 0, if numerator == denominator */
CC = R1 == 1;
IF CC JUMP .LRETURN_ZERO; /* Return 0, if denominator == 1 */
CC = R1 == -1;
IF CC JUMP .LRETURN_ZERO; /* Return 0, if denominator == -1 */
/* Valid input. Use __divsi3() to compute the quotient, and then
* derive the remainder from that. */
[--SP] = (R7:6); /* Push R7 and R6 */
[--SP] = RETS; /* and return address */
R7 = R0; /* Copy of R0 */
R6 = R1; /* Save for later */
SP += -12; /* Should always provide this space */
CALL ___divsi3; /* Compute signed quotient using ___divsi3()*/
SP += 12;
R0 *= R6; /* Quotient * divisor */
R0 = R7 - R0; /* Dividend - (quotient * divisor) */
RETS = [SP++]; /* Get back return address */
(R7:6) = [SP++]; /* Pop registers R7 and R4 */
RTS; /* Store remainder */
.LRETURN_ZERO:
R0 = 0;
.LRETURN_R0:
RTS;

View File

@ -22,10 +22,9 @@
* MA 02111-1307 USA
*/
#include "gcclib.h"
/* Generic function got from GNU gcc package, libgcc2.c */
#ifndef SI_TYPE_SIZE
#define SI_TYPE_SIZE 32
#endif
#define __ll_B (1L << (SI_TYPE_SIZE / 2))
#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
#define __ll_highpart(t) ((USItype) (t) / __ll_B)
@ -64,18 +63,6 @@ do { \
__w.ll; })
#endif
typedef unsigned int USItype __attribute__ ((mode (SI)));
typedef int SItype __attribute__ ((mode (SI)));
typedef int DItype __attribute__ ((mode (DI)));
typedef int word_type __attribute__ ((mode (__word__)));
struct DIstruct {SItype low, high;};
typedef union
{
struct DIstruct s;
DItype ll;
} DIunion;
DItype __muldi3 (DItype u, DItype v)
{
DIunion w;

View File

@ -0,0 +1,30 @@
.align 2
.global ___smulsi3_highpart;
.type ___smulsi3_highpart, STT_FUNC;
#ifdef CONFIG_ARITHMETIC_OPS_L1
.section .l1.text
#else
.text
#endif
___smulsi3_highpart:
R2 = R1.L * R0.L (FU);
R3 = R1.H * R0.L (IS,M);
R0 = R0.H * R1.H, R1 = R0.H * R1.L (IS,M);
R1.L = R2.H + R1.L;
cc = ac0;
R2 = cc;
R1.L = R1.L + R3.L;
cc = ac0;
R1 >>>= 16;
R3 >>>= 16;
R1 = R1 + R3;
R1 = R1 + R2;
R2 = cc;
R1 = R1 + R2;
R0 = R0 + R1;
RTS;

299
arch/blackfin/lib/udivsi3.S Normal file
View File

@ -0,0 +1,299 @@
/*
* File: arch/blackfin/lib/udivsi3.S
* Based on:
* Author:
*
* Created:
* Description:
*
* Rev: $Id: udivsi3.S 2795 2007-03-05 06:25:33Z cooloney $
*
* Modified:
* Copyright 2004-2006 Analog Devices Inc.
*
* Bugs: Enter bugs at http://blackfin.uclinux.org/
*
* 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, see the file COPYING, or write
* to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define CARRY AC0
#ifdef CONFIG_ARITHMETIC_OPS_L1
.section .l1.text
#else
.text
#endif
.globl ___udivsi3;
___udivsi3:
CC = R0 < R1 (IU); /* If X < Y, always return 0 */
IF CC JUMP .Lreturn_ident;
R2 = R1 << 16;
CC = R2 <= R0 (IU);
IF CC JUMP .Lidents;
R2 = R0 >> 31; /* if X is a 31-bit number */
R3 = R1 >> 15; /* and Y is a 15-bit number */
R2 = R2 | R3; /* then it's okay to use the DIVQ builtins (fallthrough to fast)*/
CC = R2;
IF CC JUMP .Ly_16bit;
/* METHOD 1: FAST DIVQ
We know we have a 31-bit dividend, and 15-bit divisor so we can use the
simple divq approach (first setting AQ to 0 - implying unsigned division,
then 16 DIVQ's).
*/
AQ = CC; /* Clear AQ (CC==0) */
/* ISR States: When dividing two integers (32.0/16.0) using divide primitives,
we need to shift the dividend one bit to the left.
We have already checked that we have a 31-bit number so we are safe to do
that.
*/
R0 <<= 1;
DIVQ(R0, R1); // 1
DIVQ(R0, R1); // 2
DIVQ(R0, R1); // 3
DIVQ(R0, R1); // 4
DIVQ(R0, R1); // 5
DIVQ(R0, R1); // 6
DIVQ(R0, R1); // 7
DIVQ(R0, R1); // 8
DIVQ(R0, R1); // 9
DIVQ(R0, R1); // 10
DIVQ(R0, R1); // 11
DIVQ(R0, R1); // 12
DIVQ(R0, R1); // 13
DIVQ(R0, R1); // 14
DIVQ(R0, R1); // 15
DIVQ(R0, R1); // 16
R0 = R0.L (Z);
RTS;
.Ly_16bit:
/* We know that the upper 17 bits of Y might have bits set,
** or that the sign bit of X might have a bit. If Y is a
** 16-bit number, but not bigger, then we can use the builtins
** with a post-divide correction.
** R3 currently holds Y>>15, which means R3's LSB is the
** bit we're interested in.
*/
/* According to the ISR, to use the Divide primitives for
** unsigned integer divide, the useable range is 31 bits
*/
CC = ! BITTST(R0, 31);
/* IF condition is true we can scale our inputs and use the divide primitives,
** with some post-adjustment
*/
R3 += -1; /* if so, Y is 0x00008nnn */
CC &= AZ;
/* If condition is true we can scale our inputs and use the divide primitives,
** with some post-adjustment
*/
R3 = R1 >> 1; /* Pre-scaled divisor for primitive case */
R2 = R0 >> 16;
R2 = R3 - R2; /* shifted divisor < upper 16 bits of dividend */
CC &= CARRY;
IF CC JUMP .Lshift_and_correct;
/* Fall through to the identities */
/* METHOD 2: identities and manual calculation
We are not able to use the divide primites, but may still catch some special
cases.
*/
.Lidents:
/* Test for common identities. Value to be returned is placed in R2. */
CC = R0 == 0; /* 0/Y => 0 */
IF CC JUMP .Lreturn_r0;
CC = R0 == R1; /* X==Y => 1 */
IF CC JUMP .Lreturn_ident;
CC = R1 == 1; /* X/1 => X */
IF CC JUMP .Lreturn_ident;
R2.L = ONES R1;
R2 = R2.L (Z);
CC = R2 == 1;
IF CC JUMP .Lpower_of_two;
[--SP] = (R7:5); /* Push registers R5-R7 */
/* Idents don't match. Go for the full operation. */
R6 = 2; /* assume we'll shift two */
R3 = 1;
P2 = R1;
/* If either R0 or R1 have sign set, */
/* divide them by two, and note it's */
/* been done. */
CC = R1 < 0;
R2 = R1 >> 1;
IF CC R1 = R2; /* Possibly-shifted R1 */
IF !CC R6 = R3; /* R1 doesn't, so at most 1 shifted */
P0 = 0;
R3 = -R1;
[--SP] = R3;
R2 = R0 >> 1;
R2 = R0 >> 1;
CC = R0 < 0;
IF CC P0 = R6; /* Number of values divided */
IF !CC R2 = R0; /* Shifted R0 */
/* P0 is 0, 1 (NR/=2) or 2 (NR/=2, DR/=2) */
/* r2 holds Copy dividend */
R3 = 0; /* Clear partial remainder */
R7 = 0; /* Initialise quotient bit */
P1 = 32; /* Set loop counter */
LSETUP(.Lulst, .Lulend) LC0 = P1; /* Set loop counter */
.Lulst: R6 = R2 >> 31; /* R6 = sign bit of R2, for carry */
R2 = R2 << 1; /* Shift 64 bit dividend up by 1 bit */
R3 = R3 << 1 || R5 = [SP];
R3 = R3 | R6; /* Include any carry */
CC = R7 < 0; /* Check quotient(AQ) */
/* If AQ==0, we'll sub divisor */
IF CC R5 = R1; /* and if AQ==1, we'll add it. */
R3 = R3 + R5; /* Add/sub divsor to partial remainder */
R7 = R3 ^ R1; /* Generate next quotient bit */
R5 = R7 >> 31; /* Get AQ */
BITTGL(R5, 0); /* Invert it, to get what we'll shift */
.Lulend: R2 = R2 + R5; /* and "shift" it in. */
CC = P0 == 0; /* Check how many inputs we shifted */
IF CC JUMP .Lno_mult; /* if none... */
R6 = R2 << 1;
CC = P0 == 1;
IF CC R2 = R6; /* if 1, Q = Q*2 */
IF !CC R1 = P2; /* if 2, restore stored divisor */
R3 = R2; /* Copy of R2 */
R3 *= R1; /* Q * divisor */
R5 = R0 - R3; /* Z = (dividend - Q * divisor) */
CC = R1 <= R5 (IU); /* Check if divisor <= Z? */
R6 = CC; /* if yes, R6 = 1 */
R2 = R2 + R6; /* if yes, add one to quotient(Q) */
.Lno_mult:
SP += 4;
(R7:5) = [SP++]; /* Pop registers R5-R7 */
R0 = R2; /* Store quotient */
RTS;
.Lreturn_ident:
CC = R0 < R1 (IU); /* If X < Y, always return 0 */
R2 = 0;
IF CC JUMP .Ltrue_return_ident;
R2 = -1 (X); /* X/0 => 0xFFFFFFFF */
CC = R1 == 0;
IF CC JUMP .Ltrue_return_ident;
R2 = -R2; /* R2 now 1 */
CC = R0 == R1; /* X==Y => 1 */
IF CC JUMP .Ltrue_return_ident;
R2 = R0; /* X/1 => X */
/*FALLTHRU*/
.Ltrue_return_ident:
R0 = R2;
.Lreturn_r0:
RTS;
.Lpower_of_two:
/* Y has a single bit set, which means it's a power of two.
** That means we can perform the division just by shifting
** X to the right the appropriate number of bits
*/
/* signbits returns the number of sign bits, minus one.
** 1=>30, 2=>29, ..., 0x40000000=>0. Which means we need
** to shift right n-signbits spaces. It also means 0x80000000
** is a special case, because that *also* gives a signbits of 0
*/
R2 = R0 >> 31;
CC = R1 < 0;
IF CC JUMP .Ltrue_return_ident;
R1.l = SIGNBITS R1;
R1 = R1.L (Z);
R1 += -30;
R0 = LSHIFT R0 by R1.L;
RTS;
/* METHOD 3: PRESCALE AND USE THE DIVIDE PRIMITIVES WITH SOME POST-CORRECTION
Two scaling operations are required to use the divide primitives with a
divisor > 0x7FFFF.
Firstly (as in method 1) we need to shift the dividend 1 to the left for
integer division.
Secondly we need to shift both the divisor and dividend 1 to the right so
both are in range for the primitives.
The left/right shift of the dividend does nothing so we can skip it.
*/
.Lshift_and_correct:
R2 = R0;
// R3 is already R1 >> 1
CC=!CC;
AQ = CC; /* Clear AQ, got here with CC = 0 */
DIVQ(R2, R3); // 1
DIVQ(R2, R3); // 2
DIVQ(R2, R3); // 3
DIVQ(R2, R3); // 4
DIVQ(R2, R3); // 5
DIVQ(R2, R3); // 6
DIVQ(R2, R3); // 7
DIVQ(R2, R3); // 8
DIVQ(R2, R3); // 9
DIVQ(R2, R3); // 10
DIVQ(R2, R3); // 11
DIVQ(R2, R3); // 12
DIVQ(R2, R3); // 13
DIVQ(R2, R3); // 14
DIVQ(R2, R3); // 15
DIVQ(R2, R3); // 16
/* According to the Instruction Set Reference:
To divide by a divisor > 0x7FFF,
1. prescale and perform divide to obtain quotient (Q) (done above),
2. multiply quotient by unscaled divisor (result M)
3. subtract the product from the divident to get an error (E = X - M)
4. if E < divisor (Y) subtract 1, if E > divisor (Y) add 1, else return quotient (Q)
*/
R3 = R2.L (Z); /* Q = X' / Y' */
R2 = R3; /* Preserve Q */
R2 *= R1; /* M = Q * Y */
R2 = R0 - R2; /* E = X - M */
R0 = R3; /* Copy Q into result reg */
/* Correction: If result of the multiply is negative, we overflowed
and need to correct the result by subtracting 1 from the result.*/
R3 = 0xFFFF (Z);
R2 = R2 >> 16; /* E >> 16 */
CC = R2 == R3;
R3 = 1 ;
R1 = R0 - R3;
IF CC R0 = R1;
RTS;

View File

@ -0,0 +1,68 @@
/*
* File: arch/blackfin/lib/umodsi3.S
* Based on:
* Author:
*
* Created:
* Description: libgcc1 routines for Blackfin 5xx
*
* Rev: $Id: umodsi3.S 2769 2007-02-19 16:45:53Z hennerich $
*
* Modified:
* Copyright 2004-2006 Analog Devices Inc.
*
* Bugs: Enter bugs at http://blackfin.uclinux.org/
*
* 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, see the file COPYING, or write
* to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef CONFIG_ARITHMETIC_OPS_L1
.section .l1.text
#else
.text
#endif
.extern ___udivsi3;
.globl ___umodsi3
___umodsi3:
CC=R0==0;
IF CC JUMP .LRETURN_R0; /* Return 0, if NR == 0 */
CC= R1==0;
IF CC JUMP .LRETURN_ZERO_VAL; /* Return 0, if DR == 0 */
CC=R0==R1;
IF CC JUMP .LRETURN_ZERO_VAL; /* Return 0, if NR == DR */
CC = R1 == 1;
IF CC JUMP .LRETURN_ZERO_VAL; /* Return 0, if DR == 1 */
CC = R0<R1 (IU);
IF CC JUMP .LRETURN_R0; /* Return dividend (R0),IF NR<DR */
[--SP] = (R7:6); /* Push registers and */
[--SP] = RETS; /* Return address */
R7 = R0; /* Copy of R0 */
R6 = R1;
SP += -12; /* Should always provide this space */
CALL ___udivsi3; /* Compute unsigned quotient using ___udiv32()*/
SP += 12;
R0 *= R6; /* Quotient * divisor */
R0 = R7 - R0; /* Dividend - (quotient * divisor) */
RETS = [SP++]; /* Pop return address */
( R7:6) = [SP++]; /* And registers */
RTS; /* Return remainder */
.LRETURN_ZERO_VAL:
R0 = 0;
.LRETURN_R0:
RTS;

View File

@ -0,0 +1,23 @@
.align 2
.global ___umulsi3_highpart;
.type ___umulsi3_highpart, STT_FUNC;
#ifdef CONFIG_ARITHMETIC_OPS_L1
.section .l1.text
#else
.text
#endif
___umulsi3_highpart:
R2 = R1.H * R0.H, R3 = R1.L * R0.H (FU);
R0 = R1.L * R0.L, R1 = R1.H * R0.L (FU);
R0 >>= 16;
/* Unsigned multiplication has the nice property that we can
ignore carry on this first addition. */
R0 = R0 + R3;
R0 = R0 + R1;
cc = ac0;
R1 = cc;
R1 = PACK(R1.l,R0.h);
R0 = R1 + R2;
RTS;

View File

@ -25,22 +25,52 @@
#ifndef _BLACKFIN_H_
#define _BLACKFIN_H_
#include <asm/cpu/defBF533.h>
#include <asm/cpu/bf533_serial.h>
#define lo(con32) ((con32) & 0xFFFF)
#define hi(con32) (((con32) >> 16) & 0xFFFF)
#ifdef CONFIG_BF561
#include <asm/cpu/defBF561.h>
#ifndef __ASSEMBLY__
#include <asm/cpu/cdefBF561.h>
#endif
#endif
#ifndef __ASSEMBLY__
#ifndef ASSEMBLY
#ifdef SHARED_RESOURCES
#include <asm/shared_resources.h>
#endif
#include <asm/cpu/cdefBF53x.h>
#endif
/* Get the System clock */
ulong get_sclk(void);
#endif
#include <asm/cpu/defBF533.h>
#include <asm/cpu/defBF533_extn.h>
#include <asm/cpu/bf533_serial.h>
#if ( CONFIG_CLKIN_HALF == 0 )
#define CONFIG_VCO_HZ ( CONFIG_CLKIN_HZ * CONFIG_VCO_MULT )
#else
#define CONFIG_VCO_HZ (( CONFIG_CLKIN_HZ * CONFIG_VCO_MULT ) / 2 )
#endif
#if (CONFIG_PLL_BYPASS == 0)
#define CONFIG_CCLK_HZ ( CONFIG_VCO_HZ / CONFIG_CCLK_DIV )
#define CONFIG_SCLK_HZ ( CONFIG_VCO_HZ / CONFIG_SCLK_DIV )
#else
#define CONFIG_CCLK_HZ CONFIG_CLKIN_HZ
#define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ
#endif
#if (CONFIG_CCLK_DIV == 1)
#define CONFIG_CCLK_ACT_DIV CCLK_DIV1
#endif
#if (CONFIG_CCLK_DIV == 2)
#define CONFIG_CCLK_ACT_DIV CCLK_DIV2
#endif
#if (CONFIG_CCLK_DIV == 4)
#define CONFIG_CCLK_ACT_DIV CCLK_DIV4
#endif
#if (CONFIG_CCLK_DIV == 8)
#define CONFIG_CCLK_ACT_DIV CCLK_DIV8
#endif
#ifndef CONFIG_CCLK_ACT_DIV
#define CONFIG_CCLK_ACT_DIV CONFIG_CCLK_DIV_not_defined_properly
#endif
#endif

View File

File diff suppressed because it is too large Load Diff

View File

@ -30,17 +30,6 @@
/* include all Core registers and bit definitions */
#include <asm/cpu/def_LPBlackfin.h>
/* Helper macros
* usage:
* P0.H = HI(UART_THR);
* P0.L = LO(UART_THR);
*/
#define LO(con32) ((con32) & 0xFFFF)
#define lo(con32) ((con32) & 0xFFFF)
#define HI(con32) (((con32) >> 16) & 0xFFFF)
#define hi(con32) (((con32) >> 16) & 0xFFFF)
/*
* System MMR Register Map
*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,76 @@
/*
* defBF533_extn.h
*
* This file is subject to the terms and conditions of the GNU Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Non-GPL License also available as part of VisualDSP++
*
* http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html
*
* (c) Copyright 2001-2005 Analog Devices, Inc. All rights reserved
*
* This file under source code control, please send bugs or changes to:
* dsptools.support@analog.com
*
*/
#ifndef _DEF_BF533_EXTN_H
#define _DEF_BF533_EXTN_H
#define OFFSET_( x ) ((x) & 0x0000FFFF) /* define macro for offset */
/* Delay inserted for PLL transition */
#define PLL_DELAY 0x1000
#define L1_ISRAM 0xFFA00000
#define L1_ISRAM_END 0xFFA10000
#define DATA_BANKA_SRAM 0xFF800000
#define DATA_BANKA_SRAM_END 0xFF808000
#define DATA_BANKB_SRAM 0xFF900000
#define DATA_BANKB_SRAM_END 0xFF908000
#define SYSMMR_BASE 0xFFC00000
#define WDSIZE16 0x00000004
/* Event Vector Table Address */
#define EVT_EMULATION_ADDR 0xffe02000
#define EVT_RESET_ADDR 0xffe02004
#define EVT_NMI_ADDR 0xffe02008
#define EVT_EXCEPTION_ADDR 0xffe0200c
#define EVT_GLOBAL_INT_ENB_ADDR 0xffe02010
#define EVT_HARDWARE_ERROR_ADDR 0xffe02014
#define EVT_TIMER_ADDR 0xffe02018
#define EVT_IVG7_ADDR 0xffe0201c
#define EVT_IVG8_ADDR 0xffe02020
#define EVT_IVG9_ADDR 0xffe02024
#define EVT_IVG10_ADDR 0xffe02028
#define EVT_IVG11_ADDR 0xffe0202c
#define EVT_IVG12_ADDR 0xffe02030
#define EVT_IVG13_ADDR 0xffe02034
#define EVT_IVG14_ADDR 0xffe02038
#define EVT_IVG15_ADDR 0xffe0203c
#define EVT_OVERRIDE_ADDR 0xffe02100
/* IMASK Bit values */
#define IVG15_POS 0x00008000
#define IVG14_POS 0x00004000
#define IVG13_POS 0x00002000
#define IVG12_POS 0x00001000
#define IVG11_POS 0x00000800
#define IVG10_POS 0x00000400
#define IVG9_POS 0x00000200
#define IVG8_POS 0x00000100
#define IVG7_POS 0x00000080
#define IVGTMR_POS 0x00000040
#define IVGHW_POS 0x00000020
#define WDOG_TMR_DISABLE (0xAD << 4)
#define ICTL_RST 0x00000000
#define ICTL_NMI 0x00000002
#define ICTL_GP 0x00000004
#define ICTL_DISABLE 0x00000003
/* Watch Dog timer values setup */
#define WATCHDOG_DISABLE WDOG_TMR_DISABLE | ICTL_DISABLE
#endif /* _DEF_BF533_EXTN_H */

View File

@ -1,64 +0,0 @@
/*
* U-boot - global_data.h Declarations for global data of u-boot
*
* Copyright (c) 2005 blackfin.uclinux.org
*
* (C) Copyright 2000-2004
* 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 __ASM_GBL_DATA_H
#define __ASM_GBL_DATA_H
#include <asm/irq.h>
/*
* The following data structure is placed in some memory wich is
* available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
* some locked parts of the data cache) to allow for a minimum set of
* global variables during system initialization (until we have set
* up the memory controller so that we can use RAM).
*
* Keep it *SMALL* and remember to set CFG_GBL_DATA_SIZE > sizeof(gd_t)
*/
typedef struct global_data {
bd_t *bd;
unsigned long flags;
unsigned long board_type;
unsigned long baudrate;
unsigned long have_console; /* serial_init() was called */
unsigned long ram_size; /* RAM size */
unsigned long reloc_off; /* Relocation Offset */
unsigned long env_addr; /* Address of Environment struct */
unsigned long env_valid; /* Checksum of Environment valid? */
void **jt; /* jump table */
} gd_t;
/*
* Global Data Flags
*/
#define GD_FLG_RELOC 0x00001 /* Code was relocated to RAM */
#define GD_FLG_DEVINIT 0x00002 /* Devices have been initialized */
#define GD_FLG_SILENT 0x00004 /* Silent mode */
#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("P5")
#endif

View File

@ -25,10 +25,6 @@
#ifndef _BLACKFIN_IO_H
#define _BLACKFIN_IO_H
#ifdef __KERNEL__
#include <linux/config.h>
/* function prototypes for CF support */
extern void cf_outsw(unsigned short *addr, unsigned short *sect_buf, int words);
extern void cf_insw(unsigned short *sect_buf, unsigned short *addr, int words);
@ -119,4 +115,3 @@ extern void blkfin_inv_cache_all(void);
#define dma_cache_wback_inv(_start,_size) do { blkfin_inv_cache_all();} while (0)
#endif
#endif

View File

@ -1,89 +0,0 @@
/*
* U-boot - machdep.h
*
* Copyright (c) 2005 blackfin.uclinux.org
*
* 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 _BLACKFIN_MACHDEP_H
#define _BLACKFIN_MACHDEP_H
/* Machine dependent initial routines:
*
* Based on include/asm-m68knommu/machdep.h
* For blackfin, just now we only have bfin, so they'd point to the default bfin
*
*/
struct pt_regs;
struct kbd_repeat;
struct mktime;
struct hwclk_time;
struct gendisk;
struct buffer_head;
extern void (*mach_sched_init) (void (*handler) (int, void *, struct pt_regs *));
/* machine dependent keyboard functions */
extern int (*mach_keyb_init) (void);
extern int (*mach_kbdrate) (struct kbd_repeat *);
extern void (*mach_kbd_leds) (unsigned int);
/* machine dependent irq functions */
extern void (*mach_init_IRQ) (void);
extern void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *);
extern int (*mach_request_irq) (unsigned int irq,
void (*handler) (int, void *,
struct pt_regs *),
unsigned long flags, const char *devname,
void *dev_id);
extern void (*mach_free_irq) (unsigned int irq, void *dev_id);
extern void (*mach_get_model) (char *model);
extern int (*mach_get_hardware_list) (char *buffer);
extern int (*mach_get_irq_list) (char *buf);
extern void (*mach_process_int) (int irq, struct pt_regs * fp);
/* machine dependent timer functions */
extern unsigned long (*mach_gettimeoffset) (void);
extern void (*mach_gettod) (int *year, int *mon, int *day, int *hour,
int *min, int *sec);
extern int (*mach_hwclk) (int, struct hwclk_time *);
extern int (*mach_set_clock_mmss) (unsigned long);
extern void (*mach_reset) (void);
extern void (*mach_halt) (void);
extern void (*mach_power_off) (void);
extern unsigned long (*mach_hd_init) (unsigned long, unsigned long);
extern void (*mach_hd_setup) (char *, int *);
extern long mach_max_dma_address;
extern void (*mach_floppy_setup) (char *, int *);
extern void (*mach_floppy_eject) (void);
extern void (*mach_heartbeat) (int);
extern void (*mach_l2_flush) (int);
extern int mach_sysrq_key;
extern int mach_sysrq_shift_state;
extern int mach_sysrq_shift_mask;
extern char *mach_sysrq_xlate;
#ifdef CONFIG_UCLINUX
extern void config_BSP(char *command, int len);
extern void (*mach_tick) (void);
#endif
#endif

View File

@ -25,8 +25,6 @@
#ifndef _BLACKFIN_PAGE_H
#define _BLACKFIN_PAGE_H
#include <linux/config.h>
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT (12)
@ -112,11 +110,6 @@ extern __inline__ int get_order(unsigned long size)
#define virt_to_page(addr) (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
#define BUG() do { \
\
while (1); /* dead-loop */ \
} while (0)
#define PAGE_BUG(page) do { \
BUG(); \
} while (0)

View File

@ -22,12 +22,6 @@
* MA 02111-1307 USA
*/
/*
* Changes made by Akbar Hussain April 10, 2001
*/
#include <linux/config.h>
/* This handles the memory map.. */
#ifdef CONFIG_BLACKFIN

View File

@ -36,7 +36,6 @@
*/
#define current_text_addr() ({ __label__ _l; _l: &&_l;})
#include <linux/config.h>
#include <asm/segment.h>
#include <asm/ptrace.h>
#include <asm/current.h>

View File

@ -29,8 +29,6 @@
#ifndef _BLACKFIN_SETUP_H
#define _BLACKFIN_SETUP_H
#include <linux/config.h>
/*
* Linux/Blackfin Architectures
*/
@ -75,12 +73,14 @@ extern unsigned long vme_brdtype;
extern int blackfin_num_memory; /* # of memory blocks found (and used) */
extern int blackfin_realnum_memory; /* real # of memory blocks found */
extern struct mem_info blackfin_memory[NUM_MEMINFO]; /* memory description */
struct mem_info {
unsigned long addr; /* physical address of memory chunk */
unsigned long size; /* length of memory chunk (in bytes) */
};
extern struct mem_info blackfin_memory[NUM_MEMINFO]; /* memory description */
#endif
#endif

View File

@ -27,53 +27,4 @@
#ifndef _BLACKFINNOMMU_STRING_H_
#define _BLACKFINNOMMU_STRING_H_
#ifdef __KERNEL__ /* only set these up for kernel code */
#include <asm/setup.h>
#include <asm/page.h>
#include <asm/cpu/defBF533.h>
#define __HAVE_ARCH_STRCPY
#define __HAVE_ARCH_STRNCPY
#define __HAVE_ARCH_STRCMP
#define __HAVE_ARCH_STRNCMP
#define __HAVE_ARCH_MEMCPY
extern char *strcpy(char *dest, const char *src);
extern char *strncpy(char *dest, const char *src, size_t n);
extern int strcmp(const char *cs, const char *ct);
extern int strncmp(const char *cs, const char *ct, size_t count);
extern void * memcpy(void * dest,const void *src,size_t count);
extern void *memset(void *s, int c, size_t count);
extern int memcmp(const void *, const void *, __kernel_size_t);
#else /* KERNEL */
/*
* let user libraries deal with these,
* IMHO the kernel has no place defining these functions for user apps
*/
#define __HAVE_ARCH_STRCPY 1
#define __HAVE_ARCH_STRNCPY 1
#define __HAVE_ARCH_STRCAT 1
#define __HAVE_ARCH_STRNCAT 1
#define __HAVE_ARCH_STRCMP 1
#define __HAVE_ARCH_STRNCMP 1
#define __HAVE_ARCH_STRNICMP 1
#define __HAVE_ARCH_STRCHR 1
#define __HAVE_ARCH_STRRCHR 1
#define __HAVE_ARCH_STRSTR 1
#define __HAVE_ARCH_STRLEN 1
#define __HAVE_ARCH_STRNLEN 1
#define __HAVE_ARCH_MEMSET 1
#define __HAVE_ARCH_MEMCPY 1
#define __HAVE_ARCH_MEMMOVE 1
#define __HAVE_ARCH_MEMSCAN 1
#define __HAVE_ARCH_MEMCMP 1
#define __HAVE_ARCH_MEMCHR 1
#define __HAVE_ARCH_STRTOK 1
#endif /* KERNEL */
#endif /* _BLACKFIN_STRING_H_ */

View File

@ -1,49 +0,0 @@
#
# U-boot Makefile
#
# Copyright (c) 2005 blackfin.uclinux.org
#
# (C) Copyright 2000-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 = $(obj)lib$(ARCH).a
SOBJS =
COBJS = board.o bf533_linux.o bf533_string.o cache.o muldi3.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
$(LIB): $(obj).depend $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################

View File

@ -1,279 +0,0 @@
/*
* U-boot - board.c First C file to be called contains init routines
*
* Copyright (c) 2005 blackfin.uclinux.org
*
* (C) Copyright 2000-2004
* 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 <command.h>
#include <malloc.h>
#include <devices.h>
#include <version.h>
#include <net.h>
#include <environment.h>
#include "blackfin_board.h"
#include "../drivers/smc91111.h"
DECLARE_GLOBAL_DATA_PTR;
extern flash_info_t flash_info[];
static void mem_malloc_init(void)
{
mem_malloc_start = CFG_MALLOC_BASE;
mem_malloc_end = (CFG_MALLOC_BASE + CFG_MALLOC_LEN);
mem_malloc_brk = mem_malloc_start;
memset((void *) mem_malloc_start, 0,
mem_malloc_end - mem_malloc_start);
}
void *sbrk(ptrdiff_t increment)
{
ulong old = mem_malloc_brk;
ulong new = old + increment;
if ((new < mem_malloc_start) || (new > mem_malloc_end)) {
return (NULL);
}
mem_malloc_brk = new;
return ((void *) old);
}
static int display_banner(void)
{
sprintf(version_string, VERSION_STRING_FORMAT, VERSION_STRING);
printf("%s\n", version_string);
return (0);
}
static void display_flash_config(ulong size)
{
puts("FLASH: ");
print_size(size, "\n");
return;
}
static int init_baudrate(void)
{
uchar tmp[64];
int i = getenv_r("baudrate", tmp, sizeof(tmp));
gd->bd->bi_baudrate = gd->baudrate = (i > 0)
? (int) simple_strtoul(tmp, NULL, 10)
: CONFIG_BAUDRATE;
return (0);
}
#ifdef DEBUG
static void display_global_data(void)
{
bd_t *bd;
bd = gd->bd;
printf("--flags:%x\n", gd->flags);
printf("--board_type:%x\n", gd->board_type);
printf("--baudrate:%x\n", gd->baudrate);
printf("--have_console:%x\n", gd->have_console);
printf("--ram_size:%x\n", gd->ram_size);
printf("--reloc_off:%x\n", gd->reloc_off);
printf("--env_addr:%x\n", gd->env_addr);
printf("--env_valid:%x\n", gd->env_valid);
printf("--bd:%x %x\n", gd->bd, bd);
printf("---bi_baudrate:%x\n", bd->bi_baudrate);
printf("---bi_ip_addr:%x\n", bd->bi_ip_addr);
printf("---bi_enetaddr:%x %x %x %x %x %x\n",
bd->bi_enetaddr[0],
bd->bi_enetaddr[1],
bd->bi_enetaddr[2],
bd->bi_enetaddr[3],
bd->bi_enetaddr[4],
bd->bi_enetaddr[5]);
printf("---bi_arch_number:%x\n", bd->bi_arch_number);
printf("---bi_boot_params:%x\n", bd->bi_boot_params);
printf("---bi_memstart:%x\n", bd->bi_memstart);
printf("---bi_memsize:%x\n", bd->bi_memsize);
printf("---bi_flashstart:%x\n", bd->bi_flashstart);
printf("---bi_flashsize:%x\n", bd->bi_flashsize);
printf("---bi_flashoffset:%x\n", bd->bi_flashoffset);
printf("--jt:%x *:%x\n", gd->jt, *(gd->jt));
}
#endif
/*
* All attempts to come up with a "common" initialization sequence
* that works for all boards and architectures failed: some of the
* requirements are just _too_ different. To get rid of the resulting
* mess of board dependend #ifdef'ed code we now make the whole
* initialization sequence configurable to the user.
*
* The requirements for any new initalization function is simple: it
* receives a pointer to the "global data" structure as it's only
* argument, and returns an integer return code, where 0 means
* "continue" and != 0 means "fatal error, hang the system".
*/
void board_init_f(ulong bootflag)
{
ulong addr;
bd_t *bd;
gd = (gd_t *) (CFG_GBL_DATA_ADDR);
memset((void *) gd, 0, sizeof(gd_t));
/* Board data initialization */
addr = (CFG_GBL_DATA_ADDR + sizeof(gd_t));
/* Align to 4 byte boundary */
addr &= ~(4 - 1);
bd = (bd_t*)addr;
gd->bd = bd;
memset((void *) bd, 0, sizeof(bd_t));
/* Initialize */
init_IRQ();
env_init(); /* initialize environment */
init_baudrate(); /* initialze baudrate settings */
serial_init(); /* serial communications setup */
console_init_f();
display_banner(); /* say that we are here */
checkboard();
#if defined(CONFIG_RTC_BF533) && (CONFIG_COMMANDS & CFG_CMD_DATE)
rtc_init();
#endif
timer_init();
printf("Clock: VCO: %lu MHz, Core: %lu MHz, System: %lu MHz\n", \
CONFIG_VCO_HZ/1000000, CONFIG_CCLK_HZ/1000000, CONFIG_SCLK_HZ/1000000);
printf("SDRAM: ");
print_size(initdram(0), "\n");
board_init_r((gd_t *) gd, 0x20000010);
}
void board_init_r(gd_t * id, ulong dest_addr)
{
ulong size;
extern void malloc_bin_reloc(void);
char *s, *e;
bd_t *bd;
int i;
gd = id;
gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */
bd = gd->bd;
#if CONFIG_STAMP
/* There are some other pointer constants we must deal with */
/* configure available FLASH banks */
size = flash_init();
display_flash_config(size);
flash_protect(FLAG_PROTECT_SET, CFG_FLASH_BASE, CFG_FLASH_BASE + 0x1ffff, &flash_info[0]);
bd->bi_flashstart = CFG_FLASH_BASE;
bd->bi_flashsize = size;
bd->bi_flashoffset = 0;
#else
bd->bi_flashstart = 0;
bd->bi_flashsize = 0;
bd->bi_flashoffset = 0;
#endif
/* initialize malloc() area */
mem_malloc_init();
malloc_bin_reloc();
/* relocate environment function pointers etc. */
env_relocate();
/* board MAC address */
s = getenv("ethaddr");
for (i = 0; i < 6; ++i) {
bd->bi_enetaddr[i] = s ? simple_strtoul(s, &e, 16) : 0;
if (s)
s = (*e) ? e + 1 : e;
}
/* IP Address */
bd->bi_ip_addr = getenv_IPaddr("ipaddr");
/* Initialize devices */
devices_init();
jumptable_init();
/* Initialize the console (after the relocation and devices init) */
console_init_r();
/* Initialize from environment */
if ((s = getenv("loadaddr")) != NULL) {
load_addr = simple_strtoul(s, NULL, 16);
}
#if (CONFIG_COMMANDS & CFG_CMD_NET)
if ((s = getenv("bootfile")) != NULL) {
copy_filename(BootFile, s, sizeof(BootFile));
}
#endif
#if defined(CONFIG_MISC_INIT_R)
/* miscellaneous platform dependent initialisations */
misc_init_r();
#endif
#ifdef CONFIG_DRIVER_SMC91111
#ifdef SHARED_RESOURCES
/* Switch to Ethernet */
swap_to(ETHERNET);
#endif
if ( (SMC_inw(BANK_SELECT) & UPPER_BYTE_MASK) != SMC_IDENT ) {
printf("ERROR: Can't find SMC91111 at address %x\n", SMC_BASE_ADDRESS);
} else {
printf("Net: SMC91111 at 0x%08X\n", SMC_BASE_ADDRESS);
}
#ifdef SHARED_RESOURCES
swap_to(FLASH);
#endif
#endif
#ifdef CONFIG_SOFT_I2C
init_func_i2c();
#endif
#ifdef DEBUG
display_global_data(void);
#endif
/* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {
main_loop();
}
}
#ifdef CONFIG_SOFT_I2C
static int init_func_i2c (void)
{
puts ("I2C: ");
i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
puts ("ready\n");
return (0);
}
#endif
void hang(void)
{
puts("### ERROR ### Please RESET the board ###\n");
for (;;);
}