SPARC: Added support for SPARC LEON2 SOC Processor.

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
This commit is contained in:
Daniel Hellstrom 2008-03-28 10:00:33 +01:00
parent 2a2fa797e6
commit b330990c2f
13 changed files with 2651 additions and 0 deletions

View File

@ -2902,6 +2902,10 @@ r2dplus_config : unconfig
## LEON3
#########################################################################
#########################################################################
## LEON2
#########################################################################
#########################################################################
#########################################################################
#########################################################################

1
README
View File

@ -153,6 +153,7 @@ Directory Hierarchy:
- at32ap Files specific to Atmel AVR32 AP CPUs
- i386 Files specific to i386 CPUs
- ixp Files specific to Intel XScale IXP CPUs
- leon2 Files specific to Gaisler LEON2 SPARC CPU
- leon3 Files specific to Gaisler LEON3 SPARC CPU
- mcf52x2 Files specific to Freescale ColdFire MCF52x2 CPUs
- mcf5227x Files specific to Freescale ColdFire MCF5227x CPUs

54
cpu/leon2/Makefile Normal file
View File

@ -0,0 +1,54 @@
#
# (C) Copyright 2003-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$(CPU).a
START = start.o
SOBJS =
COBJS = cpu_init.o serial.o cpu.o interrupts.o prom.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
START := $(addprefix $(obj),$(START))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
$(START): $(START:.o=.S)
$(CC) -D__ASSEMBLY__ $(DBGFLAGS) $(OPTFLAGS) -D__KERNEL__ -DTEXT_BASE=$(TEXT_BASE) \
-I$(TOPDIR)/include -fno-builtin -ffreestanding -nostdinc -isystem $(gccincdir) -pipe \
$(PLATFORM_CPPFLAGS) -Wall -Wstrict-prototypes \
-I$(TOPDIR)/board -c -o $(START) $(START:.o=.S)
sinclude $(obj).depend
#########################################################################

26
cpu/leon2/config.mk Normal file
View File

@ -0,0 +1,26 @@
#
# (C) Copyright 2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
PLATFORM_RELFLAGS += -fPIC
PLATFORM_CPPFLAGS += -DCONFIG_LEON

58
cpu/leon2/cpu.c Normal file
View File

@ -0,0 +1,58 @@
/* CPU specific code for the LEON2 CPU
*
* (C) Copyright 2007
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <watchdog.h>
#include <command.h>
DECLARE_GLOBAL_DATA_PTR;
extern void _reset_reloc(void);
int checkcpu(void)
{
/* check LEON version here */
printf("CPU: LEON2\n");
return 0;
}
/* ------------------------------------------------------------------------- */
void cpu_reset(void)
{
/* Interrupts off */
disable_interrupts();
/* jump to restart in flash */
_reset_reloc();
}
int do_reset(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
cpu_reset();
return 1;
}
/* ------------------------------------------------------------------------- */

142
cpu/leon2/cpu_init.c Normal file
View File

@ -0,0 +1,142 @@
/* Initializes CPU and basic hardware such as memory
* controllers, IRQ controller and system timer 0.
*
* (C) Copyright 2007
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#include <common.h>
#include <asm/asi.h>
#include <asm/leon.h>
#include <config.h>
DECLARE_GLOBAL_DATA_PTR;
/* reset CPU (jump to 0, without reset) */
void start(void);
struct {
gd_t gd_area;
bd_t bd;
} global_data;
/*
* Breath some life into the CPU...
*
* Set up the memory map,
* initialize a bunch of registers.
*
* Run from FLASH/PROM:
* - until memory controller is set up, only registers avaiable
* - no global variables available for writing
* - constants avaiable
*/
void cpu_init_f(void)
{
LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
/* initialize the IRQMP */
leon2->Interrupt_Force = 0;
leon2->Interrupt_Pending = 0;
leon2->Interrupt_Clear = 0xfffe; /* clear all old pending interrupts */
leon2->Interrupt_Mask = 0xfffe0000; /* mask all IRQs */
/* cache */
/* I/O port setup */
#ifdef LEON2_IO_PORT_DIR
leon2->PIO_Direction = LEON2_IO_PORT_DIR;
#endif
#ifdef LEON2_IO_PORT_DATA
leon2->PIO_Data = LEON2_IO_PORT_DATA;
#endif
#ifdef LEON2_IO_PORT_INT
leon2->PIO_Interrupt = LEON2_IO_PORT_INT;
#else
leon2->PIO_Interrupt = 0;
#endif
}
void cpu_init_f2(void)
{
}
/*
* initialize higher level parts of CPU like time base and timers
*/
int cpu_init_r(void)
{
LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
/* initialize prescaler common to all timers to 1MHz */
leon2->Scaler_Counter = leon2->Scaler_Reload =
(((CONFIG_SYS_CLK_FREQ / 1000) + 500) / 1000) - 1;
return (0);
}
/* Uses Timer 0 to get accurate
* pauses. Max 2 raised to 32 ticks
*
*/
void cpu_wait_ticks(unsigned long ticks)
{
unsigned long start = get_timer(0);
while (get_timer(start) < ticks) ;
}
/* initiate and setup timer0 interrupt to 1MHz
* Return irq number for timer int or a negative number for
* dealing with self
*/
int timer_interrupt_init_cpu(void)
{
LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
/* 1ms ticks */
leon2->Timer_Counter_1 = 0;
leon2->Timer_Reload_1 = 999; /* (((1000000 / 100) - 1)) */
leon2->Timer_Control_1 =
(LEON2_TIMER_CTRL_EN | LEON2_TIMER_CTRL_RS | LEON2_TIMER_CTRL_LD);
return LEON2_TIMER1_IRQNO;
}
/*
* This function is intended for SHORT delays only.
*/
unsigned long cpu_usec2ticks(unsigned long usec)
{
/* timer set to 1kHz ==> 1 clk tick = 1 msec */
if (usec < 1000)
return 1;
return (usec / 1000);
}
unsigned long cpu_ticks2usec(unsigned long ticks)
{
/* 1tick = 1usec */
return ticks * 1000;
}

217
cpu/leon2/interrupts.c Normal file
View File

@ -0,0 +1,217 @@
/*
* (C) Copyright 2007
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
*
* (C) Copyright 2006
* Detlev Zundel, DENX Software Engineering, dzu@denx.de
*
* (C) Copyright -2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2001
* Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
*
* 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 <asm/stack.h>
#include <common.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <command.h>
#include <asm/irq.h>
#include <asm/leon.h>
/* 15 normal irqs and a non maskable interrupt */
#define NR_IRQS 15
struct irq_action {
interrupt_handler_t *handler;
void *arg;
unsigned int count;
};
static struct irq_action irq_handlers[NR_IRQS] = { {0}, };
static int spurious_irq_cnt = 0;
static int spurious_irq = 0;
static inline unsigned int leon2_get_irqmask(unsigned int irq)
{
if ((irq < 0) || (irq >= NR_IRQS)) {
return 0;
} else {
return (1 << irq);
}
}
static void leon2_ic_disable(unsigned int irq)
{
unsigned int mask, pil;
LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
pil = intLock();
/* get mask of interrupt */
mask = leon2_get_irqmask(irq);
/* set int level */
leon2->Interrupt_Mask =
SPARC_NOCACHE_READ(&leon2->Interrupt_Mask) & (~mask);
intUnlock(pil);
}
static void leon2_ic_enable(unsigned int irq)
{
unsigned int mask, pil;
LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
pil = intLock();
/* get mask of interrupt */
mask = leon2_get_irqmask(irq);
/* set int level */
leon2->Interrupt_Mask =
SPARC_NOCACHE_READ(&leon2->Interrupt_Mask) | mask;
intUnlock(pil);
}
void handler_irq(int irq, struct pt_regs *regs)
{
if (irq_handlers[irq].handler) {
if (((unsigned int)irq_handlers[irq].handler > CFG_RAM_END) ||
((unsigned int)irq_handlers[irq].handler < CFG_RAM_BASE)
) {
printf("handler_irq: bad handler: %x, irq number %d\n",
(unsigned int)irq_handlers[irq].handler, irq);
return;
}
irq_handlers[irq].handler(irq_handlers[irq].arg);
irq_handlers[irq].count++;
} else {
spurious_irq_cnt++;
spurious_irq = irq;
}
}
void leon2_force_int(int irq)
{
LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
if ((irq >= NR_IRQS) || (irq < 0))
return;
printf("Forcing interrupt %d\n", irq);
leon2->Interrupt_Force =
SPARC_NOCACHE_READ(&leon2->Interrupt_Force) | (1 << irq);
}
/****************************************************************************/
int interrupt_init_cpu(void)
{
return (0);
}
/****************************************************************************/
/* Handle Timer 0 IRQ */
void timer_interrupt_cpu(void *arg)
{
LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
leon2->Timer_Control_1 =
(LEON2_TIMER_CTRL_EN | LEON2_TIMER_CTRL_RS | LEON2_TIMER_CTRL_LD);
/* nothing to do here */
return;
}
/****************************************************************************/
/*
* Install and free a interrupt handler.
*/
void irq_install_handler(int irq, interrupt_handler_t * handler, void *arg)
{
if (irq < 0 || irq >= NR_IRQS) {
printf("irq_install_handler: bad irq number %d\n", irq);
return;
}
if (irq_handlers[irq].handler != NULL)
printf("irq_install_handler: 0x%08lx replacing 0x%08lx\n",
(ulong) handler, (ulong) irq_handlers[irq].handler);
if (((unsigned int)handler > CFG_RAM_END) ||
((unsigned int)handler < CFG_RAM_BASE)
) {
printf("irq_install_handler: bad handler: %x, irq number %d\n",
(unsigned int)handler, irq);
return;
}
irq_handlers[irq].handler = handler;
irq_handlers[irq].arg = arg;
/* enable irq on LEON2 hardware */
leon2_ic_enable(irq);
}
void irq_free_handler(int irq)
{
if (irq < 0 || irq >= NR_IRQS) {
printf("irq_free_handler: bad irq number %d\n", irq);
return;
}
/* disable irq on LEON2 hardware */
leon2_ic_disable(irq);
irq_handlers[irq].handler = NULL;
irq_handlers[irq].arg = NULL;
}
/****************************************************************************/
#if defined(CONFIG_CMD_IRQ)
void do_irqinfo(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
{
int irq;
unsigned int pil = get_pil();
printf("PIL level: %u\n\r", pil);
printf("Spurious IRQ: %u, last unknown IRQ: %d\n",
spurious_irq_cnt, spurious_irq);
puts("\nInterrupt-Information:\n" "Nr Routine Arg Count\n");
for (irq = 0; irq < NR_IRQS; irq++) {
if (irq_handlers[irq].handler != NULL) {
printf("%02d %08lx %08lx %ld\n", irq,
(unsigned int)irq_handlers[irq].handler,
(unsigned int)irq_handlers[irq].arg,
irq_handlers[irq].count);
}
}
}
#endif

1047
cpu/leon2/prom.c Normal file

File diff suppressed because it is too large Load Diff

165
cpu/leon2/serial.c Normal file
View File

@ -0,0 +1,165 @@
/* GRLIB APBUART Serial controller driver
*
* (C) Copyright 2008
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#include <common.h>
#include <asm/processor.h>
#include <asm/leon.h>
DECLARE_GLOBAL_DATA_PTR;
/* Force cache miss each time a serial controller reg is read */
#define CACHE_BYPASS 1
#ifdef CACHE_BYPASS
#define READ_BYTE(var) SPARC_NOCACHE_READ_BYTE((unsigned int)&(var))
#define READ_HWORD(var) SPARC_NOCACHE_READ_HWORD((unsigned int)&(var))
#define READ_WORD(var) SPARC_NOCACHE_READ((unsigned int)&(var))
#define READ_DWORD(var) SPARC_NOCACHE_READ_DWORD((unsigned int)&(var))
#endif
int serial_init(void)
{
LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
LEON2_Uart_regs *regs;
unsigned int tmp;
/* Init LEON2 UART
*
* Set scaler / baud rate
*
* Receiver & transmitter enable
*/
#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
#else
regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
#endif
regs->UART_Scaler = CFG_LEON2_UART1_SCALER;
/* Let bit 11 be unchanged (debug bit for GRMON) */
tmp = READ_WORD(regs->UART_Control);
regs->UART_Control = ((tmp & LEON2_UART_CTRL_DBG) |
(LEON2_UART1_LOOPBACK_ENABLE << 7) |
(LEON2_UART1_FLOWCTRL_ENABLE << 6) |
(LEON2_UART1_PARITY_ENABLE << 5) |
(LEON2_UART1_ODDPAR_ENABLE << 4) |
LEON2_UART_CTRL_RE | LEON2_UART_CTRL_TE);
return 0;
}
void serial_putc(const char c)
{
if (c == '\n')
serial_putc_raw('\r');
serial_putc_raw(c);
}
void serial_putc_raw(const char c)
{
LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
LEON2_Uart_regs *regs;
#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
#else
regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
#endif
/* Wait for last character to go. */
while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_THE)) ;
/* Send data */
regs->UART_Channel = c;
#ifdef LEON_DEBUG
/* Wait for data to be sent */
while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_TSE)) ;
#endif
}
void serial_puts(const char *s)
{
while (*s) {
serial_putc(*s++);
}
}
int serial_getc(void)
{
LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
LEON2_Uart_regs *regs;
#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
#else
regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
#endif
/* Wait for a character to arrive. */
while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_DR)) ;
/* read data */
return READ_WORD(regs->UART_Channel);
}
int serial_tstc(void)
{
LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
LEON2_Uart_regs *regs;
#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
#else
regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
#endif
return (READ_WORD(regs->UART_Status) & LEON2_UART_STAT_DR);
}
/* set baud rate for uart */
void serial_setbrg(void)
{
/* update baud rate settings, read it from gd->baudrate */
unsigned int scaler;
LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
LEON2_Uart_regs *regs;
#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
#else
regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
#endif
if (gd->baudrate > 0) {
scaler =
(((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) -
5) / 10;
regs->UART_Scaler = scaler;
}
}

661
cpu/leon2/start.S Normal file
View File

@ -0,0 +1,661 @@
/* This is where the SPARC/LEON3 starts
* Copyright (C) 2007,
* Daniel Hellstrom, daniel@gaisler.com
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <config.h>
#include <asm/asmmacro.h>
#include <asm/winmacro.h>
#include <asm/psr.h>
#include <asm/stack.h>
#include <asm/leon.h>
#include <version.h>
/* Entry for traps which jump to a programmer-specified trap handler. */
#define TRAPR(H) \
wr %g0, 0xfe0, %psr; \
mov %g0, %tbr; \
ba (H); \
mov %g0, %wim;
#define TRAP(H) \
mov %psr, %l0; \
ba (H); \
nop; nop;
#define TRAPI(ilevel) \
mov ilevel, %l7; \
mov %psr, %l0; \
b _irq_entry; \
mov %wim, %l3
/* Unexcpected trap will halt the processor by forcing it to error state */
#undef BAD_TRAP
#define BAD_TRAP ta 0; nop; nop; nop;
/* Software trap. Treat as BAD_TRAP for the time being... */
#define SOFT_TRAP TRAP(_hwerr)
#define PSR_INIT 0x1FC0 /* Disable traps, set s and ps */
#define WIM_INIT 2
/* All traps low-level code here must end with this macro. */
#define RESTORE_ALL b ret_trap_entry; clr %l6;
#define WRITE_PAUSE nop;nop;nop
WINDOWSIZE = (16 * 4)
ARGPUSHSIZE = (6 * 4)
ARGPUSH = (WINDOWSIZE + 4)
MINFRAME = (WINDOWSIZE + ARGPUSHSIZE + 4)
/* Number of register windows */
#ifndef CFG_SPARC_NWINDOWS
#error Must define number of SPARC register windows, default is 8
#endif
#define STACK_ALIGN 8
#define SA(X) (((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1))
.section ".start", "ax"
.globl _start, start, _trap_table
.globl _irq_entry, nmi_trap
.globl _reset_reloc
/* at address 0
* Hardware traps
*/
start:
_start:
_trap_table:
TRAPR(_hardreset); ! 00 reset trap
BAD_TRAP; ! 01 instruction_access_exception
BAD_TRAP; ! 02 illegal_instruction
BAD_TRAP; ! 03 priveleged_instruction
BAD_TRAP; ! 04 fp_disabled
TRAP(_window_overflow); ! 05 window_overflow
TRAP(_window_underflow); ! 06 window_underflow
BAD_TRAP; ! 07 Memory Address Not Aligned
BAD_TRAP; ! 08 Floating Point Exception
BAD_TRAP; ! 09 Data Miss Exception
BAD_TRAP; ! 0a Tagged Instruction Ovrflw
BAD_TRAP; ! 0b Watchpoint Detected
BAD_TRAP; ! 0c
BAD_TRAP; ! 0d
BAD_TRAP; ! 0e
BAD_TRAP; ! 0f
BAD_TRAP; ! 10
TRAPI(1); ! 11 IRQ level 1
TRAPI(2); ! 12 IRQ level 2
TRAPI(3); ! 13 IRQ level 3
TRAPI(4); ! 14 IRQ level 4
TRAPI(5); ! 15 IRQ level 5
TRAPI(6); ! 16 IRQ level 6
TRAPI(7); ! 17 IRQ level 7
TRAPI(8); ! 18 IRQ level 8
TRAPI(9); ! 19 IRQ level 9
TRAPI(10); ! 1a IRQ level 10
TRAPI(11); ! 1b IRQ level 11
TRAPI(12); ! 1c IRQ level 12
TRAPI(13); ! 1d IRQ level 13
TRAPI(14); ! 1e IRQ level 14
TRAP(_nmi_trap); ! 1f IRQ level 15 /
! NMI (non maskable interrupt)
BAD_TRAP; ! 20 r_register_access_error
BAD_TRAP; ! 21 instruction access error
BAD_TRAP; ! 22
BAD_TRAP; ! 23
BAD_TRAP; ! 24 co-processor disabled
BAD_TRAP; ! 25 uniplemented FLUSH
BAD_TRAP; ! 26
BAD_TRAP; ! 27
BAD_TRAP; ! 28 co-processor exception
BAD_TRAP; ! 29 data access error
BAD_TRAP; ! 2a division by zero
BAD_TRAP; ! 2b data store error
BAD_TRAP; ! 2c data access MMU miss
BAD_TRAP; ! 2d
BAD_TRAP; ! 2e
BAD_TRAP; ! 2f
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 30-33
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 34-37
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 38-3b
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 3c-3f
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 40-43
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 44-47
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 48-4b
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 4c-4f
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 50-53
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 54-57
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 58-5b
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 5c-5f
/* implementaion dependent */
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 60-63
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 64-67
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 68-6b
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 6c-6f
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 70-73
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 74-77
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 78-7b
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 7c-7f
/* Software traps, not handled */
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 80-83
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 84-87
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 88-8b
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 8c-8f
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 90-93
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 94-97
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 98-9b
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 9c-9f
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! a0-a3
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! a4-a7
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! a8-ab
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! ac-af
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! b0-b3
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! b4-b7
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! b8-bb
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! bc-bf
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! c0-c3
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! c4-c7
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! c8-cb
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! cc-cf
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! d0-d3
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! d4-d7
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! d8-db
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! dc-df
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! e0-e3
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! e4-e7
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! e8-eb
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! ec-ef
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! f0-f3
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! f4-f7
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! f8-fb
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! fc-ff
/*
* Version string
*/
.data
.globl version_string
version_string:
.ascii U_BOOT_VERSION
.ascii " (", __DATE__, " - ", __TIME__, ")"
.ascii CONFIG_IDENT_STRING, "\0"
.section ".text"
.align 4
_hardreset:
1000:
flush
nop
nop
nop
/* Init Cache */
set (LEON2_PREGS+LEON_REG_CACHECTRL_OFFSET), %g1
set 0x0081000f, %g2
st %g2, [%g1]
mov %g0, %y
clr %g1
clr %g2
clr %g3
clr %g4
clr %g5
clr %g6
clr %g7
mov %asr17, %g3
and %g3, 0x1f, %g3
clear_window:
mov %g0, %l0
mov %g0, %l1
mov %g0, %l2
mov %g0, %l3
mov %g0, %l4
mov %g0, %l5
mov %g0, %l6
mov %g0, %l7
mov %g0, %o0
mov %g0, %o1
mov %g0, %o2
mov %g0, %o3
mov %g0, %o4
mov %g0, %o5
mov %g0, %o6
mov %g0, %o7
subcc %g3, 1, %g3
bge clear_window
save
leon2_init:
/* LEON2 Register Base in g1 */
set LEON2_PREGS, %g1
leon2_init_cache:
/* Set Cache control register */
set 0x1000f, %g2
st %g2, [%g1 + 0x14]
leon2_init_clear:
/* Clear LEON2 registers */
st %g0, [%g1 + LEON2_ECTRL]
st %g0, [%g1 + LEON2_IMASK]
st %g0, [%g1 + LEON2_IPEND]
st %g0, [%g1 + LEON2_IFORCE]
st %g0, [%g1 + LEON2_ICLEAR]
st %g0, [%g1 + LEON2_IOREG]
st %g0, [%g1 + LEON2_IODIR]
st %g0, [%g1 + LEON2_IOICONF]
st %g0, [%g1 + LEON2_UCTRL0]
st %g0, [%g1 + LEON2_UCTRL1]
leon2_init_ioport:
/* I/O port initialization */
set 0xaa00, %g2
st %g2, [%g1 + LEON2_IOREG]
leon2_init_mctrl:
/* memory config register 1 */
set CFG_GRLIB_MEMCFG1, %g2
ld [%g1], %g3 !
and %g3, 0x300, %g3
or %g2, %g3, %g2
st %g2, [%g1 + LEON2_MCFG1]
set CFG_GRLIB_MEMCFG2, %g2 ! Load memory config register 2
#if !( defined(TSIM) || !defined(BZIMAGE))
st %g2, [%g1 + LEON2_MCFG2] ! only for prom version, else done by "dumon -i"
#endif
set CFG_GRLIB_MEMCFG3, %g2 ! Init FT register
st %g2, [%g1 + LEON2_ECTRL]
ld [%g1 + LEON2_ECTRL], %g2
srl %g2, 30, %g2
andcc %g2, 3, %g6
bne,a leon2_init_wim
mov %g0, %asr16 ! clear err_reg
leon2_init_wim:
set WIM_INIT, %g3
mov %g3, %wim
leon2_init_psr:
set 0x1000, %g3
mov %psr, %g2
wr %g2, %g3, %psr
nop
nop
nop
leon2_init_stackp:
set CFG_INIT_SP_OFFSET, %fp
andn %fp, 0x0f, %fp
sub %fp, 64, %sp
cpu_init_unreloc:
call cpu_init_f
nop
/* un relocated start address of monitor */
#define TEXT_START _text
/* un relocated end address of monitor */
#define DATA_END __init_end
reloc:
set TEXT_START,%g2
set DATA_END,%g3
set CFG_RELOC_MONITOR_BASE,%g4
reloc_loop:
ldd [%g2],%l0
ldd [%g2+8],%l2
std %l0,[%g4]
std %l2,[%g4+8]
inc 16,%g2
subcc %g3,%g2,%g0
bne reloc_loop
inc 16,%g4
clr %l0
clr %l1
clr %l2
clr %l3
clr %g2
/* register g4 contain address to start
* This means that BSS must be directly after data and code segments
*
* g3 is length of bss = (__bss_end-__bss_start)
*
*/
clr_bss:
/* clear bss area (the relocated) */
set __bss_start,%g2
set __bss_end,%g3
sub %g3,%g2,%g3
add %g3,%g4,%g3
clr %g1 /* std %g0 uses g0 and g1 */
/* clearing 16byte a time ==> linker script need to align to 16 byte offset */
clr_bss_16:
std %g0,[%g4]
std %g0,[%g4+8]
inc 16,%g4
cmp %g3,%g4
bne clr_bss_16
nop
/* add offsets to GOT table */
fixup_got:
set __got_start,%g4
set __got_end,%g3
/*
* new got offset = (old GOT-PTR (read with ld) -
* CFG_RELOC_MONITOR_BASE(from define) ) +
* Destination Address (from define)
*/
set CFG_RELOC_MONITOR_BASE,%g2
set TEXT_START, %g1
add %g4,%g2,%g4
sub %g4,%g1,%g4
add %g3,%g2,%g3
sub %g3,%g1,%g3
sub %g2,%g1,%g2 ! prepare register with (new base address) -
! (old base address)
got_loop:
ld [%g4],%l0 ! load old GOT-PTR
add %l0,%g2,%l0 ! increase with (new base address) -
! (old base)
st %l0,[%g4]
inc 4,%g4
cmp %g3,%g4
bne got_loop
nop
prom_relocate:
set __prom_start, %g2
set __prom_end, %g3
set CFG_PROM_OFFSET, %g4
prom_relocate_loop:
ldd [%g2],%l0
ldd [%g2+8],%l2
std %l0,[%g4]
std %l2,[%g4+8]
inc 16,%g2
subcc %g3,%g2,%g0
bne prom_relocate_loop
inc 16,%g4
/* Trap table has been moved, lets tell CPU about
* the new trap table address
*/
set CFG_RELOC_MONITOR_BASE, %g2
wr %g0, %g2, %tbr
/* call relocate*/
nop
/* Call relocated init functions */
jump:
set cpu_init_f2,%o1
set CFG_RELOC_MONITOR_BASE,%o2
add %o1,%o2,%o1
sub %o1,%g1,%o1
call %o1
clr %o0
set board_init_f,%o1
set CFG_RELOC_MONITOR_BASE,%o2
add %o1,%o2,%o1
sub %o1,%g1,%o1
call %o1
clr %o0
dead: ta 0 ! if call returns...
nop
/* Interrupt handler caller,
* reg L7: interrupt number
* reg L0: psr after interrupt
* reg L1: PC
* reg L2: next PC
* reg L3: wim
*/
_irq_entry:
SAVE_ALL
or %l0, PSR_PIL, %g2
wr %g2, 0x0, %psr
WRITE_PAUSE
wr %g2, PSR_ET, %psr
WRITE_PAUSE
mov %l7, %o0 ! irq level
set handler_irq, %o1
set (CFG_RELOC_MONITOR_BASE-TEXT_BASE), %o2
add %o1, %o2, %o1
call %o1
add %sp, SF_REGS_SZ, %o1 ! pt_regs ptr
or %l0, PSR_PIL, %g2 ! restore PIL after handler_irq
wr %g2, PSR_ET, %psr ! keep ET up
WRITE_PAUSE
RESTORE_ALL
!Window overflow trap handler.
.global _window_overflow
_window_overflow:
mov %wim, %l3 ! Calculate next WIM
mov %g1, %l7
srl %l3, 1, %g1
sll %l3, (CFG_SPARC_NWINDOWS-1) , %l4
or %l4, %g1, %g1
save ! Get into window to be saved.
mov %g1, %wim
nop;
nop;
nop
st %l0, [%sp + 0];
st %l1, [%sp + 4];
st %l2, [%sp + 8];
st %l3, [%sp + 12];
st %l4, [%sp + 16];
st %l5, [%sp + 20];
st %l6, [%sp + 24];
st %l7, [%sp + 28];
st %i0, [%sp + 32];
st %i1, [%sp + 36];
st %i2, [%sp + 40];
st %i3, [%sp + 44];
st %i4, [%sp + 48];
st %i5, [%sp + 52];
st %i6, [%sp + 56];
st %i7, [%sp + 60];
restore ! Go back to trap window.
mov %l7, %g1
jmp %l1 ! Re-execute save.
rett %l2
/* Window underflow trap handler. */
.global _window_underflow
_window_underflow:
mov %wim, %l3 ! Calculate next WIM
sll %l3, 1, %l4
srl %l3, (CFG_SPARC_NWINDOWS-1), %l5
or %l5, %l4, %l5
mov %l5, %wim
nop; nop; nop
restore ! Two restores to get into the
restore ! window to restore
ld [%sp + 0], %l0; ! Restore window from the stack
ld [%sp + 4], %l1;
ld [%sp + 8], %l2;
ld [%sp + 12], %l3;
ld [%sp + 16], %l4;
ld [%sp + 20], %l5;
ld [%sp + 24], %l6;
ld [%sp + 28], %l7;
ld [%sp + 32], %i0;
ld [%sp + 36], %i1;
ld [%sp + 40], %i2;
ld [%sp + 44], %i3;
ld [%sp + 48], %i4;
ld [%sp + 52], %i5;
ld [%sp + 56], %i6;
ld [%sp + 60], %i7;
save ! Get back to the trap window.
save
jmp %l1 ! Re-execute restore.
rett %l2
retl
_nmi_trap:
nop
jmp %l1
rett %l2
_hwerr:
ta 0
nop
nop
b _hwerr ! loop infinite
nop
/* Registers to not touch at all. */
#define t_psr l0 /* Set by caller */
#define t_pc l1 /* Set by caller */
#define t_npc l2 /* Set by caller */
#define t_wim l3 /* Set by caller */
#define t_twinmask l4 /* Set at beginning of this entry routine. */
#define t_kstack l5 /* Set right before pt_regs frame is built */
#define t_retpc l6 /* If you change this, change winmacro.h header file */
#define t_systable l7 /* Never touch this, could be the syscall table ptr. */
#define curptr g6 /* Set after pt_regs frame is built */
trap_setup:
/* build a pt_regs trap frame. */
sub %fp, (SF_REGS_SZ + PT_REGS_SZ), %t_kstack
PT_STORE_ALL(t_kstack, t_psr, t_pc, t_npc, g2)
/* See if we are in the trap window. */
mov 1, %t_twinmask
sll %t_twinmask, %t_psr, %t_twinmask ! t_twinmask = (1 << psr)
andcc %t_twinmask, %t_wim, %g0
beq 1f ! in trap window, clean up
nop
/*-------------------------------------------------
* Spill , adjust %wim and go.
*/
srl %t_wim, 0x1, %g2 ! begin computation of new %wim
set (CFG_SPARC_NWINDOWS-1), %g3 !NWINDOWS-1
sll %t_wim, %g3, %t_wim ! NWINDOWS-1
or %t_wim, %g2, %g2
and %g2, 0xff, %g2
save %g0, %g0, %g0 ! get in window to be saved
/* Set new %wim value */
wr %g2, 0x0, %wim
/* Save the kernel window onto the corresponding stack. */
RW_STORE(sp)
restore %g0, %g0, %g0
/*-------------------------------------------------*/
1:
/* Trap from kernel with a window available.
* Just do it...
*/
jmpl %t_retpc + 0x8, %g0 ! return to caller
mov %t_kstack, %sp ! jump onto new stack
#define twin_tmp1 l4
#define glob_tmp g4
#define curptr g6
ret_trap_entry:
wr %t_psr, 0x0, %psr ! enable nesting again, clear ET
/* Will the rett land us in the invalid window? */
mov 2, %g1
sll %g1, %t_psr, %g1
set CFG_SPARC_NWINDOWS, %g2 !NWINDOWS
srl %g1, %g2, %g2
or %g1, %g2, %g1
rd %wim, %g2
andcc %g2, %g1, %g0
be 1f ! Nope, just return from the trap
sll %g2, 0x1, %g1
/* We have to grab a window before returning. */
set (CFG_SPARC_NWINDOWS-1), %g3 !NWINDOWS-1
srl %g2, %g3, %g2
or %g1, %g2, %g1
and %g1, 0xff, %g1
wr %g1, 0x0, %wim
/* Grrr, make sure we load from the right %sp... */
PT_LOAD_ALL(sp, t_psr, t_pc, t_npc, g1)
restore %g0, %g0, %g0
RW_LOAD(sp)
b 2f
save %g0, %g0, %g0
/* Reload the entire frame in case this is from a
* kernel system call or whatever...
*/
1:
PT_LOAD_ALL(sp, t_psr, t_pc, t_npc, g1)
2:
wr %t_psr, 0x0, %psr
nop;
nop;
nop
jmp %t_pc
rett %t_npc
/* This is called from relocated C-code.
* It resets the system by jumping to _start
*/
_reset_reloc:
set start, %l0
call %l0
nop

View File

@ -0,0 +1,36 @@
/* asi.h: Address Space Identifier values for the LEON2 sparc.
*
* Copyright (C) 2008 Daniel Hellstrom (daniel@gaisler.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
*
*/
#ifndef _LEON2_ASI_H
#define _LEON2_ASI_H
#define ASI_CACHEMISS 0x01 /* Force D-Cache miss on load (lda) */
#define ASI_M_FLUSH_PROBE 0x03 /* MMU Flush/Probe */
#define ASI_IFLUSH 0x05 /* Flush I-Cache */
#define ASI_DFLUSH 0x06 /* Flush D-Cache */
#define ASI_BYPASS 0x1c /* Bypass MMU (Physical address) */
#define ASI_MMUFLUSH 0x18 /* FLUSH TLB */
#define ASI_M_MMUREGS 0x19 /* READ/Write MMU Registers */
#endif /* _LEON2_ASI_H */

View File

@ -27,6 +27,10 @@
#include <asm/leon3.h>
#elif defined(CONFIG_LEON2)
#include <asm/leon2.h>
#else
#error Unknown LEON processor

236
include/asm-sparc/leon2.h Normal file
View File

@ -0,0 +1,236 @@
/* LEON2 header file. LEON2 is a SOC processor.
*
* (C) Copyright 2008
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#ifndef __LEON2_H__
#define __LEON2_H__
#ifdef CONFIG_LEON2
/* LEON 2 I/O register definitions */
#define LEON2_PREGS 0x80000000
#define LEON2_MCFG1 0x00
#define LEON2_MCFG2 0x04
#define LEON2_ECTRL 0x08
#define LEON2_FADDR 0x0C
#define LEON2_MSTAT 0x10
#define LEON2_CCTRL 0x14
#define LEON2_PWDOWN 0x18
#define LEON2_WPROT1 0x1C
#define LEON2_WPROT2 0x20
#define LEON2_LCONF 0x24
#define LEON2_TCNT0 0x40
#define LEON2_TRLD0 0x44
#define LEON2_TCTRL0 0x48
#define LEON2_TCNT1 0x50
#define LEON2_TRLD1 0x54
#define LEON2_TCTRL1 0x58
#define LEON2_SCNT 0x60
#define LEON2_SRLD 0x64
#define LEON2_UART0 0x70
#define LEON2_UDATA0 0x70
#define LEON2_USTAT0 0x74
#define LEON2_UCTRL0 0x78
#define LEON2_USCAL0 0x7C
#define LEON2_UART1 0x80
#define LEON2_UDATA1 0x80
#define LEON2_USTAT1 0x84
#define LEON2_UCTRL1 0x88
#define LEON2_USCAL1 0x8C
#define LEON2_IMASK 0x90
#define LEON2_IPEND 0x94
#define LEON2_IFORCE 0x98
#define LEON2_ICLEAR 0x9C
#define LEON2_IOREG 0xA0
#define LEON2_IODIR 0xA4
#define LEON2_IOICONF 0xA8
#define LEON2_IPEND2 0xB0
#define LEON2_IMASK2 0xB4
#define LEON2_ISTAT2 0xB8
#define LEON2_ICLEAR2 0xBC
#ifndef __ASSEMBLER__
/*
* Structure for LEON memory mapped registers.
*
* Source: Section 6.1 - On-chip registers
*
* NOTE: There is only one of these structures per CPU, its base address
* is 0x80000000, and the variable LEON_REG is placed there by the
* linkcmds file.
*/
typedef struct {
volatile unsigned int Memory_Config_1;
volatile unsigned int Memory_Config_2;
volatile unsigned int Edac_Control;
volatile unsigned int Failed_Address;
volatile unsigned int Memory_Status;
volatile unsigned int Cache_Control;
volatile unsigned int Power_Down;
volatile unsigned int Write_Protection_1;
volatile unsigned int Write_Protection_2;
volatile unsigned int Leon_Configuration;
volatile unsigned int dummy2;
volatile unsigned int dummy3;
volatile unsigned int dummy4;
volatile unsigned int dummy5;
volatile unsigned int dummy6;
volatile unsigned int dummy7;
volatile unsigned int Timer_Counter_1;
volatile unsigned int Timer_Reload_1;
volatile unsigned int Timer_Control_1;
volatile unsigned int Watchdog;
volatile unsigned int Timer_Counter_2;
volatile unsigned int Timer_Reload_2;
volatile unsigned int Timer_Control_2;
volatile unsigned int dummy8;
volatile unsigned int Scaler_Counter;
volatile unsigned int Scaler_Reload;
volatile unsigned int dummy9;
volatile unsigned int dummy10;
volatile unsigned int UART_Channel_1;
volatile unsigned int UART_Status_1;
volatile unsigned int UART_Control_1;
volatile unsigned int UART_Scaler_1;
volatile unsigned int UART_Channel_2;
volatile unsigned int UART_Status_2;
volatile unsigned int UART_Control_2;
volatile unsigned int UART_Scaler_2;
volatile unsigned int Interrupt_Mask;
volatile unsigned int Interrupt_Pending;
volatile unsigned int Interrupt_Force;
volatile unsigned int Interrupt_Clear;
volatile unsigned int PIO_Data;
volatile unsigned int PIO_Direction;
volatile unsigned int PIO_Interrupt;
} LEON2_regs;
typedef struct {
volatile unsigned int UART_Channel;
volatile unsigned int UART_Status;
volatile unsigned int UART_Control;
volatile unsigned int UART_Scaler;
} LEON2_Uart_regs;
#endif
/*
* The following constants are intended to be used ONLY in assembly
* language files.
*
* NOTE: The intended style of usage is to load the address of LEON REGS
* into a register and then use these as displacements from
* that register.
*/
#define LEON_REG_MEMCFG1_OFFSET 0x00
#define LEON_REG_MEMCFG2_OFFSET 0x04
#define LEON_REG_EDACCTRL_OFFSET 0x08
#define LEON_REG_FAILADDR_OFFSET 0x0C
#define LEON_REG_MEMSTATUS_OFFSET 0x10
#define LEON_REG_CACHECTRL_OFFSET 0x14
#define LEON_REG_POWERDOWN_OFFSET 0x18
#define LEON_REG_WRITEPROT1_OFFSET 0x1C
#define LEON_REG_WRITEPROT2_OFFSET 0x20
#define LEON_REG_LEONCONF_OFFSET 0x24
#define LEON_REG_UNIMPLEMENTED_2_OFFSET 0x28
#define LEON_REG_UNIMPLEMENTED_3_OFFSET 0x2C
#define LEON_REG_UNIMPLEMENTED_4_OFFSET 0x30
#define LEON_REG_UNIMPLEMENTED_5_OFFSET 0x34
#define LEON_REG_UNIMPLEMENTED_6_OFFSET 0x38
#define LEON_REG_UNIMPLEMENTED_7_OFFSET 0x3C
#define LEON_REG_TIMERCNT1_OFFSET 0x40
#define LEON_REG_TIMERLOAD1_OFFSET 0x44
#define LEON_REG_TIMERCTRL1_OFFSET 0x48
#define LEON_REG_WDOG_OFFSET 0x4C
#define LEON_REG_TIMERCNT2_OFFSET 0x50
#define LEON_REG_TIMERLOAD2_OFFSET 0x54
#define LEON_REG_TIMERCTRL2_OFFSET 0x58
#define LEON_REG_UNIMPLEMENTED_8_OFFSET 0x5C
#define LEON_REG_SCALERCNT_OFFSET 0x60
#define LEON_REG_SCALER_LOAD_OFFSET 0x64
#define LEON_REG_UNIMPLEMENTED_9_OFFSET 0x68
#define LEON_REG_UNIMPLEMENTED_10_OFFSET 0x6C
#define LEON_REG_UARTDATA1_OFFSET 0x70
#define LEON_REG_UARTSTATUS1_OFFSET 0x74
#define LEON_REG_UARTCTRL1_OFFSET 0x78
#define LEON_REG_UARTSCALER1_OFFSET 0x7C
#define LEON_REG_UARTDATA2_OFFSET 0x80
#define LEON_REG_UARTSTATUS2_OFFSET 0x84
#define LEON_REG_UARTCTRL2_OFFSET 0x88
#define LEON_REG_UARTSCALER2_OFFSET 0x8C
#define LEON_REG_IRQMASK_OFFSET 0x90
#define LEON_REG_IRQPEND_OFFSET 0x94
#define LEON_REG_IRQFORCE_OFFSET 0x98
#define LEON_REG_IRQCLEAR_OFFSET 0x9C
#define LEON_REG_PIODATA_OFFSET 0xA0
#define LEON_REG_PIODIR_OFFSET 0xA4
#define LEON_REG_PIOIRQ_OFFSET 0xA8
#define LEON_REG_SIM_RAM_SIZE_OFFSET 0xF4
#define LEON_REG_SIM_ROM_SIZE_OFFSET 0xF8
/*
* Interrupt Sources
*
* The interrupt source numbers directly map to the trap type and to
* the bits used in the Interrupt Clear, Interrupt Force, Interrupt Mask,
* and the Interrupt Pending Registers.
*/
#define LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR 1
#define LEON_INTERRUPT_UART_1_RX_TX 2
#define LEON_INTERRUPT_UART_0_RX_TX 3
#define LEON_INTERRUPT_EXTERNAL_0 4
#define LEON_INTERRUPT_EXTERNAL_1 5
#define LEON_INTERRUPT_EXTERNAL_2 6
#define LEON_INTERRUPT_EXTERNAL_3 7
#define LEON_INTERRUPT_TIMER1 8
#define LEON_INTERRUPT_TIMER2 9
#define LEON_INTERRUPT_EMPTY1 10
#define LEON_INTERRUPT_EMPTY2 11
#define LEON_INTERRUPT_OPEN_ETH 12
#define LEON_INTERRUPT_EMPTY4 13
#define LEON_INTERRUPT_EMPTY5 14
#define LEON_INTERRUPT_EMPTY6 15
/* Timer Bits */
#define LEON2_TIMER_CTRL_EN 0x1 /* Timer enable */
#define LEON2_TIMER_CTRL_RS 0x2 /* Timer reStart */
#define LEON2_TIMER_CTRL_LD 0x4 /* Timer reLoad */
#define LEON2_TIMER1_IRQNO 8 /* Timer 1 IRQ number */
#define LEON2_TIMER2_IRQNO 9 /* Timer 2 IRQ number */
#define LEON2_TIMER1_IE (1<<LEON2_TIMER1_IRQNO) /* Timer 1 interrupt enable */
#define LEON2_TIMER2_IE (1<<LEON2_TIMER2_IRQNO) /* Timer 2 interrupt enable */
/* UART bits */
#define LEON2_UART_CTRL_RE 1 /* UART Receiver enable */
#define LEON2_UART_CTRL_TE 2 /* UART Transmitter enable */
#define LEON2_UART_CTRL_RI 4 /* UART Receiver Interrupt enable */
#define LEON2_UART_CTRL_TI 8 /* UART Transmitter Interrupt enable */
#define LEON2_UART_CTRL_DBG (1<<11) /* Debug Bit used by GRMON */
#define LEON2_UART_STAT_DR 1 /* UART Data Ready */
#define LEON2_UART_STAT_TSE 2 /* UART Transmit Shift Reg empty */
#define LEON2_UART_STAT_THE 4 /* UART Transmit Hold Reg empty */
#else
#error Include LEON2 header file only if LEON2 processor
#endif
#endif