diff options
Diffstat (limited to 'cpu/leon2')
-rw-r--r-- | cpu/leon2/Makefile | 54 | ||||
-rw-r--r-- | cpu/leon2/config.mk | 26 | ||||
-rw-r--r-- | cpu/leon2/cpu.c | 66 | ||||
-rw-r--r-- | cpu/leon2/cpu_init.c | 142 | ||||
-rw-r--r-- | cpu/leon2/interrupts.c | 217 | ||||
-rw-r--r-- | cpu/leon2/prom.c | 1047 | ||||
-rw-r--r-- | cpu/leon2/serial.c | 165 | ||||
-rw-r--r-- | cpu/leon2/start.S | 662 |
8 files changed, 0 insertions, 2379 deletions
diff --git a/cpu/leon2/Makefile b/cpu/leon2/Makefile deleted file mode 100644 index 7cc4420179..0000000000 --- a/cpu/leon2/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -# -# (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 - -######################################################################### diff --git a/cpu/leon2/config.mk b/cpu/leon2/config.mk deleted file mode 100644 index 30b224a068..0000000000 --- a/cpu/leon2/config.mk +++ /dev/null @@ -1,26 +0,0 @@ -# -# (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 diff --git a/cpu/leon2/cpu.c b/cpu/leon2/cpu.c deleted file mode 100644 index d6e23b129c..0000000000 --- a/cpu/leon2/cpu.c +++ /dev/null @@ -1,66 +0,0 @@ -/* 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> -#include <netdev.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; -} - -/* ------------------------------------------------------------------------- */ - -#ifdef CONFIG_GRETH -int cpu_eth_init(bd_t *bis) -{ - return greth_initialize(bis); -} -#endif diff --git a/cpu/leon2/cpu_init.c b/cpu/leon2/cpu_init.c deleted file mode 100644 index a24f778c6d..0000000000 --- a/cpu/leon2/cpu_init.c +++ /dev/null @@ -1,142 +0,0 @@ -/* 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; -} diff --git a/cpu/leon2/interrupts.c b/cpu/leon2/interrupts.c deleted file mode 100644 index 9b0da963af..0000000000 --- a/cpu/leon2/interrupts.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * (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 > CONFIG_SYS_RAM_END) || - ((unsigned int)irq_handlers[irq].handler < CONFIG_SYS_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 > CONFIG_SYS_RAM_END) || - ((unsigned int)handler < CONFIG_SYS_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 diff --git a/cpu/leon2/prom.c b/cpu/leon2/prom.c deleted file mode 100644 index 1a6c7f79cd..0000000000 --- a/cpu/leon2/prom.c +++ /dev/null @@ -1,1047 +0,0 @@ -/* prom.c - emulates a sparc v0 PROM for the linux kernel. - * - * Copyright (C) 2003 Konrad Eisele <eiselekd@web.de> - * Copyright (C) 2004 Stefan Holst <mail@s-holst.de> - * 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 <common.h> -#include <asm/prom.h> -#include <asm/machines.h> -#include <asm/srmmu.h> -#include <asm/processor.h> -#include <asm/irq.h> -#include <asm/leon.h> - -#include <config.h> -/* -#define PRINT_ROM_VEC -*/ -extern struct linux_romvec *kernel_arg_promvec; - -#define PROM_PGT __attribute__ ((__section__ (".prom.pgt"))) -#define PROM_TEXT __attribute__ ((__section__ (".prom.text"))) -#define PROM_DATA __attribute__ ((__section__ (".prom.data"))) - -/* for __va */ -extern int __prom_start; -#define PAGE_OFFSET 0xf0000000 -#define phys_base CONFIG_SYS_SDRAM_BASE -#define PROM_OFFS 8192 -#define PROM_SIZE_MASK (PROM_OFFS-1) -#define __va(x) ( \ - (void *)( ((unsigned long)(x))-PROM_OFFS+ \ - (CONFIG_SYS_PROM_OFFSET-phys_base)+PAGE_OFFSET-TEXT_BASE ) \ - ) -#define __phy(x) ((void *)(((unsigned long)(x))-PROM_OFFS+CONFIG_SYS_PROM_OFFSET-TEXT_BASE)) - -struct property { - char *name; - char *value; - int length; -}; - -struct node { - int level; - struct property *properties; -}; - -static void leon_reboot(char *bcommand); -static void leon_halt(void); -static int leon_nbputchar(int c); -static int leon_nbgetchar(void); - -static int no_nextnode(int node); -static int no_child(int node); -static int no_proplen(int node, char *name); -static int no_getprop(int node, char *name, char *value); -static int no_setprop(int node, char *name, char *value, int len); -static char *no_nextprop(int node, char *name); - -static struct property PROM_TEXT *find_property(int node, char *name); -static int PROM_TEXT leon_strcmp(const char *s1, const char *s2); -static void *PROM_TEXT leon_memcpy(void *dest, const void *src, size_t n); -static void PROM_TEXT leon_reboot_physical(char *bcommand); - -void __inline__ leon_flush_cache_all(void) -{ - __asm__ __volatile__(" flush "); - __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"::"i"(ASI_DFLUSH):"memory"); -} - -void __inline__ leon_flush_tlb_all(void) -{ - leon_flush_cache_all(); - __asm__ __volatile__("sta %%g0, [%0] %1\n\t"::"r"(0x400), - "i"(ASI_MMUFLUSH):"memory"); -} - -typedef struct { - unsigned int ctx_table[256]; - unsigned int pgd_table[256]; -} sparc_srmmu_setup; - -sparc_srmmu_setup srmmu_tables PROM_PGT = { - {0}, - {0x1e, - 0x10001e, - 0x20001e, - 0x30001e, - 0x40001e, - 0x50001e, - 0x60001e, - 0x70001e, - 0x80001e, - 0x90001e, - 0xa0001e, - 0xb0001e, - 0xc0001e, - 0xd0001e, - 0xe0001e, - 0xf0001e, - 0x100001e, - 0x110001e, - 0x120001e, - 0x130001e, - 0x140001e, - 0x150001e, - 0x160001e, - 0x170001e, - 0x180001e, - 0x190001e, - 0x1a0001e, - 0x1b0001e, - 0x1c0001e, - 0x1d0001e, - 0x1e0001e, - 0x1f0001e, - 0x200001e, - 0x210001e, - 0x220001e, - 0x230001e, - 0x240001e, - 0x250001e, - 0x260001e, - 0x270001e, - 0x280001e, - 0x290001e, - 0x2a0001e, - 0x2b0001e, - 0x2c0001e, - 0x2d0001e, - 0x2e0001e, - 0x2f0001e, - 0x300001e, - 0x310001e, - 0x320001e, - 0x330001e, - 0x340001e, - 0x350001e, - 0x360001e, - 0x370001e, - 0x380001e, - 0x390001e, - 0x3a0001e, - 0x3b0001e, - 0x3c0001e, - 0x3d0001e, - 0x3e0001e, - 0x3f0001e, - 0x400001e, - 0x410001e, - 0x420001e, - 0x430001e, - 0x440001e, - 0x450001e, - 0x460001e, - 0x470001e, - 0x480001e, - 0x490001e, - 0x4a0001e, - 0x4b0001e, - 0x4c0001e, - 0x4d0001e, - 0x4e0001e, - 0x4f0001e, - 0x500001e, - 0x510001e, - 0x520001e, - 0x530001e, - 0x540001e, - 0x550001e, - 0x560001e, - 0x570001e, - 0x580001e, - 0x590001e, - 0x5a0001e, - 0x5b0001e, - 0x5c0001e, - 0x5d0001e, - 0x5e0001e, - 0x5f0001e, - 0x600001e, - 0x610001e, - 0x620001e, - 0x630001e, - 0x640001e, - 0x650001e, - 0x660001e, - 0x670001e, - 0x680001e, - 0x690001e, - 0x6a0001e, - 0x6b0001e, - 0x6c0001e, - 0x6d0001e, - 0x6e0001e, - 0x6f0001e, - 0x700001e, - 0x710001e, - 0x720001e, - 0x730001e, - 0x740001e, - 0x750001e, - 0x760001e, - 0x770001e, - 0x780001e, - 0x790001e, - 0x7a0001e, - 0x7b0001e, - 0x7c0001e, - 0x7d0001e, - 0x7e0001e, - 0x7f0001e, - 0x800001e, - 0x810001e, - 0x820001e, - 0x830001e, - 0x840001e, - 0x850001e, - 0x860001e, - 0x870001e, - 0x880001e, - 0x890001e, - 0x8a0001e, - 0x8b0001e, - 0x8c0001e, - 0x8d0001e, - 0x8e0001e, - 0x8f0001e, - 0x900001e, - 0x910001e, - 0x920001e, - 0x930001e, - 0x940001e, - 0x950001e, - 0x960001e, - 0x970001e, - 0x980001e, - 0x990001e, - 0x9a0001e, - 0x9b0001e, - 0x9c0001e, - 0x9d0001e, - 0x9e0001e, - 0x9f0001e, - 0xa00001e, - 0xa10001e, - 0xa20001e, - 0xa30001e, - 0xa40001e, - 0xa50001e, - 0xa60001e, - 0xa70001e, - 0xa80001e, - 0xa90001e, - 0xaa0001e, - 0xab0001e, - 0xac0001e, - 0xad0001e, - 0xae0001e, - 0xaf0001e, - 0xb00001e, - 0xb10001e, - 0xb20001e, - 0xb30001e, - 0xb40001e, - 0xb50001e, - 0xb60001e, - 0xb70001e, - 0xb80001e, - 0xb90001e, - 0xba0001e, - 0xbb0001e, - 0xbc0001e, - 0xbd0001e, - 0xbe0001e, - 0xbf0001e, - 0xc00001e, - 0xc10001e, - 0xc20001e, - 0xc30001e, - 0xc40001e, - 0xc50001e, - 0xc60001e, - 0xc70001e, - 0xc80001e, - 0xc90001e, - 0xca0001e, - 0xcb0001e, - 0xcc0001e, - 0xcd0001e, - 0xce0001e, - 0xcf0001e, - 0xd00001e, - 0xd10001e, - 0xd20001e, - 0xd30001e, - 0xd40001e, - 0xd50001e, - 0xd60001e, - 0xd70001e, - 0xd80001e, - 0xd90001e, - 0xda0001e, - 0xdb0001e, - 0xdc0001e, - 0xdd0001e, - 0xde0001e, - 0xdf0001e, - 0xe00001e, - 0xe10001e, - 0xe20001e, - 0xe30001e, - 0xe40001e, - 0xe50001e, - 0xe60001e, - 0xe70001e, - 0xe80001e, - 0xe90001e, - 0xea0001e, - 0xeb0001e, - 0xec0001e, - 0xed0001e, - 0xee0001e, - 0xef0001e, - 0x400001e /* default */ - } -}; - -/* a self contained prom info structure */ -struct leon_reloc_func { - struct property *(*find_property) (int node, char *name); - int (*strcmp) (char *s1, char *s2); - void *(*memcpy) (void *dest, const void *src, size_t n); - void (*reboot_physical) (char *cmd); -}; - -struct leon_prom_info { - int freq_khz; - int leon_nctx; - int mids[32]; - int baudrates[2]; - struct leon_reloc_func reloc_funcs; - struct property root_properties[4]; - struct property cpu_properties[7]; -#undef CPUENTRY -#define CPUENTRY(idx) struct property cpu_properties##idx[4] - CPUENTRY(1); - CPUENTRY(2); - CPUENTRY(3); - CPUENTRY(4); - CPUENTRY(5); - CPUENTRY(6); - CPUENTRY(7); - CPUENTRY(8); - CPUENTRY(9); - CPUENTRY(10); - CPUENTRY(11); - CPUENTRY(12); - CPUENTRY(13); - CPUENTRY(14); - CPUENTRY(15); - CPUENTRY(16); - CPUENTRY(17); - CPUENTRY(18); - CPUENTRY(19); - CPUENTRY(20); - CPUENTRY(21); - CPUENTRY(22); - CPUENTRY(23); - CPUENTRY(24); - CPUENTRY(25); - CPUENTRY(26); - CPUENTRY(27); - CPUENTRY(28); - CPUENTRY(29); - CPUENTRY(30); - CPUENTRY(31); - struct idprom idprom; - struct linux_nodeops nodeops; - struct linux_mlist_v0 *totphys_p; - struct linux_mlist_v0 totphys; - struct linux_mlist_v0 *avail_p; - struct linux_mlist_v0 avail; - struct linux_mlist_v0 *prommap_p; - void (*synchook) (void); - struct linux_arguments_v0 *bootargs_p; - struct linux_arguments_v0 bootargs; - struct linux_romvec romvec; - struct node nodes[35]; - char s_device_type[12]; - char s_cpu[4]; - char s_mid[4]; - char s_idprom[7]; - char s_compatability[14]; - char s_leon2[6]; - char s_mmu_nctx[9]; - char s_frequency[16]; - char s_uart1_baud[11]; - char s_uart2_baud[11]; - char arg[256]; -}; - -/* static prom info */ -static struct leon_prom_info PROM_DATA spi = { - CONFIG_SYS_CLK_FREQ / 1000, - 256, - { -#undef CPUENTRY -#define CPUENTRY(idx) idx - CPUENTRY(0), - CPUENTRY(1), - CPUENTRY(2), - CPUENTRY(3), - CPUENTRY(4), - CPUENTRY(5), - CPUENTRY(6), - CPUENTRY(7), - CPUENTRY(8), - CPUENTRY(9), - CPUENTRY(10), - CPUENTRY(11), - CPUENTRY(12), - CPUENTRY(13), - CPUENTRY(14), - CPUENTRY(15), - CPUENTRY(16), - CPUENTRY(17), - CPUENTRY(18), - CPUENTRY(19), - CPUENTRY(20), - CPUENTRY(21), - CPUENTRY(22), - CPUENTRY(23), - CPUENTRY(24), - CPUENTRY(25), - CPUENTRY(26), - CPUENTRY(27), - CPUENTRY(28), - CPUENTRY(29), - CPUENTRY(30), - 31}, - {38400, 38400}, - { - __va(find_property), - __va(leon_strcmp), - __va(leon_memcpy), - __phy(leon_reboot_physical), - }, - { - {__va(spi.s_device_type), __va(spi.s_idprom), 4}, - {__va(spi.s_idprom), (char *)__va(&spi.idprom), sizeof(struct idprom)}, - {__va(spi.s_compatability), __va(spi.s_leon2), 5}, - {NULL, NULL, -1} - }, - { - {__va(spi.s_device_type), __va(spi.s_cpu), 4}, - {__va(spi.s_mid), __va(&spi.mids[0]), 4}, - {__va(spi.s_mmu_nctx), (char *)__va(&spi.leon_nctx), 4}, - {__va(spi.s_frequency), (char *)__va(&spi.freq_khz), 4}, - {__va(spi.s_uart1_baud), (char *)__va(&spi.baudrates[0]), 4}, - {__va(spi.s_uart2_baud), (char *)__va(&spi.baudrates[1]), 4}, - {NULL, NULL, -1} - }, -#undef CPUENTRY -#define CPUENTRY(idx) \ - { /* cpu_properties */ \ - {__va(spi.s_device_type), __va(spi.s_cpu), 4}, \ - {__va(spi.s_mid), __va(&spi.mids[idx]), 4}, \ - {__va(spi.s_frequency), (char *)__va(&spi.freq_khz), 4}, \ - {NULL, NULL, -1} \ - } - CPUENTRY(1), - CPUENTRY(2), - CPUENTRY(3), - CPUENTRY(4), - CPUENTRY(5), - CPUENTRY(6), - CPUENTRY(7), - CPUENTRY(8), - CPUENTRY(9), - CPUENTRY(10), - CPUENTRY(11), - CPUENTRY(12), - CPUENTRY(13), - CPUENTRY(14), - CPUENTRY(15), - CPUENTRY(16), - CPUENTRY(17), - CPUENTRY(18), - CPUENTRY(19), - CPUENTRY(20), - CPUENTRY(21), - CPUENTRY(22), - CPUENTRY(23), - CPUENTRY(24), - CPUENTRY(25), - CPUENTRY(26), - CPUENTRY(27), - CPUENTRY(28), - CPUENTRY(29), - CPUENTRY(30), - CPUENTRY(31), - { - 0x01, /* format */ - M_LEON2 | M_LEON2_SOC, /* machine type */ - {0, 0, 0, 0, 0, 0}, /* eth */ - 0, /* date */ - 0, /* sernum */ - 0, /* checksum */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} /* reserved */ - }, - { - __va(no_nextnode), - __va(no_child), - __va(no_proplen), - __va(no_getprop), - __va(no_setprop), - __va(no_nextprop) - }, - __va(&spi.totphys), - { - NULL, - (char *)CONFIG_SYS_SDRAM_BASE, - 0, - }, - __va(&spi.avail), - { - NULL, - (char *)CONFIG_SYS_SDRAM_BASE, - 0, - }, - NULL, /* prommap_p */ - NULL, - __va(&spi.bootargs), - { - {NULL, __va(spi.arg), NULL /*... */ }, - /*... */ - }, - { - 0, - 0, /* sun4c v0 prom */ - 0, 0, - {__va(&spi.totphys_p), __va(&spi.prommap_p), __va(&spi.avail_p)}, - __va(&spi.nodeops), - NULL, {NULL /* ... */ }, - NULL, NULL, - NULL, NULL, /* pv_getchar, pv_putchar */ - __va(leon_nbgetchar), __va(leon_nbputchar), - NULL, - __va(leon_reboot), - NULL, - NULL, - NULL, - __va(leon_halt), - __va(&spi.synchook), - {NULL}, - __va(&spi.bootargs_p) - /*... */ - }, - { - {0, __va(spi.root_properties + 3) /* NULL, NULL, -1 */ }, - {0, __va(spi.root_properties)}, - /* cpu 0, must be spi.nodes[2] see leon_prom_init() */ - {1, __va(spi.cpu_properties)}, - -#undef CPUENTRY -#define CPUENTRY(idx) \ - {1, __va(spi.cpu_properties##idx) } /* cpu <idx> */ - CPUENTRY(1), - CPUENTRY(2), - CPUENTRY(3), - CPUENTRY(4), - CPUENTRY(5), - CPUENTRY(6), - CPUENTRY(7), - CPUENTRY(8), - CPUENTRY(9), - CPUENTRY(10), - CPUENTRY(11), - CPUENTRY(12), - CPUENTRY(13), - CPUENTRY(14), - CPUENTRY(15), - CPUENTRY(16), - CPUENTRY(17), - CPUENTRY(18), - CPUENTRY(19), - CPUENTRY(20), - CPUENTRY(21), - CPUENTRY(22), - CPUENTRY(23), - CPUENTRY(24), - CPUENTRY(25), - CPUENTRY(26), - CPUENTRY(27), - CPUENTRY(28), - CPUENTRY(29), - CPUENTRY(30), - CPUENTRY(31), - {-1, __va(spi.root_properties + 3) /* NULL, NULL, -1 */ } - }, - "device_type", - "cpu", - "mid", - "idprom", - "compatability", - "leon2", - "mmu-nctx", - "clock-frequency", - "uart1_baud", - "uart2_baud", - CONFIG_DEFAULT_KERNEL_COMMAND_LINE -}; - -/* from arch/sparc/kernel/setup.c */ -#define RAMDISK_LOAD_FLAG 0x4000 -extern unsigned short root_flags; -extern unsigned short root_dev; -extern unsigned short ram_flags; -extern unsigned int sparc_ramdisk_image; -extern unsigned int sparc_ramdisk_size; -extern int root_mountflags; - -extern char initrd_end, initrd_start; - -/* Reboot the CPU = jump to beginning of flash again. - * - * Make sure that all function are inlined here. - */ -static void PROM_TEXT leon_reboot(char *bcommand) -{ - register char *arg = bcommand; - void __attribute__ ((noreturn)) (*reboot_physical) (char *cmd); - - /* get physical address */ - struct leon_prom_info *pspi = - (void *)(CONFIG_SYS_PROM_OFFSET + sizeof(srmmu_tables)); - - unsigned int *srmmu_ctx_table; - - /* Turn of Interrupts */ - set_pil(0xf); - - /* Set kernel's context, context zero */ - srmmu_set_context(0); - - /* Get physical address of the MMU shutdown routine */ - reboot_physical = (void *) - SPARC_BYPASS_READ(&pspi->reloc_funcs.reboot_physical); - - /* Now that we know the physical address of the function - * we can make the MMU allow jumping to it. - */ - srmmu_ctx_table = (unsigned int *)srmmu_get_ctable_ptr(); - - srmmu_ctx_table = (unsigned int *)SPARC_BYPASS_READ(srmmu_ctx_table); - - /* get physical address of kernel's context table (assume ptd) */ - srmmu_ctx_table = (unsigned int *) - (((unsigned int)srmmu_ctx_table & 0xfffffffc) << 4); - - /* enable access to physical address of MMU shutdown function */ - SPARC_BYPASS_WRITE(&srmmu_ctx_table - [((unsigned int)reboot_physical) >> 24], - (((unsigned int)reboot_physical & 0xff000000) >> 4) | - 0x1e); - - /* flush TLB cache */ - leon_flush_tlb_all(); - - /* flash instruction & data cache */ - sparc_icache_flush_all(); - sparc_dcache_flush_all(); - - /* jump to physical address function - * so that when the MMU is disabled - * we can continue to execute - */ - reboot_physical(arg); -} - -static void PROM_TEXT leon_reboot_physical(char *bcommand) -{ - void __attribute__ ((noreturn)) (*reset) (void); - - /* Turn off MMU */ - srmmu_set_mmureg(0); - - /* Hardcoded start address */ - reset = CONFIG_SYS_MONITOR_BASE; - - /* flush data cache */ - sparc_dcache_flush_all(); - - /* flush instruction cache */ - sparc_icache_flush_all(); - - /* Jump to start in Flash */ - reset(); -} - -static void PROM_TEXT leon_halt(void) -{ - while (1) ; -} - -/* get single char, don't care for blocking*/ -static int PROM_TEXT leon_nbgetchar(void) -{ - return -1; -} - -/* put single char, don't care for blocking*/ -static int PROM_TEXT leon_nbputchar(int c) -{ - LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS; - - /***** put char in buffer... *********** - * Make sure all functions are inline! * - ***************************************/ - - /* Wait for last character to go. */ - while (!(SPARC_BYPASS_READ(&leon2->UART_Status_1) - & LEON2_UART_STAT_THE)) ; - - /* Send data */ - SPARC_BYPASS_WRITE(&leon2->UART_Channel_1, c); - - /* Wait for data to be sent */ - while (!(SPARC_BYPASS_READ(&leon2->UART_Status_1) - & LEON2_UART_STAT_TSE)) ; - - return 0; -} - -/* node ops */ - -/*#define nodes ((struct node *)__va(&pspi->nodes))*/ -#define nodes ((struct node *)(pspi->nodes)) - -static int PROM_TEXT no_nextnode(int node) -{ - /* get physical address */ - struct leon_prom_info *pspi = - (void *)(CONFIG_SYS_PROM_OFFSET + sizeof(srmmu_tables)); - - /* convert into virtual address */ - pspi = (struct leon_prom_info *) - (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET); - - if (nodes[node].level == nodes[node + 1].level) - return node + 1; - return -1; -} - -static int PROM_TEXT no_child(int node) -{ - /* get physical address */ - struct leon_prom_info *pspi = (struct leon_prom_info *) - (CONFIG_SYS_PROM_OFFSET + sizeof(srmmu_tables)); - - /* convert into virtual address */ - pspi = (struct leon_prom_info *) - (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET); - - if (nodes[node].level == nodes[node + 1].level - 1) - return node + 1; - return -1; -} - -static struct property PROM_TEXT *find_property(int node, char *name) -{ - /* get physical address */ - struct leon_prom_info *pspi = (struct leon_prom_info *) - (CONFIG_SYS_PROM_OFFSET + sizeof(srmmu_tables)); - - /* convert into virtual address */ - pspi = (struct leon_prom_info *) - (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET); - - struct property *prop = &nodes[node].properties[0]; - while (prop && prop->name) { - if (pspi->reloc_funcs.strcmp(prop->name, name) == 0) - return prop; - prop++; - } - return NULL; -} - -static int PROM_TEXT no_proplen(int node, char *name) -{ - /* get physical address */ - struct leon_prom_info *pspi = (struct leon_prom_info *) - (CONFIG_SYS_PROM_OFFSET + sizeof(srmmu_tables)); - - /* convert into virtual address */ - pspi = (struct leon_prom_info *) - (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET); - - struct property *prop = pspi->reloc_funcs.find_property(node, name); - if (prop) - return prop->length; - return -1; -} - -static int PROM_TEXT no_getprop(int node, char *name, char *value) -{ - /* get physical address */ - struct leon_prom_info *pspi = (struct leon_prom_info *) - (CONFIG_SYS_PROM_OFFSET + sizeof(srmmu_tables)); - - /* convert into virtual address */ - pspi = (struct leon_prom_info *) - (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET); - - struct property *prop = pspi->reloc_funcs.find_property(node, name); - if (prop) { - pspi->reloc_funcs.memcpy(value, prop->value, prop->length); - return 1; - } - return -1; -} - -static int PROM_TEXT no_setprop(int node, char *name, char *value, int len) -{ - return -1; -} - -static char PROM_TEXT *no_nextprop(int node, char *name) -{ - /* get physical address */ - struct leon_prom_info *pspi = (struct leon_prom_info *) - (CONFIG_SYS_PROM_OFFSET + sizeof(srmmu_tables)); - struct property *prop; - - /* convert into virtual address */ - pspi = (struct leon_prom_info *) - (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET); - - if (!name || !name[0]) - return nodes[node].properties[0].name; - - prop = pspi->reloc_funcs.find_property(node, name); - if (prop) - return prop[1].name; - return NULL; -} - -static int PROM_TEXT leon_strcmp(const char *s1, const char *s2) -{ - register char result; - - while (1) { - result = *s1 - *s2; - if (result || !*s1) - break; - s2++; - s1++; - } - - return result; -} - -static void *PROM_TEXT leon_memcpy(void *dest, const void *src, size_t n) -{ - char *dst = (char *)dest, *source = (char *)src; - - while (n--) { - *dst = *source; - dst++; - source++; - } - return dest; -} - -#define GETREGSP(sp) __asm__ __volatile__("mov %%sp, %0" : "=r" (sp)) - -void leon_prom_init(struct leon_prom_info *pspi) -{ - unsigned long i; - unsigned char cksum, *ptr; - char *addr_str, *end; - unsigned long sp; - GETREGSP(sp); - - pspi->freq_khz = CONFIG_SYS_CLK_FREQ / 1000; - - /* Set Available main memory size */ - pspi->totphys.num_bytes = CONFIG_SYS_PROM_OFFSET - CONFIG_SYS_SDRAM_BASE; - pspi->avail.num_bytes = pspi->totphys.num_bytes; - -#undef nodes - pspi->nodes[3].level = -1; - pspi->nodes[3].properties = __va(spi.root_properties + 3); - - /* Set Ethernet MAC address from environment */ - if ((addr_str = getenv("ethaddr")) != NULL) { - for (i = 0; i < 6; i++) { - pspi->idprom.id_ethaddr[i] = addr_str ? - simple_strtoul(addr_str, &end, 16) : 0; - if (addr_str) { - addr_str = (*end) ? end + 1 : end; - } - } - } else { - /* HW Address not found in environment, - * Set default HW address - */ - pspi->idprom.id_ethaddr[0] = 0; - pspi->idprom.id_ethaddr[1] = 0; - pspi->idprom.id_ethaddr[2] = 0; - pspi->idprom.id_ethaddr[3] = 0; - pspi->idprom.id_ethaddr[4] = 0; - pspi->idprom.id_ethaddr[5] = 0; - } - - ptr = (unsigned char *)&pspi->idprom; - for (i = cksum = 0; i <= 0x0E; i++) - cksum ^= *ptr++; - pspi->idprom.id_cksum = cksum; -} - -static inline void set_cache(unsigned long regval) -{ - asm volatile ("sta %0, [%%g0] %1\n\t":: "r" (regval), "i"(2):"memory"); -} - -extern unsigned short bss_start, bss_end; - -/* mark as section .img.main.text, to be referenced in linker script */ -int prom_init(void) -{ - struct leon_prom_info *pspi = (void *) - ((((unsigned int)&spi) & PROM_SIZE_MASK) + CONFIG_SYS_PROM_OFFSET); - - /* disable mmu */ - srmmu_set_mmureg(0x00000000); - __asm__ __volatile__("flush\n\t"); - - /* init prom info struct */ - leon_prom_init(pspi); - - kernel_arg_promvec = &pspi->romvec; -#ifdef PRINT_ROM_VEC - printf("Kernel rom vec: 0x%lx\n", (unsigned int)(&pspi->romvec)); -#endif - return 0; -} - -/* Copy current kernel boot argument to ROMvec */ -void prepare_bootargs(char *bootargs) -{ - struct leon_prom_info *pspi; - char *src, *dst; - int left; - - /* if no bootargs set, skip copying ==> default bootline */ - if (bootargs && (*bootargs != '\0')) { - pspi = (void *)((((unsigned int)&spi) & PROM_SIZE_MASK) + - CONFIG_SYS_PROM_OFFSET); - src = bootargs; - dst = &pspi->arg[0]; - left = 255; /* max len */ - while (*src && left > 0) { - *dst++ = *src++; - left--; - } - /* terminate kernel command line string */ - *dst = 0; - } -} - -void srmmu_init_cpu(unsigned int entry) -{ - sparc_srmmu_setup *psrmmu_tables = (void *) - ((((unsigned int)&srmmu_tables) & PROM_SIZE_MASK) + - CONFIG_SYS_PROM_OFFSET); - - /* Make context 0 (kernel's context) point - * to our prepared memory mapping - */ -#define PTD 1 - psrmmu_tables->ctx_table[0] = - ((unsigned int)&psrmmu_tables->pgd_table[0x00]) >> 4 | PTD; - - /* Set virtual kernel address 0xf0000000 - * to SRAM/SDRAM address. - * Make it READ/WRITE/EXEC to SuperUser - */ -#define PTE 2 -#define ACC_SU_ALL 0x1c - psrmmu_tables->pgd_table[0xf0] = - (CONFIG_SYS_SDRAM_BASE >> 4) | ACC_SU_ALL | PTE; - psrmmu_tables->pgd_table[0xf1] = - ((CONFIG_SYS_SDRAM_BASE + 0x1000000) >> 4) | ACC_SU_ALL | PTE; - psrmmu_tables->pgd_table[0xf2] = - ((CONFIG_SYS_SDRAM_BASE + 0x2000000) >> 4) | ACC_SU_ALL | PTE; - psrmmu_tables->pgd_table[0xf3] = - ((CONFIG_SYS_SDRAM_BASE + 0x3000000) >> 4) | ACC_SU_ALL | PTE; - psrmmu_tables->pgd_table[0xf4] = - ((CONFIG_SYS_SDRAM_BASE + 0x4000000) >> 4) | ACC_SU_ALL | PTE; - psrmmu_tables->pgd_table[0xf5] = - ((CONFIG_SYS_SDRAM_BASE + 0x5000000) >> 4) | ACC_SU_ALL | PTE; - psrmmu_tables->pgd_table[0xf6] = - ((CONFIG_SYS_SDRAM_BASE + 0x6000000) >> 4) | ACC_SU_ALL | PTE; - psrmmu_tables->pgd_table[0xf7] = - ((CONFIG_SYS_SDRAM_BASE + 0x7000000) >> 4) | ACC_SU_ALL | PTE; - - /* convert rom vec pointer to virtual address */ - kernel_arg_promvec = (struct linux_romvec *) - (((unsigned int)kernel_arg_promvec & 0x0fffffff) | 0xf0000000); - - /* Set Context pointer to point to context table - * 256 contexts supported. - */ - srmmu_set_ctable_ptr((unsigned int)&psrmmu_tables->ctx_table[0]); - - /* Set kernel's context, context zero */ - srmmu_set_context(0); - - /* Invalidate all Cache */ - __asm__ __volatile__("flush\n\t"); - - srmmu_set_mmureg(0x00000001); - leon_flush_tlb_all(); - leon_flush_cache_all(); -} diff --git a/cpu/leon2/serial.c b/cpu/leon2/serial.c deleted file mode 100644 index 4f41b8e6aa..0000000000 --- a/cpu/leon2/serial.c +++ /dev/null @@ -1,165 +0,0 @@ -/* 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 = CONFIG_SYS_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; - } -} diff --git a/cpu/leon2/start.S b/cpu/leon2/start.S deleted file mode 100644 index b1f1eb5f3c..0000000000 --- a/cpu/leon2/start.S +++ /dev/null @@ -1,662 +0,0 @@ -/* 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 <timestamp.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 CONFIG_SYS_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 " (", U_BOOT_DATE, " - ", U_BOOT_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 CONFIG_SYS_GRLIB_MEMCFG1, %g2 - ld [%g1], %g3 ! - and %g3, 0x300, %g3 - or %g2, %g3, %g2 - st %g2, [%g1 + LEON2_MCFG1] - set CONFIG_SYS_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 CONFIG_SYS_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 CONFIG_SYS_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 CONFIG_SYS_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) - - * CONFIG_SYS_RELOC_MONITOR_BASE(from define) ) + - * Destination Address (from define) - */ - set CONFIG_SYS_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 CONFIG_SYS_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 CONFIG_SYS_RELOC_MONITOR_BASE, %g2 - wr %g0, %g2, %tbr - -/* call relocate*/ - nop -/* Call relocated init functions */ -jump: - set cpu_init_f2,%o1 - set CONFIG_SYS_RELOC_MONITOR_BASE,%o2 - add %o1,%o2,%o1 - sub %o1,%g1,%o1 - call %o1 - clr %o0 - - set board_init_f,%o1 - set CONFIG_SYS_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 (CONFIG_SYS_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, (CONFIG_SYS_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, (CONFIG_SYS_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 (CONFIG_SYS_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 CONFIG_SYS_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 (CONFIG_SYS_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 |