GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
|
||||
## Build a couple of necessary functions into a private libgcc
|
||||
## if the user asked for it
|
||||
lib-$(CONFIG_USE_PRIVATE_LIBGCC) += lshrdi3.o muldi3.o ashldi3.o
|
||||
|
||||
obj-$(CONFIG_CMD_BOOTM) += bootm.o
|
||||
obj-y += cache.o
|
||||
obj-y += interrupts.o
|
||||
obj-y += time.o
|
||||
obj-y += traps.o
|
||||
@@ -0,0 +1,49 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* ashldi3.c extracted from gcc-2.7.2.3/libgcc2.c and
|
||||
* gcc-2.7.2.3/longlong.h
|
||||
*
|
||||
* Copyright (C) 1989-2015 Free Software Foundation, Inc.
|
||||
*/
|
||||
|
||||
#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;
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <env.h>
|
||||
#include <image.h>
|
||||
#include <u-boot/zlib.h>
|
||||
#include <bzlib.h>
|
||||
#include <watchdog.h>
|
||||
#include <asm/byteorder.h>
|
||||
#ifdef CONFIG_SHOW_BOOT_PROGRESS
|
||||
# include <status_led.h>
|
||||
#endif
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define PHYSADDR(x) x
|
||||
|
||||
#define LINUX_MAX_ENVS 256
|
||||
#define LINUX_MAX_ARGS 256
|
||||
|
||||
static ulong get_sp (void);
|
||||
static void set_clocks_in_mhz (bd_t *kbd);
|
||||
|
||||
void arch_lmb_reserve(struct lmb *lmb)
|
||||
{
|
||||
ulong sp;
|
||||
|
||||
/*
|
||||
* Booting a (Linux) kernel image
|
||||
*
|
||||
* Allocate space for command line and board info - the
|
||||
* address should be as high as possible within the reach of
|
||||
* the kernel (see CONFIG_SYS_BOOTMAPSZ settings), but in unused
|
||||
* memory, which means far enough below the current stack
|
||||
* pointer.
|
||||
*/
|
||||
sp = get_sp();
|
||||
debug ("## Current stack ends at 0x%08lx ", sp);
|
||||
|
||||
/* adjust sp by 1K to be safe */
|
||||
sp -= 1024;
|
||||
lmb_reserve(lmb, sp, (CONFIG_SYS_SDRAM_BASE + gd->ram_size - sp));
|
||||
}
|
||||
|
||||
int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images)
|
||||
{
|
||||
int ret;
|
||||
bd_t *kbd;
|
||||
void (*kernel) (bd_t *, ulong, ulong, ulong, ulong);
|
||||
struct lmb *lmb = &images->lmb;
|
||||
|
||||
/*
|
||||
* allow the PREP bootm subcommand, it is required for bootm to work
|
||||
*/
|
||||
if (flag & BOOTM_STATE_OS_PREP)
|
||||
return 0;
|
||||
|
||||
if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
|
||||
return 1;
|
||||
|
||||
/* allocate space for kernel copy of board info */
|
||||
ret = boot_get_kbd (lmb, &kbd);
|
||||
if (ret) {
|
||||
puts("ERROR with allocation of kernel bd\n");
|
||||
goto error;
|
||||
}
|
||||
set_clocks_in_mhz(kbd);
|
||||
|
||||
ret = image_setup_linux(images);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))images->ep;
|
||||
|
||||
debug("## Transferring control to Linux (at address %08lx) ...\n",
|
||||
(ulong) kernel);
|
||||
|
||||
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
|
||||
|
||||
/*
|
||||
* Linux Kernel Parameters (passing board info data):
|
||||
* sp+00: Ignore, side effect of using jsr to jump to kernel
|
||||
* sp+04: ptr to board info data
|
||||
* sp+08: initrd_start or 0 if no initrd
|
||||
* sp+12: initrd_end - unused if initrd_start is 0
|
||||
* sp+16: Start of command line string
|
||||
* sp+20: End of command line string
|
||||
*/
|
||||
(*kernel)(kbd, images->initrd_start, images->initrd_end,
|
||||
images->cmdline_start, images->cmdline_end);
|
||||
/* does not return */
|
||||
error:
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ulong get_sp (void)
|
||||
{
|
||||
ulong sp;
|
||||
|
||||
asm("movel %%a7, %%d0\n"
|
||||
"movel %%d0, %0\n": "=d"(sp): :"%d0");
|
||||
|
||||
return sp;
|
||||
}
|
||||
|
||||
static void set_clocks_in_mhz (bd_t *kbd)
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = env_get("clocks_in_mhz");
|
||||
if (s) {
|
||||
/* convert all clock information to MHz */
|
||||
kbd->bi_intfreq /= 1000000L;
|
||||
kbd->bi_busfreq /= 1000000L;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <cpu_func.h>
|
||||
#include <asm/immap.h>
|
||||
#include <asm/cache.h>
|
||||
|
||||
volatile int *cf_icache_status = (int *)ICACHE_STATUS;
|
||||
volatile int *cf_dcache_status = (int *)DCACHE_STATUS;
|
||||
|
||||
void flush_cache(ulong start_addr, ulong size)
|
||||
{
|
||||
/* Must be implemented for all M68k processors with copy-back data cache */
|
||||
}
|
||||
|
||||
int icache_status(void)
|
||||
{
|
||||
return *cf_icache_status;
|
||||
}
|
||||
|
||||
int dcache_status(void)
|
||||
{
|
||||
return *cf_dcache_status;
|
||||
}
|
||||
|
||||
void icache_enable(void)
|
||||
{
|
||||
icache_invalid();
|
||||
|
||||
*cf_icache_status = 1;
|
||||
|
||||
#if defined(CONFIG_CF_V4) || defined(CONFIG_CF_V4E)
|
||||
__asm__ __volatile__("movec %0, %%acr2"::"r"(CONFIG_SYS_CACHE_ACR2));
|
||||
__asm__ __volatile__("movec %0, %%acr3"::"r"(CONFIG_SYS_CACHE_ACR3));
|
||||
#if defined(CONFIG_CF_V4E)
|
||||
__asm__ __volatile__("movec %0, %%acr6"::"r"(CONFIG_SYS_CACHE_ACR6));
|
||||
__asm__ __volatile__("movec %0, %%acr7"::"r"(CONFIG_SYS_CACHE_ACR7));
|
||||
#endif
|
||||
#else
|
||||
__asm__ __volatile__("movec %0, %%acr0"::"r"(CONFIG_SYS_CACHE_ACR0));
|
||||
__asm__ __volatile__("movec %0, %%acr1"::"r"(CONFIG_SYS_CACHE_ACR1));
|
||||
#endif
|
||||
|
||||
__asm__ __volatile__("movec %0, %%cacr"::"r"(CONFIG_SYS_CACHE_ICACR));
|
||||
}
|
||||
|
||||
void icache_disable(void)
|
||||
{
|
||||
u32 temp = 0;
|
||||
|
||||
*cf_icache_status = 0;
|
||||
icache_invalid();
|
||||
|
||||
#if defined(CONFIG_CF_V4) || defined(CONFIG_CF_V4E)
|
||||
__asm__ __volatile__("movec %0, %%acr2"::"r"(temp));
|
||||
__asm__ __volatile__("movec %0, %%acr3"::"r"(temp));
|
||||
#if defined(CONFIG_CF_V4E)
|
||||
__asm__ __volatile__("movec %0, %%acr6"::"r"(temp));
|
||||
__asm__ __volatile__("movec %0, %%acr7"::"r"(temp));
|
||||
#endif
|
||||
#else
|
||||
__asm__ __volatile__("movec %0, %%acr0"::"r"(temp));
|
||||
__asm__ __volatile__("movec %0, %%acr1"::"r"(temp));
|
||||
#endif
|
||||
}
|
||||
|
||||
void icache_invalid(void)
|
||||
{
|
||||
u32 temp;
|
||||
|
||||
temp = CONFIG_SYS_ICACHE_INV;
|
||||
if (*cf_icache_status)
|
||||
temp |= CONFIG_SYS_CACHE_ICACR;
|
||||
|
||||
__asm__ __volatile__("movec %0, %%cacr"::"r"(temp));
|
||||
}
|
||||
|
||||
/*
|
||||
* data cache only for ColdFire V4 such as MCF547x_8x, MCF5445x
|
||||
* the dcache will be dummy in ColdFire V2 and V3
|
||||
*/
|
||||
void dcache_enable(void)
|
||||
{
|
||||
dcache_invalid();
|
||||
*cf_dcache_status = 1;
|
||||
|
||||
#if defined(CONFIG_CF_V4) || defined(CONFIG_CF_V4E)
|
||||
__asm__ __volatile__("movec %0, %%acr0"::"r"(CONFIG_SYS_CACHE_ACR0));
|
||||
__asm__ __volatile__("movec %0, %%acr1"::"r"(CONFIG_SYS_CACHE_ACR1));
|
||||
#if defined(CONFIG_CF_V4E)
|
||||
__asm__ __volatile__("movec %0, %%acr4"::"r"(CONFIG_SYS_CACHE_ACR4));
|
||||
__asm__ __volatile__("movec %0, %%acr5"::"r"(CONFIG_SYS_CACHE_ACR5));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
__asm__ __volatile__("movec %0, %%cacr"::"r"(CONFIG_SYS_CACHE_DCACR));
|
||||
}
|
||||
|
||||
void dcache_disable(void)
|
||||
{
|
||||
u32 temp = 0;
|
||||
|
||||
*cf_dcache_status = 0;
|
||||
dcache_invalid();
|
||||
|
||||
__asm__ __volatile__("movec %0, %%cacr"::"r"(temp));
|
||||
|
||||
#if defined(CONFIG_CF_V4) || defined(CONFIG_CF_V4E)
|
||||
__asm__ __volatile__("movec %0, %%acr0"::"r"(temp));
|
||||
__asm__ __volatile__("movec %0, %%acr1"::"r"(temp));
|
||||
#if defined(CONFIG_CF_V4E)
|
||||
__asm__ __volatile__("movec %0, %%acr4"::"r"(temp));
|
||||
__asm__ __volatile__("movec %0, %%acr5"::"r"(temp));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void dcache_invalid(void)
|
||||
{
|
||||
#if defined(CONFIG_CF_V4) || defined(CONFIG_CF_V4E)
|
||||
u32 temp;
|
||||
|
||||
temp = CONFIG_SYS_DCACHE_INV;
|
||||
if (*cf_dcache_status)
|
||||
temp |= CONFIG_SYS_CACHE_DCACR;
|
||||
if (*cf_icache_status)
|
||||
temp |= CONFIG_SYS_CACHE_ICACR;
|
||||
|
||||
__asm__ __volatile__("movec %0, %%cacr"::"r"(temp));
|
||||
#endif
|
||||
}
|
||||
|
||||
__weak void invalidate_dcache_range(unsigned long start, unsigned long stop)
|
||||
{
|
||||
/* An empty stub, real implementation should be in platform code */
|
||||
}
|
||||
__weak void flush_dcache_range(unsigned long start, unsigned long stop)
|
||||
{
|
||||
/* An empty stub, real implementation should be in platform code */
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2000-2004
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* (C) Copyright 2007 Freescale Semiconductor Inc
|
||||
* TsiChung Liew (Tsi-Chung.Liew@freescale.com)
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <irq_func.h>
|
||||
#include <watchdog.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/immap.h>
|
||||
|
||||
#define NR_IRQS (CONFIG_SYS_NUM_IRQS)
|
||||
|
||||
/*
|
||||
* Interrupt vector functions.
|
||||
*/
|
||||
struct interrupt_action {
|
||||
interrupt_handler_t *handler;
|
||||
void *arg;
|
||||
};
|
||||
|
||||
static struct interrupt_action irq_vecs[NR_IRQS];
|
||||
|
||||
static __inline__ unsigned short get_sr (void)
|
||||
{
|
||||
unsigned short sr;
|
||||
|
||||
asm volatile ("move.w %%sr,%0":"=r" (sr):);
|
||||
|
||||
return sr;
|
||||
}
|
||||
|
||||
static __inline__ void set_sr (unsigned short sr)
|
||||
{
|
||||
asm volatile ("move.w %0,%%sr"::"r" (sr));
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/*
|
||||
* Install and free an interrupt handler
|
||||
*/
|
||||
void irq_install_handler(int vec, interrupt_handler_t * handler, void *arg)
|
||||
{
|
||||
if ((vec < 0) || (vec >= NR_IRQS)) {
|
||||
printf ("irq_install_handler: wrong interrupt vector %d\n",
|
||||
vec);
|
||||
return;
|
||||
}
|
||||
|
||||
irq_vecs[vec].handler = handler;
|
||||
irq_vecs[vec].arg = arg;
|
||||
}
|
||||
|
||||
void irq_free_handler(int vec)
|
||||
{
|
||||
if ((vec < 0) || (vec >= NR_IRQS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
irq_vecs[vec].handler = NULL;
|
||||
irq_vecs[vec].arg = NULL;
|
||||
}
|
||||
|
||||
void enable_interrupts(void)
|
||||
{
|
||||
unsigned short sr;
|
||||
|
||||
sr = get_sr ();
|
||||
set_sr (sr & ~0x0700);
|
||||
}
|
||||
|
||||
int disable_interrupts(void)
|
||||
{
|
||||
unsigned short sr;
|
||||
|
||||
sr = get_sr ();
|
||||
set_sr (sr | 0x0700);
|
||||
|
||||
return ((sr & 0x0700) == 0); /* return true, if interrupts were enabled before */
|
||||
}
|
||||
|
||||
void int_handler (struct pt_regs *fp)
|
||||
{
|
||||
int vec;
|
||||
|
||||
vec = (fp->vector >> 2) & 0xff;
|
||||
if (vec > 0x40)
|
||||
vec -= 0x40;
|
||||
|
||||
if (irq_vecs[vec].handler != NULL) {
|
||||
irq_vecs[vec].handler (irq_vecs[vec].arg);
|
||||
} else {
|
||||
printf ("\nBogus External Interrupt Vector %d\n", vec);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* lshrdi3.c extracted from gcc-2.7.2.3/libgcc2.c and
|
||||
* gcc-2.7.2.3/longlong.h
|
||||
*
|
||||
* Copyright (C) 1989-2015 Free Software Foundation, Inc.
|
||||
*/
|
||||
|
||||
#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;
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and
|
||||
* gcc-2.7.2.3/longlong.h
|
||||
*
|
||||
* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
|
||||
*/
|
||||
|
||||
#define SI_TYPE_SIZE 32
|
||||
#define __BITS4 (SI_TYPE_SIZE / 4)
|
||||
#define __ll_B (1L << (SI_TYPE_SIZE / 2))
|
||||
#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
|
||||
#define __ll_highpart(t) ((USItype) (t) / __ll_B)
|
||||
|
||||
#define umul_ppmm(w1, w0, u, v) \
|
||||
do { \
|
||||
USItype __x0, __x1, __x2, __x3; \
|
||||
USItype __ul, __vl, __uh, __vh; \
|
||||
\
|
||||
__ul = __ll_lowpart (u); \
|
||||
__uh = __ll_highpart (u); \
|
||||
__vl = __ll_lowpart (v); \
|
||||
__vh = __ll_highpart (v); \
|
||||
\
|
||||
__x0 = (USItype) __ul * __vl; \
|
||||
__x1 = (USItype) __ul * __vh; \
|
||||
__x2 = (USItype) __uh * __vl; \
|
||||
__x3 = (USItype) __uh * __vh; \
|
||||
\
|
||||
__x1 += __ll_highpart (__x0);/* this can't give carry */ \
|
||||
__x1 += __x2; /* but this indeed can */ \
|
||||
if (__x1 < __x2) /* did we get it? */ \
|
||||
__x3 += __ll_B; /* yes, add it in the proper pos. */ \
|
||||
\
|
||||
(w1) = __x3 + __ll_highpart (__x1); \
|
||||
(w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
|
||||
} while (0)
|
||||
|
||||
#define __umulsidi3(u, v) \
|
||||
({DIunion __w; \
|
||||
umul_ppmm (__w.s.high, __w.s.low, u, v); \
|
||||
__w.ll; })
|
||||
|
||||
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;
|
||||
|
||||
DItype __muldi3 (DItype u, DItype v)
|
||||
{
|
||||
DIunion w;
|
||||
DIunion uu, vv;
|
||||
|
||||
uu.ll = u,
|
||||
vv.ll = v;
|
||||
|
||||
w.ll = __umulsidi3 (uu.s.low, vv.s.low);
|
||||
w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
|
||||
+ (USItype) uu.s.high * (USItype) vv.s.low);
|
||||
|
||||
return w.ll;
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2003 Josef Baumgartner <josef.baumgartner@telex.de>
|
||||
*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <irq_func.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <asm/timer.h>
|
||||
#include <asm/immap.h>
|
||||
#include <watchdog.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static volatile ulong timestamp = 0;
|
||||
|
||||
#ifndef CONFIG_SYS_WATCHDOG_FREQ
|
||||
#define CONFIG_SYS_WATCHDOG_FREQ (CONFIG_SYS_HZ / 2)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MCFTMR)
|
||||
#ifndef CONFIG_SYS_UDELAY_BASE
|
||||
# error "uDelay base not defined!"
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_SYS_TMR_BASE) || !defined(CONFIG_SYS_INTR_BASE) || !defined(CONFIG_SYS_TMRINTR_NO) || !defined(CONFIG_SYS_TMRINTR_MASK)
|
||||
# error "TMR_BASE, INTR_BASE, TMRINTR_NO or TMRINTR_MASk not defined!"
|
||||
#endif
|
||||
extern void dtimer_intr_setup(void);
|
||||
|
||||
void __udelay(unsigned long usec)
|
||||
{
|
||||
volatile dtmr_t *timerp = (dtmr_t *) (CONFIG_SYS_UDELAY_BASE);
|
||||
uint start, now, tmp;
|
||||
|
||||
while (usec > 0) {
|
||||
if (usec > 65000)
|
||||
tmp = 65000;
|
||||
else
|
||||
tmp = usec;
|
||||
usec = usec - tmp;
|
||||
|
||||
/* Set up TIMER 3 as timebase clock */
|
||||
timerp->tmr = DTIM_DTMR_RST_RST;
|
||||
timerp->tcn = 0;
|
||||
/* set period to 1 us */
|
||||
timerp->tmr =
|
||||
CONFIG_SYS_TIMER_PRESCALER | DTIM_DTMR_CLK_DIV1 | DTIM_DTMR_FRR |
|
||||
DTIM_DTMR_RST_EN;
|
||||
|
||||
start = now = timerp->tcn;
|
||||
while (now < start + tmp)
|
||||
now = timerp->tcn;
|
||||
}
|
||||
}
|
||||
|
||||
void dtimer_interrupt(void *not_used)
|
||||
{
|
||||
volatile dtmr_t *timerp = (dtmr_t *) (CONFIG_SYS_TMR_BASE);
|
||||
|
||||
/* check for timer interrupt asserted */
|
||||
if ((CONFIG_SYS_TMRPND_REG & CONFIG_SYS_TMRINTR_MASK) == CONFIG_SYS_TMRINTR_PEND) {
|
||||
timerp->ter = (DTIM_DTER_CAP | DTIM_DTER_REF);
|
||||
timestamp++;
|
||||
|
||||
#if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG)
|
||||
if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0) {
|
||||
WATCHDOG_RESET ();
|
||||
}
|
||||
#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int timer_init(void)
|
||||
{
|
||||
volatile dtmr_t *timerp = (dtmr_t *) (CONFIG_SYS_TMR_BASE);
|
||||
|
||||
timestamp = 0;
|
||||
|
||||
timerp->tcn = 0;
|
||||
timerp->trr = 0;
|
||||
|
||||
/* Set up TIMER 4 as clock */
|
||||
timerp->tmr = DTIM_DTMR_RST_RST;
|
||||
|
||||
/* initialize and enable timer interrupt */
|
||||
irq_install_handler(CONFIG_SYS_TMRINTR_NO, dtimer_interrupt, 0);
|
||||
|
||||
timerp->tcn = 0;
|
||||
timerp->trr = 1000; /* Interrupt every ms */
|
||||
|
||||
dtimer_intr_setup();
|
||||
|
||||
/* set a period of 1us, set timer mode to restart and enable timer and interrupt */
|
||||
timerp->tmr = CONFIG_SYS_TIMER_PRESCALER | DTIM_DTMR_CLK_DIV1 |
|
||||
DTIM_DTMR_FRR | DTIM_DTMR_ORRI | DTIM_DTMR_RST_EN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
return (timestamp - base);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MCFTMR */
|
||||
|
||||
#if defined(CONFIG_MCFPIT)
|
||||
#if !defined(CONFIG_SYS_PIT_BASE)
|
||||
# error "CONFIG_SYS_PIT_BASE not defined!"
|
||||
#endif
|
||||
|
||||
static unsigned short lastinc;
|
||||
|
||||
void __udelay(unsigned long usec)
|
||||
{
|
||||
volatile pit_t *timerp = (pit_t *) (CONFIG_SYS_UDELAY_BASE);
|
||||
uint tmp;
|
||||
|
||||
while (usec > 0) {
|
||||
if (usec > 65000)
|
||||
tmp = 65000;
|
||||
else
|
||||
tmp = usec;
|
||||
usec = usec - tmp;
|
||||
|
||||
/* Set up TIMER 3 as timebase clock */
|
||||
timerp->pcsr = PIT_PCSR_OVW;
|
||||
timerp->pmr = 0;
|
||||
/* set period to 1 us */
|
||||
timerp->pcsr |= PIT_PCSR_PRE(CONFIG_SYS_PIT_PRESCALE) | PIT_PCSR_EN;
|
||||
|
||||
timerp->pmr = tmp;
|
||||
while (timerp->pcntr > 0) ;
|
||||
}
|
||||
}
|
||||
|
||||
void timer_init(void)
|
||||
{
|
||||
volatile pit_t *timerp = (pit_t *) (CONFIG_SYS_PIT_BASE);
|
||||
timestamp = 0;
|
||||
|
||||
/* Set up TIMER 4 as poll clock */
|
||||
timerp->pcsr = PIT_PCSR_OVW;
|
||||
timerp->pmr = lastinc = 0;
|
||||
timerp->pcsr |= PIT_PCSR_PRE(CONFIG_SYS_PIT_PRESCALE) | PIT_PCSR_EN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
unsigned short now, diff;
|
||||
volatile pit_t *timerp = (pit_t *) (CONFIG_SYS_PIT_BASE);
|
||||
|
||||
now = timerp->pcntr;
|
||||
diff = -(now - lastinc);
|
||||
|
||||
timestamp += diff;
|
||||
lastinc = now;
|
||||
return timestamp - base;
|
||||
}
|
||||
|
||||
void wait_ticks(unsigned long ticks)
|
||||
{
|
||||
u32 start = get_timer(0);
|
||||
while (get_timer(start) < ticks) ;
|
||||
}
|
||||
#endif /* CONFIG_MCFPIT */
|
||||
|
||||
/*
|
||||
* This function is derived from PowerPC code (read timebase as long long).
|
||||
* On M68K it just returns the timer value.
|
||||
*/
|
||||
unsigned long long get_ticks(void)
|
||||
{
|
||||
return get_timer(0);
|
||||
}
|
||||
|
||||
unsigned long usec2ticks(unsigned long usec)
|
||||
{
|
||||
return get_timer(usec);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is derived from PowerPC code (timebase clock frequency).
|
||||
* On M68K it returns the number of timer ticks per second.
|
||||
*/
|
||||
ulong get_tbclk(void)
|
||||
{
|
||||
return CONFIG_SYS_HZ;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2003
|
||||
* Josef Baumgartner <josef.baumgartner@telex.de>
|
||||
*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <init.h>
|
||||
#include <watchdog.h>
|
||||
#include <command.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
|
||||
extern void _exc_handler(void);
|
||||
extern void _int_handler(void);
|
||||
|
||||
static void show_frame(struct pt_regs *fp)
|
||||
{
|
||||
printf ("Vector Number: %d Format: %02x Fault Status: %01x\n\n", (fp->vector & 0x3fc) >> 2,
|
||||
fp->format, (fp->vector & 0x3) | ((fp->vector & 0xc00) >> 8));
|
||||
printf ("PC: %08lx SR: %08lx SP: %08lx\n", fp->pc, (long) fp->sr, (long) fp);
|
||||
printf ("D0: %08lx D1: %08lx D2: %08lx D3: %08lx\n",
|
||||
fp->d0, fp->d1, fp->d2, fp->d3);
|
||||
printf ("D4: %08lx D5: %08lx D6: %08lx D7: %08lx\n",
|
||||
fp->d4, fp->d5, fp->d6, fp->d7);
|
||||
printf ("A0: %08lx A1: %08lx A2: %08lx A3: %08lx\n",
|
||||
fp->a0, fp->a1, fp->a2, fp->a3);
|
||||
printf ("A4: %08lx A5: %08lx A6: %08lx\n",
|
||||
fp->a4, fp->a5, fp->a6);
|
||||
}
|
||||
|
||||
void exc_handler(struct pt_regs *fp) {
|
||||
printf("\n\n*** Unexpected exception ***\n");
|
||||
show_frame (fp);
|
||||
printf("\n*** Please Reset Board! ***\n");
|
||||
for(;;);
|
||||
}
|
||||
|
||||
void trap_init(ulong value) {
|
||||
unsigned long *vec = (ulong *)value;
|
||||
int i;
|
||||
|
||||
for(i = 2; i < 25; i++) {
|
||||
vec[i] = (unsigned long)_exc_handler;
|
||||
}
|
||||
for(i = 25; i < 32; i++) {
|
||||
vec[i] = (unsigned long)_int_handler;
|
||||
}
|
||||
for(i = 32; i < 64; i++) {
|
||||
vec[i] = (unsigned long)_exc_handler;
|
||||
}
|
||||
for(i = 64; i < 256; i++) {
|
||||
vec[i] = (unsigned long)_int_handler;
|
||||
}
|
||||
|
||||
setvbr(value); /* set vector base register to new table */
|
||||
}
|
||||
Reference in New Issue
Block a user