diff options
Diffstat (limited to 'cpu')
-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 | ||||
-rw-r--r-- | cpu/leon3/Makefile | 54 | ||||
-rw-r--r-- | cpu/leon3/ambapp.c | 359 | ||||
-rw-r--r-- | cpu/leon3/config.mk | 26 | ||||
-rw-r--r-- | cpu/leon3/cpu.c | 75 | ||||
-rw-r--r-- | cpu/leon3/cpu_init.c | 254 | ||||
-rw-r--r-- | cpu/leon3/interrupts.c | 219 | ||||
-rw-r--r-- | cpu/leon3/prom.c | 1078 | ||||
-rw-r--r-- | cpu/leon3/serial.c | 139 | ||||
-rw-r--r-- | cpu/leon3/start.S | 617 | ||||
-rw-r--r-- | cpu/leon3/usb_uhci.c | 1313 | ||||
-rw-r--r-- | cpu/leon3/usb_uhci.h | 184 |
19 files changed, 0 insertions, 6697 deletions
diff --git a/cpu/leon2/Makefile b/cpu/leon2/Makefile deleted file mode 100644 index 7cc4420..0000000 --- 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 30b224a..0000000 --- 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 d6e23b1..0000000 --- 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 a24f778..0000000 --- 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 9b0da96..0000000 --- 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 1a6c7f7..0000000 --- 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 4f41b8e..0000000 --- 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 b1f1eb5..0000000 --- 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 diff --git a/cpu/leon3/Makefile b/cpu/leon3/Makefile deleted file mode 100644 index 182543d..0000000 --- a/cpu/leon3/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 ambapp.o interrupts.o prom.o usb_uhci.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/leon3/ambapp.c b/cpu/leon3/ambapp.c deleted file mode 100644 index efd41ae..0000000 --- a/cpu/leon3/ambapp.c +++ /dev/null @@ -1,359 +0,0 @@ -/* Gaisler AMBA Plug&Play bus scanning. Functions - * ending on _nomem is inteded to be used only during - * initialization, only registers are used (no ram). - * - * (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 <command.h> -#include <ambapp.h> - -#if defined(CONFIG_CMD_AMBAPP) -extern void ambapp_print_apb(apbctrl_pp_dev * apb, - ambapp_ahbdev * apbmst, int index); -extern void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index); -extern int ambapp_apb_print; -extern int ambapp_ahb_print; -#endif - -static int ambapp_apb_scan(unsigned int vendor, /* Plug&Play Vendor ID */ - unsigned int driver, /* Plug&Play Device ID */ - ambapp_apbdev * dev, /* Result(s) is placed here */ - int index, /* Index of device to start copying Plug&Play - * info into dev - */ - int max_cnt /* Maximal count that dev can hold, if dev - * is NULL function will stop scanning after - * max_cnt devices are found. - */ - ) -{ - int i, cnt = 0; - unsigned int apbmst_base; - ambapp_ahbdev apbmst; - apbctrl_pp_dev *apb; - - if (max_cnt == 0) - return 0; - - /* Get AMBA APB Master */ - if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_APBMST, &apbmst) != 1) { - return 0; - } - - /* Get APB CTRL Plug&Play info area */ - apbmst_base = apbmst.address[0] & LEON3_IO_AREA; - apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA); - - for (i = 0; i < LEON3_APB_SLAVES; i++) { -#if defined(CONFIG_CMD_AMBAPP) - if (ambapp_apb_print && amba_vendor(apb->conf) - && amba_device(apb->conf)) { - ambapp_print_apb(apb, &apbmst, i); - } -#endif - if ((amba_vendor(apb->conf) == vendor) && - (amba_device(apb->conf) == driver) && ((index < 0) - || (index-- == 0))) { - /* Convert Plug&Play info into a more readable format */ - cnt++; - if (dev) { - dev->irq = amba_irq(apb->conf); - dev->ver = amba_ver(apb->conf); - dev->address = - (apbmst_base | - (((apb-> - bar & 0xfff00000) >> 12))) & (((apb-> - bar & - 0x0000fff0) - << 4) | - 0xfff00000); - dev++; - } - /* found max devices? */ - if (cnt >= max_cnt) - return cnt; - } - /* Get next Plug&Play entry */ - apb++; - } - return cnt; -} - -unsigned int ambapp_apb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */ - register unsigned int driver, /* Plug&Play Device ID */ - register int index) -{ - register int i; - register ahbctrl_pp_dev *apbmst; - register apbctrl_pp_dev *apb; - register unsigned int apbmst_base; - - /* APBMST is a AHB Slave */ - apbmst = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0); - if (!apbmst) - return 0; - - apbmst_base = amba_membar_start(apbmst->bars[0]); - if (amba_membar_type(apbmst->bars[0]) == AMBA_TYPE_AHBIO) - apbmst_base = AMBA_TYPE_AHBIO_ADDR(apbmst_base); - apbmst_base &= LEON3_IO_AREA; - - /* Find the vendor/driver device on the first APB bus */ - apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA); - - for (i = 0; i < LEON3_APB_SLAVES; i++) { - if ((amba_vendor(apb->conf) == vendor) && - (amba_device(apb->conf) == driver) && ((index < 0) - || (index-- == 0))) { - /* Convert Plug&Play info info a more readable format */ - return (apbmst_base | (((apb->bar & 0xfff00000) >> 12))) - & (((apb->bar & 0x0000fff0) << 4) | 0xfff00000); - } - /* Get next Plug&Play entry */ - apb++; - } - return 0; -} - -/****************************** APB SLAVES ******************************/ - -int ambapp_apb_count(unsigned int vendor, unsigned int driver) -{ - return ambapp_apb_scan(vendor, driver, NULL, 0, LEON3_APB_SLAVES); -} - -int ambapp_apb_first(unsigned int vendor, - unsigned int driver, ambapp_apbdev * dev) -{ - return ambapp_apb_scan(vendor, driver, dev, 0, 1); -} - -int ambapp_apb_next(unsigned int vendor, - unsigned int driver, ambapp_apbdev * dev, int index) -{ - return ambapp_apb_scan(vendor, driver, dev, index, 1); -} - -int ambapp_apbs_first(unsigned int vendor, - unsigned int driver, ambapp_apbdev * dev, int max_cnt) -{ - return ambapp_apb_scan(vendor, driver, dev, 0, max_cnt); -} - -enum { - AHB_SCAN_MASTER = 0, - AHB_SCAN_SLAVE = 1 -}; - -/* Scan AMBA Plug&Play bus for AMBA AHB Masters or AHB Slaves - * for a certain matching Vendor and Device ID. - * - * Return number of devices found. - * - * Compact edition... - */ -static int ambapp_ahb_scan(unsigned int vendor, /* Plug&Play Vendor ID */ - unsigned int driver, /* Plug&Play Device ID */ - ambapp_ahbdev * dev, /* Result(s) is placed here */ - int index, /* Index of device to start copying Plug&Play - * info into dev - */ - int max_cnt, /* Maximal count that dev can hold, if dev - * is NULL function will stop scanning after - * max_cnt devices are found. - */ - int type /* Selectes what type of devices to scan. - * 0=AHB Masters - * 1=AHB Slaves - */ - ) -{ - int i, j, cnt = 0, max_pp_devs; - unsigned int addr; - ahbctrl_info *info = (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA); - ahbctrl_pp_dev *ahb; - - if (max_cnt == 0) - return 0; - - if (type == 0) { - max_pp_devs = LEON3_AHB_MASTERS; - ahb = info->masters; - } else { - max_pp_devs = LEON3_AHB_SLAVES; - ahb = info->slaves; - } - - for (i = 0; i < max_pp_devs; i++) { -#if defined(CONFIG_CMD_AMBAPP) - if (ambapp_ahb_print && amba_vendor(ahb->conf) && - amba_device(ahb->conf)) { - ambapp_print_ahb(ahb, i); - } -#endif - if ((amba_vendor(ahb->conf) == vendor) && - (amba_device(ahb->conf) == driver) && - ((index < 0) || (index-- == 0))) { - /* Convert Plug&Play info info a more readable format */ - cnt++; - if (dev) { - dev->irq = amba_irq(ahb->conf); - dev->ver = amba_ver(ahb->conf); - dev->userdef[0] = ahb->userdef[0]; - dev->userdef[1] = ahb->userdef[1]; - dev->userdef[2] = ahb->userdef[2]; - for (j = 0; j < 4; j++) { - addr = amba_membar_start(ahb->bars[j]); - if (amba_membar_type(ahb->bars[j]) == - AMBA_TYPE_AHBIO) - addr = - AMBA_TYPE_AHBIO_ADDR(addr); - dev->address[j] = addr; - } - dev++; - } - /* found max devices? */ - if (cnt >= max_cnt) - return cnt; - } - /* Get next Plug&Play entry */ - ahb++; - } - return cnt; -} - -unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info) -{ - register unsigned int ret; - - if (!ahb) - return 0; - - switch (info) { - default: - info = 0; - case 0: - case 1: - case 2: - case 3: - /* Get Address from PnP Info */ - ret = amba_membar_start(ahb->bars[info]); - if (amba_membar_type(ahb->bars[info]) == AMBA_TYPE_AHBIO) - ret = AMBA_TYPE_AHBIO_ADDR(ret); - return ret; - } - return 0; - -} - -ahbctrl_pp_dev *ambapp_ahb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */ - register unsigned int driver, /* Plug&Play Device ID */ - register unsigned int opts, /* 1=slave, 0=master */ - register int index) -{ - register ahbctrl_pp_dev *ahb; - register ahbctrl_info *info = - (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA); - register int i; - register int max_pp_devs; - - if (opts == 0) { - max_pp_devs = LEON3_AHB_MASTERS; - ahb = info->masters; - } else { - max_pp_devs = LEON3_AHB_SLAVES; - ahb = info->slaves; - } - - for (i = 0; i < max_pp_devs; i++) { - if ((amba_vendor(ahb->conf) == vendor) && - (amba_device(ahb->conf) == driver) && - ((index < 0) || (index-- == 0))) { - /* Convert Plug&Play info info a more readable format */ - return ahb; - } - /* Get next Plug&Play entry */ - ahb++; - } - return 0; -} - -/****************************** AHB MASTERS ******************************/ -int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver) -{ - /* Get number of devices of this vendor&device ID */ - return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_MASTERS, - AHB_SCAN_MASTER); -} - -int ambapp_ahbmst_first(unsigned int vendor, unsigned int driver, - ambapp_ahbdev * dev) -{ - /* find first device of this */ - return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_MASTER); -} - -int ambapp_ahbmst_next(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int index) -{ - /* find first device of this */ - return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_MASTER); -} - -int ambapp_ahbmsts_first(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int max_cnt) -{ - /* find first device of this */ - return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt, - AHB_SCAN_MASTER); -} - -/****************************** AHB SLAVES ******************************/ -int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver) -{ - /* Get number of devices of this vendor&device ID */ - return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_SLAVES, - AHB_SCAN_SLAVE); -} - -int ambapp_ahbslv_first(unsigned int vendor, unsigned int driver, - ambapp_ahbdev * dev) -{ - /* find first device of this */ - return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_SLAVE); -} - -int ambapp_ahbslv_next(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int index) -{ - /* find first device of this */ - return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_SLAVE); -} - -int ambapp_ahbslvs_first(unsigned int vendor, - unsigned int driver, ambapp_ahbdev * dev, int max_cnt) -{ - /* find first device of this */ - return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt, AHB_SCAN_SLAVE); -} diff --git a/cpu/leon3/config.mk b/cpu/leon3/config.mk deleted file mode 100644 index 30b224a..0000000 --- a/cpu/leon3/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/leon3/cpu.c b/cpu/leon3/cpu.c deleted file mode 100644 index 976f311..0000000 --- a/cpu/leon3/cpu.c +++ /dev/null @@ -1,75 +0,0 @@ -/* CPU specific code for the LEON3 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> - -#include <asm/io.h> -#include <asm/processor.h> - -DECLARE_GLOBAL_DATA_PTR; - -extern void _reset_reloc(void); - -int checkcpu(void) -{ - /* check LEON version here */ - printf("CPU: LEON3\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; - -} - -u64 flash_read64(void *addr) -{ - return __raw_readq(addr); -} - -/* ------------------------------------------------------------------------- */ - -#ifdef CONFIG_GRETH -int cpu_eth_init(bd_t *bis) -{ - return greth_initialize(bis); -} -#endif diff --git a/cpu/leon3/cpu_init.c b/cpu/leon3/cpu_init.c deleted file mode 100644 index be22ec2..0000000 --- a/cpu/leon3/cpu_init.c +++ /dev/null @@ -1,254 +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 <ambapp.h> - -#include <config.h> - -DECLARE_GLOBAL_DATA_PTR; - -/* reset CPU (jump to 0, without reset) */ -void start(void); - -/* find & initialize the memory controller */ -int init_memory_ctrl(void); - -ambapp_dev_irqmp *irqmp = NULL; -ambapp_dev_mctrl memctrl; -ambapp_dev_gptimer *gptimer = NULL; -unsigned int gptimer_irq = 0; -int leon3_snooping_avail = 0; - -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) -{ - /* these varaiable must not be initialized */ - ambapp_dev_irqmp *irqmp; - ambapp_apbdev apbdev; - register unsigned int apbmst; - - /* find AMBA APB Master */ - apbmst = (unsigned int) - ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0); - if (!apbmst) { - /* - * no AHB/APB bridge, something is wrong - * ==> jump to start (or hang) - */ - while (1) ; - } - /* Init memory controller */ - if (init_memory_ctrl()) { - while (1) ; - } - - /**************************************************** - * From here we can use the main memory and the stack. - */ - - /* Find AMBA APB IRQMP Controller */ - if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev) != 1) { - /* no IRQ controller, something is wrong - * ==> jump to start (or hang) - */ - while (1) ; - } - irqmp = (ambapp_dev_irqmp *) apbdev.address; - - /* initialize the IRQMP */ - irqmp->ilevel = 0xf; /* all IRQ off */ - irqmp->iforce = 0; - irqmp->ipend = 0; - irqmp->iclear = 0xfffe; /* clear all old pending interrupts */ - irqmp->cpu_mask[0] = 0; /* mask all IRQs on CPU 0 */ - irqmp->cpu_force[0] = 0; /* no force IRQ on CPU 0 */ - - /* cache */ -} - -void cpu_init_f2(void) -{ - -} - -/* - * initialize higher level parts of CPU like time base and timers - */ -int cpu_init_r(void) -{ - ambapp_apbdev apbdev; - - /* - * Find AMBA APB IRQMP Controller, - * When we come so far we know there is a IRQMP available - */ - ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev); - irqmp = (ambapp_dev_irqmp *) apbdev.address; - - /* timer */ - if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_GPTIMER, &apbdev) != 1) { - printf("cpu_init_r: gptimer not found!\n"); - return 1; - } - gptimer = (ambapp_dev_gptimer *) apbdev.address; - gptimer_irq = apbdev.irq; - - /* initialize prescaler common to all timers to 1MHz */ - gptimer->scalar = gptimer->scalar_reload = - (((CONFIG_SYS_CLK_FREQ / 1000) + 500) / 1000) - 1; - - return (0); -} - -/* find & setup memory controller */ -int init_memory_ctrl() -{ - register ambapp_dev_mctrl *mctrl; - register ambapp_dev_sdctrl *sdctrl; - register ambapp_dev_ddrspa *ddrspa; - register ambapp_dev_ddr2spa *ddr2spa; - register ahbctrl_pp_dev *ahb; - register unsigned int base; - register int not_found_mctrl = -1; - - /* find ESA Memory controller */ - base = ambapp_apb_next_nomem(VENDOR_ESA, ESA_MCTRL, 0); - if (base) { - mctrl = (ambapp_dev_mctrl *) base; - - /* config MCTRL memory controller */ - mctrl->mcfg1 = CONFIG_SYS_GRLIB_MEMCFG1 | (mctrl->mcfg1 & 0x300); - mctrl->mcfg2 = CONFIG_SYS_GRLIB_MEMCFG2; - mctrl->mcfg3 = CONFIG_SYS_GRLIB_MEMCFG3; - not_found_mctrl = 0; - } - - /* find Gaisler Fault Tolerant Memory controller */ - base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_FTMCTRL, 0); - if (base) { - mctrl = (ambapp_dev_mctrl *) base; - - /* config MCTRL memory controller */ - mctrl->mcfg1 = CONFIG_SYS_GRLIB_FT_MEMCFG1 | (mctrl->mcfg1 & 0x300); - mctrl->mcfg2 = CONFIG_SYS_GRLIB_FT_MEMCFG2; - mctrl->mcfg3 = CONFIG_SYS_GRLIB_FT_MEMCFG3; - not_found_mctrl = 0; - } - - /* find SDRAM controller */ - base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_SDCTRL, 0); - if (base) { - sdctrl = (ambapp_dev_sdctrl *) base; - - /* config memory controller */ - sdctrl->sdcfg = CONFIG_SYS_GRLIB_SDRAM; - not_found_mctrl = 0; - } - - ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDR2SPA, 1, 0); - if (ahb) { - ddr2spa = (ambapp_dev_ddr2spa *) ambapp_ahb_get_info(ahb, 1); - - /* Config DDR2 memory controller */ - ddr2spa->cfg1 = CONFIG_SYS_GRLIB_DDR2_CFG1; - ddr2spa->cfg3 = CONFIG_SYS_GRLIB_DDR2_CFG3; - not_found_mctrl = 0; - } - - ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDRSPA, 1, 0); - if (ahb) { - ddrspa = (ambapp_dev_ddrspa *) ambapp_ahb_get_info(ahb, 1); - - /* Config DDR memory controller */ - ddrspa->ctrl = CONFIG_SYS_GRLIB_DDR_CFG; - not_found_mctrl = 0; - } - - /* failed to find any memory controller */ - return not_found_mctrl; -} - -/* 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) -{ - /* 1ms ticks */ - gptimer->e[0].val = 0; - gptimer->e[0].rld = 999; /* (((1000000 / 100) - 1)) */ - gptimer->e[0].ctrl = - (LEON3_GPTIMER_EN | - LEON3_GPTIMER_RL | LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN); - - return gptimer_irq; -} - -/* - * 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/leon3/interrupts.c b/cpu/leon3/interrupts.c deleted file mode 100644 index ac6aca5..0000000 --- a/cpu/leon3/interrupts.c +++ /dev/null @@ -1,219 +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> -#include <ambapp.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; -}; - -extern ambapp_dev_irqmp *irqmp; -extern ambapp_dev_gptimer *gptimer; - -static struct irq_action irq_handlers[NR_IRQS] = { {0}, }; -static int spurious_irq_cnt = 0; -static int spurious_irq = 0; - -static inline unsigned int irqmp_get_irqmask(unsigned int irq) -{ - if ((irq < 0) || (irq >= NR_IRQS)) { - return 0; - } else { - return (1 << irq); - } - -} - -static void leon3_ic_disable(unsigned int irq) -{ - unsigned int mask, pil; - if (!irqmp) - return; - - pil = intLock(); - - /* get mask of interrupt */ - mask = irqmp_get_irqmask(irq); - - /* set int level */ - irqmp->cpu_mask[0] = SPARC_NOCACHE_READ(&irqmp->cpu_mask[0]) & (~mask); - - intUnlock(pil); -} - -static void leon3_ic_enable(unsigned int irq) -{ - unsigned int mask, pil; - if (!irqmp) - return; - - pil = intLock(); - - /* get mask of interrupt */ - mask = irqmp_get_irqmask(irq); - - /* set int level */ - irqmp->cpu_mask[0] = SPARC_NOCACHE_READ(&irqmp->cpu_mask[0]) | 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 leon3_force_int(int irq) -{ - if (!irqmp || (irq >= NR_IRQS) || (irq < 0)) - return; - printf("Forcing interrupt %d\n", irq); - - irqmp->iforce = SPARC_NOCACHE_READ(&irqmp->iforce) | (1 << irq); -} - -/****************************************************************************/ - -int interrupt_init_cpu(void) -{ - - return (0); -} - -/****************************************************************************/ - -/* Handle Timer 0 IRQ */ -void timer_interrupt_cpu(void *arg) -{ - gptimer->e[0].ctrl = (LEON3_GPTIMER_EN | - LEON3_GPTIMER_RL | - LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN); - /* 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 IRQMP hardware */ - leon3_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 IRQMP hardware */ - leon3_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/leon3/prom.c b/cpu/leon3/prom.c deleted file mode 100644 index 18d2fb2..0000000 --- a/cpu/leon3/prom.c +++ /dev/null @@ -1,1078 +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 <ambapp.h> - -#include <config.h> -/* -#define PRINT_ROM_VEC -*/ -extern struct linux_romvec *kernel_arg_promvec; -extern ambapp_dev_apbuart *leon3_apbuart; - -#define PROM_PGT __attribute__ ((__section__ (".prom.pgt"))) -#define PROM_TEXT __attribute__ ((__section__ (".prom.text"))) -#define PROM_DATA __attribute__ ((__section__ (".prom.data"))) - -ambapp_dev_gptimer *gptimer; - -/* 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); - ambapp_dev_apbuart *leon3_apbuart; -}; - -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) -{ - ambapp_dev_apbuart *uart; - - /* get physical address */ - struct leon_prom_info *pspi = - (void *)(CONFIG_SYS_PROM_OFFSET + sizeof(srmmu_tables)); - - uart = (ambapp_dev_apbuart *) - SPARC_BYPASS_READ(&pspi->reloc_funcs.leon3_apbuart); - - /* no UART? */ - if (!uart) - return 0; - - /***** put char in buffer... *********** - * Make sure all functions are inline! * - ***************************************/ - - /* Wait for last character to go. */ - while (!(SPARC_BYPASS_READ(&uart->status) - & LEON_REG_UART_STATUS_THE)) ; - - /* Send data */ - SPARC_BYPASS_WRITE(&uart->data, c); - - /* Wait for data to be sent */ - while (!(SPARC_BYPASS_READ(&uart->status) - & LEON_REG_UART_STATUS_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; - - /* Set the pointer to the Console UART in romvec */ - pspi->reloc_funcs.leon3_apbuart = leon3_apbuart; - - { - int j = 1; -#ifdef CONFIG_SMP - ambapp_dev_irqmp *b; - b = (ambapp_dev_irqmp *) leon3_getapbbase(VENDOR_GAISLER, - GAISLER_IRQMP); - if (b) { - j = 1 + ((LEON3_BYPASS_LOAD_PA(&(b->mpstatus)) - >> LEON3_IRQMPSTATUS_CPUNR) & 0xf); - } -#endif -#undef nodes - pspi->nodes[2 + j].level = -1; - pspi->nodes[2 + j].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/leon3/serial.c b/cpu/leon3/serial.c deleted file mode 100644 index 4b2fcb8..0000000 --- a/cpu/leon3/serial.c +++ /dev/null @@ -1,139 +0,0 @@ -/* GRLIB APBUART Serial controller driver - * - * (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/processor.h> -#include <asm/leon.h> -#include <ambapp.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 - -ambapp_dev_apbuart *leon3_apbuart = NULL; - -int serial_init(void) -{ - ambapp_apbdev apbdev; - unsigned int tmp; - - /* find UART */ - if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_APBUART, &apbdev) == 1) { - - leon3_apbuart = (ambapp_dev_apbuart *) apbdev.address; - - /* found apbuart, let's init... - * - * Set scaler / baud rate - * - * Receiver & transmitter enable - */ - leon3_apbuart->scaler = CONFIG_SYS_GRLIB_APBUART_SCALER; - - /* Let bit 11 be unchanged (debug bit for GRMON) */ - tmp = READ_WORD(leon3_apbuart->ctrl); - - leon3_apbuart->ctrl = ((tmp & LEON_REG_UART_CTRL_DBG) | - LEON_REG_UART_CTRL_RE | - LEON_REG_UART_CTRL_TE); - - return 0; - } - return -1; /* didn't find hardware */ -} - -void serial_putc(const char c) -{ - if (c == '\n') - serial_putc_raw('\r'); - - serial_putc_raw(c); -} - -void serial_putc_raw(const char c) -{ - if (!leon3_apbuart) - return; - - /* Wait for last character to go. */ - while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_THE)) ; - - /* Send data */ - leon3_apbuart->data = c; - -#ifdef LEON_DEBUG - /* Wait for data to be sent */ - while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_TSE)) ; -#endif -} - -void serial_puts(const char *s) -{ - while (*s) { - serial_putc(*s++); - } -} - -int serial_getc(void) -{ - if (!leon3_apbuart) - return 0; - - /* Wait for a character to arrive. */ - while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_DR)) ; - - /* read data */ - return READ_WORD(leon3_apbuart->data); -} - -int serial_tstc(void) -{ - if (leon3_apbuart) - return (READ_WORD(leon3_apbuart->status) & - LEON_REG_UART_STATUS_DR); - return 0; -} - -/* set baud rate for uart */ -void serial_setbrg(void) -{ - /* update baud rate settings, read it from gd->baudrate */ - unsigned int scaler; - if (leon3_apbuart && (gd->baudrate > 0)) { - scaler = - (((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) - - 5) / 10; - leon3_apbuart->scaler = scaler; - } - return; -} diff --git a/cpu/leon3/start.S b/cpu/leon3/start.S deleted file mode 100644 index bd634bd..0000000 --- a/cpu/leon3/start.S +++ /dev/null @@ -1,617 +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 - .extern leon3_snooping_avail - .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 - - /* Enable I/D-Cache and Snooping */ - set 0x0081000f, %g2 - sta %g2, [%g0] 2 - - 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 - -wininit: - set WIM_INIT, %g3 - mov %g3, %wim - -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 - nop - nop - nop - -/* If CACHE snooping is available in hardware the - * variable leon3_snooping_avail will be set to - * 0x800000 else 0. - */ -snoop_detect: - sethi %hi(0x00800000), %o0 - lda [%g0] 2, %o1 - and %o0, %o1, %o0 - sethi %hi(leon3_snooping_avail+CONFIG_SYS_RELOC_MONITOR_BASE-TEXT_BASE), %o1 - st %o0, [%lo(leon3_snooping_avail+CONFIG_SYS_RELOC_MONITOR_BASE-TEXT_BASE)+%o1] - -/* 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 diff --git a/cpu/leon3/usb_uhci.c b/cpu/leon3/usb_uhci.c deleted file mode 100644 index 8f99e1d..0000000 --- a/cpu/leon3/usb_uhci.c +++ /dev/null @@ -1,1313 +0,0 @@ -/* - * Part of this code has been derived from linux: - * Universal Host Controller Interface driver for USB (take II). - * - * (c) 1999-2001 Georg Acher, acher@in.tum.de (executive slave) (base guitar) - * Deti Fliegl, deti@fliegl.de (executive slave) (lead voice) - * Thomas Sailer, sailer@ife.ee.ethz.ch (chief consultant) (cheer leader) - * Roman Weissgaerber, weissg@vienna.at (virt root hub) (studio porter) - * (c) 2000 Yggdrasil Computing, Inc. (port of new PCI interface support - * from usb-ohci.c by Adam Richter, adam@yggdrasil.com). - * (C) 2000 David Brownell, david-b@pacbell.net (usb-ohci.c) - * - * HW-initalization based on material of - * - * (C) Copyright 1999 Linus Torvalds - * (C) Copyright 1999 Johannes Erdfelt - * (C) Copyright 1999 Randy Dunlap - * (C) Copyright 1999 Gregory P. Smith - * - * - * Adapted for U-Boot: - * (C) Copyright 2001 Denis Peter, MPL AG Switzerland - * (C) Copyright 2008, Daniel Hellström, daniel@gaisler.com - * Added AMBA Plug&Play detection of GRUSB, modified interrupt handler. - * Added cache flushes where needed. - * - * 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 - * - * - */ - -/********************************************************************** - * How it works: - * ------------- - * The framelist / Transfer descriptor / Queue Heads are similar like - * in the linux usb_uhci.c. - * - * During initialization, the following skeleton is allocated in init_skel: - * - * framespecific | common chain - * - * framelist[] - * [ 0 ]-----> TD ---------\ - * [ 1 ]-----> TD ----------> TD ------> QH -------> QH -------> QH ---> NULL - * ... TD ---------/ - * [1023]-----> TD --------/ - * - * ^^ ^^ ^^ ^^ ^^ - * 7 TDs for 1 TD for Start of Start of End Chain - * INT (2-128ms) 1ms-INT CTRL Chain BULK Chain - * - * - * Since this is a bootloader, the isochronous transfer descriptor have been removed. - * - * Interrupt Transfers. - * -------------------- - * For Interupt transfers USB_MAX_TEMP_INT_TD Transfer descriptor are available. They - * will be inserted after the appropriate (depending the interval setting) skeleton TD. - * If an interrupt has been detected the dev->irqhandler is called. The status and number - * of transfered bytes is stored in dev->irq_status resp. dev->irq_act_len. If the - * dev->irqhandler returns 0, the interrupt TD is removed and disabled. If an 1 is returned, - * the interrupt TD will be reactivated. - * - * Control Transfers - * ----------------- - * Control Transfers are issued by filling the tmp_td with the appropriate data and connect - * them to the qh_cntrl queue header. Before other control/bulk transfers can be issued, - * the programm has to wait for completion. This does not allows asynchronous data transfer. - * - * Bulk Transfers - * -------------- - * Bulk Transfers are issued by filling the tmp_td with the appropriate data and connect - * them to the qh_bulk queue header. Before other control/bulk transfers can be issued, - * the programm has to wait for completion. This does not allows asynchronous data transfer. - * - * - */ - -#include <common.h> -#include <ambapp.h> -#include <asm/leon.h> -#include <asm/leon3.h> -#include <asm/processor.h> - -#ifdef CONFIG_USB_UHCI - -#include <usb.h> -#include "usb_uhci.h" - -#define USB_MAX_TEMP_TD 128 /* number of temporary TDs for bulk and control transfers */ -#define USB_MAX_TEMP_INT_TD 32 /* number of temporary TDs for Interrupt transfers */ - -extern int leon3_snooping_avail; -/* -#define out16r(address,data) (*(unsigned short *)(address) = \ - (unsigned short)( \ - (((unsigned short)(data)&0xff)<<8) | \ - (((unsigned short)(data)&0xff00)>>8) \ - )) - */ -#define out16r(address,data) _out16r((unsigned int)(address), (unsigned short)(data)) -void _out16r(unsigned int address, unsigned short data) -{ - unsigned short val = (unsigned short)((((unsigned short)(data) & 0xff) - << 8) | (((unsigned short)(data) - & 0xff00) >> 8)); -#ifdef UHCI_DEBUG_REGS - printf("out16r(0x%lx,0x%04x = 0x%04x)\n", address, val, data); -#endif - *(unsigned short *)(address) = val; -} - -#define out32r(address,data) _out32r((unsigned int)(address), (unsigned int)(data)) -void _out32r(unsigned int address, unsigned int data) -{ - unsigned int val = (unsigned int)((((unsigned int)(data) & 0x000000ff) - << 24) | (((unsigned int)(data) & - 0x0000ff00) << 8) | - (((unsigned int)(data) & 0x00ff0000) - >> 8) | (((unsigned int)(data) & - 0xff000000) >> 24)); -#ifdef UHCI_DEBUG_REGS - printf("out32r(0x%lx,0x%lx = 0x%lx)\n", address, val, data); -#endif - *(unsigned int *)address = val; -} - -#define in16r(address) _in16r((unsigned int)(address)) -unsigned short _in16r(unsigned int address) -{ - unsigned short val = sparc_load_reg_cachemiss_word(address); - val = ((val << 8) & 0xff00) | ((val >> 8) & 0xff); -#ifdef UHCI_DEBUG_REGS - printf("in16r(0x%lx): 0x%04x\n", address, val); -#endif - return val; -} - -#define in32r(address) _in32r((unsigned int)(address)) -unsigned int _in32r(unsigned int address) -{ - unsigned int val = sparc_load_reg_cachemiss(address); - val = - ((val << 24) & 0xff000000) | ((val << 8) & 0xff0000) | ((val >> 8) & - 0xff00) | - ((val >> 24) & 0xff); -#ifdef UHCI_DEBUG_REGS - printf("in32r(0x%lx): 0x%08x\n", address, val); -#endif - return val; -} - -#define READ32(address) sparc_load_reg_cachemiss((unsigned int)(address)) - -/*#define USB_UHCI_DEBUG*/ -#undef USB_UHCI_DEBUG - -void usb_show_td(int max); -#ifdef USB_UHCI_DEBUG -void grusb_show_regs(void); -#define USB_UHCI_PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define USB_UHCI_PRINTF(fmt,args...) -#endif - -static int grusb_irq = -1; /* irq vector, if -1 uhci is stopped / reseted */ -unsigned int usb_base_addr; /* base address */ - -static uhci_td_t td_int[8] __attribute__ ((aligned(16))); /* Interrupt Transfer descriptors */ -static uhci_qh_t qh_cntrl __attribute__ ((aligned(16))); /* control Queue Head */ -static uhci_qh_t qh_bulk __attribute__ ((aligned(16))); /* bulk Queue Head */ -static uhci_qh_t qh_end __attribute__ ((aligned(16))); /* end Queue Head */ -static uhci_td_t td_last __attribute__ ((aligned(16))); /* last TD (linked with end chain) */ - -/* temporary tds */ -static uhci_td_t tmp_td[USB_MAX_TEMP_TD] __attribute__ ((aligned(16))); /* temporary bulk/control td's */ -static uhci_td_t tmp_int_td[USB_MAX_TEMP_INT_TD] __attribute__ ((aligned(16))); /* temporary interrupt td's */ - -static unsigned long framelist[1024] __attribute__ ((aligned(0x1000))); /* frame list */ - -static struct virt_root_hub rh; /* struct for root hub */ - -/********************************************************************** - * some forward decleration - */ -int uhci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, - void *buffer, int transfer_len, - struct devrequest *setup); - -/* fill a td with the approproiate data. Link, status, info and buffer - * are used by the USB controller itselfes, dev is used to identify the - * "connected" device - */ -void usb_fill_td(uhci_td_t * td, unsigned long link, unsigned long status, - unsigned long info, unsigned long buffer, unsigned long dev) -{ - td->link = swap_32(link); - td->status = swap_32(status); - if ((info & UHCI_PID) == 0) - info |= USB_PID_OUT; - td->info = swap_32(info); - td->buffer = swap_32(buffer); - td->dev_ptr = dev; -} - -/* fill a qh with the approproiate data. Head and element are used by the USB controller - * itselfes. As soon as a valid dev_ptr is filled, a td chain is connected to the qh. - * Please note, that after completion of the td chain, the entry element is removed / - * marked invalid by the USB controller. - */ -void usb_fill_qh(uhci_qh_t * qh, unsigned long head, unsigned long element) -{ - qh->head = swap_32(head); - qh->element = swap_32(element); - qh->dev_ptr = 0L; -} - -/* get the status of a td->status - */ -unsigned long usb_uhci_td_stat(unsigned long status) -{ - unsigned long result = 0; - result |= (status & TD_CTRL_NAK) ? USB_ST_NAK_REC : 0; - result |= (status & TD_CTRL_STALLED) ? USB_ST_STALLED : 0; - result |= (status & TD_CTRL_DBUFERR) ? USB_ST_BUF_ERR : 0; - result |= (status & TD_CTRL_BABBLE) ? USB_ST_BABBLE_DET : 0; - result |= (status & TD_CTRL_CRCTIMEO) ? USB_ST_CRC_ERR : 0; - result |= (status & TD_CTRL_BITSTUFF) ? USB_ST_BIT_ERR : 0; - result |= (status & TD_CTRL_ACTIVE) ? USB_ST_NOT_PROC : 0; - return result; -} - -/* get the status and the transfered len of a td chain. - * called from the completion handler - */ -int usb_get_td_status(uhci_td_t * td, struct usb_device *dev) -{ - unsigned long temp, info; - unsigned long stat; - uhci_td_t *mytd = td; - - if (dev->devnum == rh.devnum) - return 0; - dev->act_len = 0; - stat = 0; - do { - temp = swap_32((unsigned long)READ32(&mytd->status)); - stat = usb_uhci_td_stat(temp); - info = swap_32((unsigned long)READ32(&mytd->info)); - if (((info & 0xff) != USB_PID_SETUP) && (((info >> 21) & 0x7ff) != 0x7ff) && (temp & 0x7FF) != 0x7ff) { /* if not setup and not null data pack */ - dev->act_len += (temp & 0x7FF) + 1; /* the transfered len is act_len + 1 */ - } - if (stat) { /* status no ok */ - dev->status = stat; - return -1; - } - temp = swap_32((unsigned long)READ32(&mytd->link)); - mytd = (uhci_td_t *) (temp & 0xfffffff0); - } while ((temp & 0x1) == 0); /* process all TDs */ - dev->status = stat; - return 0; /* Ok */ -} - -/*------------------------------------------------------------------- - * LOW LEVEL STUFF - * assembles QHs und TDs for control, bulk and iso - *-------------------------------------------------------------------*/ -int dummy(void) -{ - USB_UHCI_PRINTF("DUMMY\n"); - return 0; -} - -/* Submits a control message. That is a Setup, Data and Status transfer. - * Routine does not wait for completion. - */ -int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, struct devrequest *setup) -{ - unsigned long destination, status; - int maxsze = usb_maxpacket(dev, pipe); - unsigned long dataptr; - int len; - int pktsze; - int i = 0; - - if (!maxsze) { - USB_UHCI_PRINTF - ("uhci_submit_control_urb: pipesize for pipe %lx is zero\n", - pipe); - return -1; - } - if (((pipe >> 8) & 0x7f) == rh.devnum) { - /* this is the root hub -> redirect it */ - return uhci_submit_rh_msg(dev, pipe, buffer, transfer_len, - setup); - } - USB_UHCI_PRINTF("uhci_submit_control start len %x, maxsize %x\n", - transfer_len, maxsze); - /* The "pipe" thing contains the destination in bits 8--18 */ - destination = (pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP; /* Setup stage */ - /* 3 errors */ - status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | (3 << 27); - /* (urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD); */ - /* Build the TD for the control request, try forever, 8 bytes of data */ - usb_fill_td(&tmp_td[i], UHCI_PTR_TERM, status, destination | (7 << 21), - (unsigned long)setup, (unsigned long)dev); -#ifdef DEBUG_EXTRA - { - char *sp = (char *)setup; - printf("SETUP to pipe %lx: %x %x %x %x %x %x %x %x\n", pipe, - sp[0], sp[1], sp[2], sp[3], sp[4], sp[5], sp[6], sp[7]); - } -#endif - dataptr = (unsigned long)buffer; - len = transfer_len; - - /* If direction is "send", change the frame from SETUP (0x2D) - to OUT (0xE1). Else change it from SETUP to IN (0x69). */ - destination = - (pipe & PIPE_DEVEP_MASK) | ((pipe & USB_DIR_IN) == - 0 ? USB_PID_OUT : USB_PID_IN); - while (len > 0) { - /* data stage */ - pktsze = len; - i++; - if (pktsze > maxsze) - pktsze = maxsze; - destination ^= 1 << TD_TOKEN_TOGGLE; /* toggle DATA0/1 */ - usb_fill_td(&tmp_td[i], UHCI_PTR_TERM, status, destination | ((pktsze - 1) << 21), dataptr, (unsigned long)dev); /* Status, pktsze bytes of data */ - tmp_td[i - 1].link = swap_32((unsigned long)&tmp_td[i]); - - dataptr += pktsze; - len -= pktsze; - } - - /* Build the final TD for control status */ - /* It's only IN if the pipe is out AND we aren't expecting data */ - - destination &= ~UHCI_PID; - if (((pipe & USB_DIR_IN) == 0) || (transfer_len == 0)) - destination |= USB_PID_IN; - else - destination |= USB_PID_OUT; - destination |= 1 << TD_TOKEN_TOGGLE; /* End in Data1 */ - i++; - status &= ~TD_CTRL_SPD; - /* no limit on errors on final packet , 0 bytes of data */ - usb_fill_td(&tmp_td[i], UHCI_PTR_TERM, status | TD_CTRL_IOC, - destination | (UHCI_NULL_DATA_SIZE << 21), 0, - (unsigned long)dev); - tmp_td[i - 1].link = swap_32((unsigned long)&tmp_td[i]); /* queue status td */ - /* usb_show_td(i+1); */ - USB_UHCI_PRINTF("uhci_submit_control end (%d tmp_tds used)\n", i); - /* first mark the control QH element terminated */ - qh_cntrl.element = 0xffffffffL; - /* set qh active */ - qh_cntrl.dev_ptr = (unsigned long)dev; - /* fill in tmp_td_chain */ - dummy(); - qh_cntrl.element = swap_32((unsigned long)&tmp_td[0]); - return 0; -} - -/*------------------------------------------------------------------- - * Prepare TDs for bulk transfers. - */ -int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len) -{ - unsigned long destination, status, info; - unsigned long dataptr; - int maxsze = usb_maxpacket(dev, pipe); - int len; - int i = 0; - - if (transfer_len < 0) { - printf("Negative transfer length in submit_bulk\n"); - return -1; - } - if (!maxsze) - return -1; - /* The "pipe" thing contains the destination in bits 8--18. */ - destination = (pipe & PIPE_DEVEP_MASK) | usb_packetid(pipe); - /* 3 errors */ - status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | (3 << 27); - /* ((urb->transfer_flags & USB_DISABLE_SPD) ? 0 : TD_CTRL_SPD) | (3 << 27); */ - /* Build the TDs for the bulk request */ - len = transfer_len; - dataptr = (unsigned long)buffer; - do { - int pktsze = len; - if (pktsze > maxsze) - pktsze = maxsze; - /* pktsze bytes of data */ - info = - destination | (((pktsze - 1) & UHCI_NULL_DATA_SIZE) << 21) | - (usb_gettoggle - (dev, usb_pipeendpoint(pipe), - usb_pipeout(pipe)) << TD_TOKEN_TOGGLE); - - if ((len - pktsze) == 0) - status |= TD_CTRL_IOC; /* last one generates INT */ - - usb_fill_td(&tmp_td[i], UHCI_PTR_TERM, status, info, dataptr, (unsigned long)dev); /* Status, pktsze bytes of data */ - if (i > 0) - tmp_td[i - 1].link = swap_32((unsigned long)&tmp_td[i]); - i++; - dataptr += pktsze; - len -= pktsze; - usb_dotoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)); - } while (len > 0); - /* first mark the bulk QH element terminated */ - qh_bulk.element = 0xffffffffL; - /* set qh active */ - qh_bulk.dev_ptr = (unsigned long)dev; - /* fill in tmp_td_chain */ - qh_bulk.element = swap_32((unsigned long)&tmp_td[0]); - return 0; -} - -/* search a free interrupt td - */ -uhci_td_t *uhci_alloc_int_td(void) -{ - int i; - for (i = 0; i < USB_MAX_TEMP_INT_TD; i++) { - if (tmp_int_td[i].dev_ptr == 0) /* no device assigned -> free TD */ - return &tmp_int_td[i]; - } - return NULL; -} - -/*------------------------------------------------------------------- - * submits USB interrupt (ie. polling ;-) - */ -int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, int interval) -{ - int nint, n; - unsigned long status, destination; - unsigned long info, tmp; - uhci_td_t *mytd; - if (interval < 0 || interval >= 256) - return -1; - - if (interval == 0) - nint = 0; - else { - for (nint = 0, n = 1; nint <= 8; nint++, n += n) { /* round interval down to 2^n */ - if (interval < n) { - interval = n / 2; - break; - } - } - nint--; - } - - USB_UHCI_PRINTF("Rounded interval to %i, chain %i\n", interval, nint); - mytd = uhci_alloc_int_td(); - if (mytd == NULL) { - printf("No free INT TDs found\n"); - return -1; - } - status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_IOC | (3 << 27); -/* (urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (3 << 27); -*/ - - destination = - (pipe & PIPE_DEVEP_MASK) | usb_packetid(pipe) | - (((transfer_len - 1) & 0x7ff) << 21); - - info = - destination | - (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) << - TD_TOKEN_TOGGLE); - tmp = swap_32(td_int[nint].link); - usb_fill_td(mytd, tmp, status, info, (unsigned long)buffer, - (unsigned long)dev); - /* Link it */ - tmp = swap_32((unsigned long)mytd); - td_int[nint].link = tmp; - - usb_dotoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)); - - return 0; -} - -/********************************************************************** - * Low Level functions - */ - -void reset_hc(void) -{ - - /* Global reset for 100ms */ - out16r(usb_base_addr + USBPORTSC1, 0x0204); - out16r(usb_base_addr + USBPORTSC2, 0x0204); - out16r(usb_base_addr + USBCMD, USBCMD_GRESET | USBCMD_RS); - /* Turn off all interrupts */ - out16r(usb_base_addr + USBINTR, 0); - wait_ms(50); - out16r(usb_base_addr + USBCMD, 0); - wait_ms(10); -} - -void start_hc(void) -{ - int timeout = 1000; - - while (in16r(usb_base_addr + USBCMD) & USBCMD_HCRESET) { - if (!--timeout) { - printf("USBCMD_HCRESET timed out!\n"); - break; - } - } - /* Turn on all interrupts */ - out16r(usb_base_addr + USBINTR, - USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP); - /* Start at frame 0 */ - out16r(usb_base_addr + USBFRNUM, 0); - /* set Framebuffer base address */ - out32r(usb_base_addr + USBFLBASEADD, (unsigned long)&framelist); - /* Run and mark it configured with a 64-byte max packet */ - out16r(usb_base_addr + USBCMD, USBCMD_RS | USBCMD_CF | USBCMD_MAXP); -} - -/* Initialize the skeleton - */ -void usb_init_skel(void) -{ - unsigned long temp; - int n; - - for (n = 0; n < USB_MAX_TEMP_INT_TD; n++) - tmp_int_td[n].dev_ptr = 0L; /* no devices connected */ - /* last td */ - usb_fill_td(&td_last, UHCI_PTR_TERM, TD_CTRL_IOC, USB_PID_OUT, 0, 0L); - /* usb_fill_td(&td_last,UHCI_PTR_TERM,0,0,0); */ - /* End Queue Header */ - usb_fill_qh(&qh_end, UHCI_PTR_TERM, (unsigned long)&td_last); - /* Bulk Queue Header */ - temp = (unsigned long)&qh_end; - usb_fill_qh(&qh_bulk, temp | UHCI_PTR_QH, UHCI_PTR_TERM); - /* Control Queue Header */ - temp = (unsigned long)&qh_bulk; - usb_fill_qh(&qh_cntrl, temp | UHCI_PTR_QH, UHCI_PTR_TERM); - /* 1ms Interrupt td */ - temp = (unsigned long)&qh_cntrl; - usb_fill_td(&td_int[0], temp | UHCI_PTR_QH, 0, USB_PID_OUT, 0, 0L); - temp = (unsigned long)&td_int[0]; - for (n = 1; n < 8; n++) - usb_fill_td(&td_int[n], temp, 0, USB_PID_OUT, 0, 0L); - for (n = 0; n < 1024; n++) { - /* link all framelist pointers to one of the interrupts */ - int m, o; - if ((n & 127) == 127) - framelist[n] = swap_32((unsigned long)&td_int[0]); - else - for (o = 1, m = 2; m <= 128; o++, m += m) - if ((n & (m - 1)) == ((m - 1) / 2)) - framelist[n] = - swap_32((unsigned long)&td_int[o]); - - } -} - -/* check the common skeleton for completed transfers, and update the status - * of the "connected" device. Called from the IRQ routine. - */ -void usb_check_skel(void) -{ - struct usb_device *dev; - /* start with the control qh */ - if (qh_cntrl.dev_ptr != 0) { /* it's a device assigned check if this caused IRQ */ - dev = (struct usb_device *)qh_cntrl.dev_ptr; - /* Flush cache now that hardware updated DATA and TDs/QHs */ - if (!leon3_snooping_avail) - sparc_dcache_flush_all(); - usb_get_td_status(&tmp_td[0], dev); /* update status */ - if (!(dev->status & USB_ST_NOT_PROC)) { /* is not active anymore, disconnect devices */ - qh_cntrl.dev_ptr = 0; - } - } - /* now process the bulk */ - if (qh_bulk.dev_ptr != 0) { /* it's a device assigned check if this caused IRQ */ - dev = (struct usb_device *)qh_bulk.dev_ptr; - /* Flush cache now that hardware updated DATA and TDs/QHs */ - if (!leon3_snooping_avail) - sparc_dcache_flush_all(); - usb_get_td_status(&tmp_td[0], dev); /* update status */ - if (!(dev->status & USB_ST_NOT_PROC)) { /* is not active anymore, disconnect devices */ - qh_bulk.dev_ptr = 0; - } - } -} - -/* check the interrupt chain, ubdate the status of the appropriate device, - * call the appropriate irqhandler and reactivate the TD if the irqhandler - * returns with 1 - */ -void usb_check_int_chain(void) -{ - int i, res; - unsigned long link, status; - struct usb_device *dev; - uhci_td_t *td, *prevtd; - - for (i = 0; i < 8; i++) { - prevtd = &td_int[i]; /* the first previous td is the skeleton td */ - link = swap_32(READ32(&td_int[i].link)) & 0xfffffff0; /* next in chain */ - td = (uhci_td_t *) link; /* assign it */ - /* all interrupt TDs are finally linked to the td_int[0]. - * so we process all until we find the td_int[0]. - * if int0 chain points to a QH, we're also done - */ - while (((i > 0) && (link != (unsigned long)&td_int[0])) || - ((i == 0) - && !(swap_32(READ32(&td->link)) & UHCI_PTR_QH))) { - /* check if a device is assigned with this td */ - status = swap_32(READ32(&td->status)); - if ((td->dev_ptr != 0L) && !(status & TD_CTRL_ACTIVE)) { - /* td is not active and a device is assigned -> call irqhandler */ - dev = (struct usb_device *)td->dev_ptr; - dev->irq_act_len = ((status & 0x7FF) == 0x7FF) ? 0 : (status & 0x7FF) + 1; /* transfered length */ - dev->irq_status = usb_uhci_td_stat(status); /* get status */ - res = dev->irq_handle(dev); /* call irqhandler */ - if (res == 1) { - /* reactivate */ - status |= TD_CTRL_ACTIVE; - td->status = swap_32(status); - prevtd = td; /* previous td = this td */ - } else { - prevtd->link = READ32(&td->link); /* link previous td directly to the nex td -> unlinked */ - /* remove device pointer */ - td->dev_ptr = 0L; - } - } /* if we call the irq handler */ - link = swap_32(READ32(&td->link)) & 0xfffffff0; /* next in chain */ - td = (uhci_td_t *) link; /* assign it */ - } /* process all td in this int chain */ - } /* next interrupt chain */ -} - -/* usb interrupt service routine. - */ -void handle_usb_interrupt(void) -{ - unsigned short status; - static int error = 0; - - /* - * Read the interrupt status, and write it back to clear the - * interrupt cause - */ - - status = in16r(usb_base_addr + USBSTS); - - if (!status) /* shared interrupt, not mine */ - return; - if (status != 1) { - /* remove host controller halted state */ - if ((status & (USBSTS_HCPE | USBSTS_HCH)) == - (USBSTS_HCPE | USBSTS_HCH)) { - /* Stop due to bug in driver, or hardware */ - out16r(usb_base_addr + USBSTS, status); - out16r(usb_base_addr + USBCMD, - USBCMD_HCRESET | USBCMD_GRESET); - printf - ("GRUSB: HW detected error(s) in USB Descriptors (STS: 0x%x)\n", - status); - usb_show_td(8); - return; - } else if ((status & 0x20) - && ((in16r(usb_base_addr + USBCMD) & USBCMD_RS) == - 0)) { - if (error < 10) { - out16r(usb_base_addr + USBCMD, - USBCMD_RS | in16r(usb_base_addr + - USBCMD)); - error++; - } - } else - error = 0; - } - usb_check_int_chain(); /* call interrupt handlers for int tds */ - usb_check_skel(); /* call completion handler for common transfer routines */ - out16r(usb_base_addr + USBSTS, status); -} - -/* init uhci - */ -int usb_lowlevel_init(void) -{ - unsigned char temp; - ambapp_ahbdev ahbdev; - - /* Find GRUSB core using AMBA Plug&Play information */ - if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_UHCI, &ahbdev) != 1) { - printf("USB UHCI: Failed to find GRUSB controller\n"); - return -1; - } - usb_base_addr = ahbdev.address[0]; - grusb_irq = ahbdev.irq; - /* - usb_base_addr = 0xfffa0000; - grusb_irq = 10; - */ -#ifdef USB_UHCI_DEBUG - grusb_show_regs(); -#endif - memset(td_int, 0, sizeof(td_int)); - memset(tmp_td, 0, sizeof(tmp_td)); - memset(tmp_int_td, 0, sizeof(tmp_int_td)); - memset(&qh_cntrl, 0, sizeof(qh_cntrl)); - memset(&qh_end, 0, sizeof(qh_end)); - memset(&td_last, 0, sizeof(td_last)); - - irq_free_handler(grusb_irq); - USB_UHCI_PRINTF("GRUSB: at 0x%lx irq %d\n", usb_base_addr, grusb_irq); - rh.devnum = 0; - usb_init_skel(); - reset_hc(); - start_hc(); - irq_install_handler(grusb_irq, - (interrupt_handler_t *) handle_usb_interrupt, NULL); - return 0; -} - -/* stop uhci - */ -int usb_lowlevel_stop(void) -{ - if (grusb_irq == -1) - return 1; - irq_free_handler(grusb_irq); - reset_hc(); - grusb_irq = -1; - return 0; -} - -/******************************************************************************************* - * Virtual Root Hub - * Since the uhci does not have a real HUB, we simulate one ;-) - */ -#undef USB_RH_DEBUG - -#ifdef USB_RH_DEBUG -#define USB_RH_PRINTF(fmt,args...) printf (fmt ,##args) -static void usb_display_wValue(unsigned short wValue, unsigned short wIndex); -static void usb_display_Req(unsigned short req); -#else -#define USB_RH_PRINTF(fmt,args...) -static void usb_display_wValue(unsigned short wValue, unsigned short wIndex) -{ -} -static void usb_display_Req(unsigned short req) -{ -} -#endif - -static unsigned char root_hub_dev_des[] = { - 0x12, /* __u8 bLength; */ - 0x01, /* __u8 bDescriptorType; Device */ - 0x00, /* __u16 bcdUSB; v1.0 */ - 0x01, - 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ - 0x00, /* __u8 bDeviceSubClass; */ - 0x00, /* __u8 bDeviceProtocol; */ - 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ - 0x00, /* __u16 idVendor; */ - 0x00, - 0x00, /* __u16 idProduct; */ - 0x00, - 0x00, /* __u16 bcdDevice; */ - 0x00, - 0x01, /* __u8 iManufacturer; */ - 0x00, /* __u8 iProduct; */ - 0x00, /* __u8 iSerialNumber; */ - 0x01 /* __u8 bNumConfigurations; */ -}; - -/* Configuration descriptor */ -static unsigned char root_hub_config_des[] = { - 0x09, /* __u8 bLength; */ - 0x02, /* __u8 bDescriptorType; Configuration */ - 0x19, /* __u16 wTotalLength; */ - 0x00, - 0x01, /* __u8 bNumInterfaces; */ - 0x01, /* __u8 bConfigurationValue; */ - 0x00, /* __u8 iConfiguration; */ - 0x40, /* __u8 bmAttributes; - Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */ - 0x00, /* __u8 MaxPower; */ - - /* interface */ - 0x09, /* __u8 if_bLength; */ - 0x04, /* __u8 if_bDescriptorType; Interface */ - 0x00, /* __u8 if_bInterfaceNumber; */ - 0x00, /* __u8 if_bAlternateSetting; */ - 0x01, /* __u8 if_bNumEndpoints; */ - 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ - 0x00, /* __u8 if_bInterfaceSubClass; */ - 0x00, /* __u8 if_bInterfaceProtocol; */ - 0x00, /* __u8 if_iInterface; */ - - /* endpoint */ - 0x07, /* __u8 ep_bLength; */ - 0x05, /* __u8 ep_bDescriptorType; Endpoint */ - 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ - 0x03, /* __u8 ep_bmAttributes; Interrupt */ - 0x08, /* __u16 ep_wMaxPacketSize; 8 Bytes */ - 0x00, - 0xff /* __u8 ep_bInterval; 255 ms */ -}; - -static unsigned char root_hub_hub_des[] = { - 0x09, /* __u8 bLength; */ - 0x29, /* __u8 bDescriptorType; Hub-descriptor */ - 0x02, /* __u8 bNbrPorts; */ - 0x00, /* __u16 wHubCharacteristics; */ - 0x00, - 0x01, /* __u8 bPwrOn2pwrGood; 2ms */ - 0x00, /* __u8 bHubContrCurrent; 0 mA */ - 0x00, /* __u8 DeviceRemovable; *** 7 Ports max *** */ - 0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */ -}; - -static unsigned char root_hub_str_index0[] = { - 0x04, /* __u8 bLength; */ - 0x03, /* __u8 bDescriptorType; String-descriptor */ - 0x09, /* __u8 lang ID */ - 0x04, /* __u8 lang ID */ -}; - -static unsigned char root_hub_str_index1[] = { - 28, /* __u8 bLength; */ - 0x03, /* __u8 bDescriptorType; String-descriptor */ - 'U', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'H', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'C', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'I', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - ' ', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'R', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'o', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'o', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 't', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - ' ', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'H', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'u', /* __u8 Unicode */ - 0, /* __u8 Unicode */ - 'b', /* __u8 Unicode */ - 0, /* __u8 Unicode */ -}; - -/* - * Root Hub Control Pipe (interrupt Pipes are not supported) - */ - -int uhci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, struct devrequest *cmd) -{ - void *data = buffer; - int leni = transfer_len; - int len = 0; - int status = 0; - int stat = 0; - int i; - - unsigned short cstatus; - - unsigned short bmRType_bReq; - unsigned short wValue; - unsigned short wIndex; - unsigned short wLength; - - if (usb_pipeint(pipe)) { - printf("Root-Hub submit IRQ: NOT implemented\n"); - return 0; - } - bmRType_bReq = cmd->requesttype | cmd->request << 8; - wValue = swap_16(cmd->value); - wIndex = swap_16(cmd->index); - wLength = swap_16(cmd->length); - usb_display_Req(bmRType_bReq); - for (i = 0; i < 8; i++) - rh.c_p_r[i] = 0; - USB_RH_PRINTF("Root-Hub: adr: %2x cmd(%1x): %02x%02x %04x %04x %04x\n", - dev->devnum, 8, cmd->requesttype, cmd->request, wValue, - wIndex, wLength); - - switch (bmRType_bReq) { - /* Request Destination: - without flags: Device, - RH_INTERFACE: interface, - RH_ENDPOINT: endpoint, - RH_CLASS means HUB here, - RH_OTHER | RH_CLASS almost ever means HUB_PORT here - */ - - case RH_GET_STATUS: - *(unsigned short *)data = swap_16(1); - len = 2; - break; - case RH_GET_STATUS | RH_INTERFACE: - *(unsigned short *)data = swap_16(0); - len = 2; - break; - case RH_GET_STATUS | RH_ENDPOINT: - *(unsigned short *)data = swap_16(0); - len = 2; - break; - case RH_GET_STATUS | RH_CLASS: - *(unsigned long *)data = swap_32(0); - len = 4; - break; /* hub power ** */ - case RH_GET_STATUS | RH_OTHER | RH_CLASS: - - status = in16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1)); - cstatus = ((status & USBPORTSC_CSC) >> (1 - 0)) | - ((status & USBPORTSC_PEC) >> (3 - 1)) | - (rh.c_p_r[wIndex - 1] << (0 + 4)); - status = (status & USBPORTSC_CCS) | ((status & USBPORTSC_PE) >> (2 - 1)) | ((status & USBPORTSC_SUSP) >> (12 - 2)) | ((status & USBPORTSC_PR) >> (9 - 4)) | (1 << 8) | /* power on ** */ - ((status & USBPORTSC_LSDA) << (-8 + 9)); - - *(unsigned short *)data = swap_16(status); - *(unsigned short *)(data + 2) = swap_16(cstatus); - len = 4; - break; - case RH_CLEAR_FEATURE | RH_ENDPOINT: - switch (wValue) { - case (RH_ENDPOINT_STALL): - len = 0; - break; - } - break; - - case RH_CLEAR_FEATURE | RH_CLASS: - switch (wValue) { - case (RH_C_HUB_OVER_CURRENT): - len = 0; /* hub power over current ** */ - break; - } - break; - - case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: - usb_display_wValue(wValue, wIndex); - switch (wValue) { - case (RH_PORT_ENABLE): - status = - in16r(usb_base_addr + USBPORTSC1 + - 2 * (wIndex - 1)); - status = (status & 0xfff5) & ~USBPORTSC_PE; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - len = 0; - break; - case (RH_PORT_SUSPEND): - status = - in16r(usb_base_addr + USBPORTSC1 + - 2 * (wIndex - 1)); - status = (status & 0xfff5) & ~USBPORTSC_SUSP; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - len = 0; - break; - case (RH_PORT_POWER): - len = 0; /* port power ** */ - break; - case (RH_C_PORT_CONNECTION): - status = - in16r(usb_base_addr + USBPORTSC1 + - 2 * (wIndex - 1)); - status = (status & 0xfff5) | USBPORTSC_CSC; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - len = 0; - break; - case (RH_C_PORT_ENABLE): - status = - in16r(usb_base_addr + USBPORTSC1 + - 2 * (wIndex - 1)); - status = (status & 0xfff5) | USBPORTSC_PEC; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - len = 0; - break; - case (RH_C_PORT_SUSPEND): -/*** WR_RH_PORTSTAT(RH_PS_PSSC); */ - len = 0; - break; - case (RH_C_PORT_OVER_CURRENT): - len = 0; - break; - case (RH_C_PORT_RESET): - rh.c_p_r[wIndex - 1] = 0; - len = 0; - break; - } - break; - case RH_SET_FEATURE | RH_OTHER | RH_CLASS: - usb_display_wValue(wValue, wIndex); - switch (wValue) { - case (RH_PORT_SUSPEND): - status = - in16r(usb_base_addr + USBPORTSC1 + - 2 * (wIndex - 1)); - status = (status & 0xfff5) | USBPORTSC_SUSP; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - len = 0; - break; - case (RH_PORT_RESET): - status = - in16r(usb_base_addr + USBPORTSC1 + - 2 * (wIndex - 1)); - status = (status & 0xfff5) | USBPORTSC_PR; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - wait_ms(10); - status = (status & 0xfff5) & ~USBPORTSC_PR; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - udelay(10); - status = (status & 0xfff5) | USBPORTSC_PE; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - wait_ms(10); - status = (status & 0xfff5) | 0xa; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - len = 0; - break; - case (RH_PORT_POWER): - len = 0; /* port power ** */ - break; - case (RH_PORT_ENABLE): - status = - in16r(usb_base_addr + USBPORTSC1 + - 2 * (wIndex - 1)); - status = (status & 0xfff5) | USBPORTSC_PE; - out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1), - status); - len = 0; - break; - } - break; - - case RH_SET_ADDRESS: - rh.devnum = wValue; - len = 0; - break; - case RH_GET_DESCRIPTOR: - switch ((wValue & 0xff00) >> 8) { - case (0x01): /* device descriptor */ - i = sizeof(root_hub_config_des); - status = i > wLength ? wLength : i; - len = leni > status ? status : leni; - memcpy(data, root_hub_dev_des, len); - break; - case (0x02): /* configuration descriptor */ - i = sizeof(root_hub_config_des); - status = i > wLength ? wLength : i; - len = leni > status ? status : leni; - memcpy(data, root_hub_config_des, len); - break; - case (0x03): /*string descriptors */ - if (wValue == 0x0300) { - i = sizeof(root_hub_str_index0); - status = i > wLength ? wLength : i; - len = leni > status ? status : leni; - memcpy(data, root_hub_str_index0, len); - break; - } - if (wValue == 0x0301) { - i = sizeof(root_hub_str_index1); - status = i > wLength ? wLength : i; - len = leni > status ? status : leni; - memcpy(data, root_hub_str_index1, len); - break; - } - stat = USB_ST_STALLED; - } - break; - - case RH_GET_DESCRIPTOR | RH_CLASS: - root_hub_hub_des[2] = 2; - i = sizeof(root_hub_hub_des); - status = i > wLength ? wLength : i; - len = leni > status ? status : leni; - memcpy(data, root_hub_hub_des, len); - break; - case RH_GET_CONFIGURATION: - *(unsigned char *)data = 0x01; - len = 1; - break; - case RH_SET_CONFIGURATION: - len = 0; - break; - default: - stat = USB_ST_STALLED; - } - USB_RH_PRINTF("Root-Hub stat %lx port1: %x port2: %x\n\n", stat, - in16r(usb_base_addr + USBPORTSC1), - in16r(usb_base_addr + USBPORTSC2)); - dev->act_len = len; - dev->status = stat; - return stat; - -} - -/******************************************************************************** - * Some Debug Routines - */ - -#ifdef USB_RH_DEBUG - -static void usb_display_Req(unsigned short req) -{ - USB_RH_PRINTF("- Root-Hub Request: "); - switch (req) { - case RH_GET_STATUS: - USB_RH_PRINTF("Get Status "); - break; - case RH_GET_STATUS | RH_INTERFACE: - USB_RH_PRINTF("Get Status Interface "); - break; - case RH_GET_STATUS | RH_ENDPOINT: - USB_RH_PRINTF("Get Status Endpoint "); - break; - case RH_GET_STATUS | RH_CLASS: - USB_RH_PRINTF("Get Status Class"); - break; /* hub power ** */ - case RH_GET_STATUS | RH_OTHER | RH_CLASS: - USB_RH_PRINTF("Get Status Class Others"); - break; - case RH_CLEAR_FEATURE | RH_ENDPOINT: - USB_RH_PRINTF("Clear Feature Endpoint "); - break; - case RH_CLEAR_FEATURE | RH_CLASS: - USB_RH_PRINTF("Clear Feature Class "); - break; - case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: - USB_RH_PRINTF("Clear Feature Other Class "); - break; - case RH_SET_FEATURE | RH_OTHER | RH_CLASS: - USB_RH_PRINTF("Set Feature Other Class "); - break; - case RH_SET_ADDRESS: - USB_RH_PRINTF("Set Address "); - break; - case RH_GET_DESCRIPTOR: - USB_RH_PRINTF("Get Descriptor "); - break; - case RH_GET_DESCRIPTOR | RH_CLASS: - USB_RH_PRINTF("Get Descriptor Class "); - break; - case RH_GET_CONFIGURATION: - USB_RH_PRINTF("Get Configuration "); - break; - case RH_SET_CONFIGURATION: - USB_RH_PRINTF("Get Configuration "); - break; - default: - USB_RH_PRINTF("****UNKNOWN**** 0x%04X ", req); - } - USB_RH_PRINTF("\n"); - -} - -static void usb_display_wValue(unsigned short wValue, unsigned short wIndex) -{ - switch (wValue) { - case (RH_PORT_ENABLE): - USB_RH_PRINTF("Root-Hub: Enable Port %d\n", wIndex); - break; - case (RH_PORT_SUSPEND): - USB_RH_PRINTF("Root-Hub: Suspend Port %d\n", wIndex); - break; - case (RH_PORT_POWER): - USB_RH_PRINTF("Root-Hub: Port Power %d\n", wIndex); - break; - case (RH_C_PORT_CONNECTION): - USB_RH_PRINTF("Root-Hub: C Port Connection Port %d\n", wIndex); - break; - case (RH_C_PORT_ENABLE): - USB_RH_PRINTF("Root-Hub: C Port Enable Port %d\n", wIndex); - break; - case (RH_C_PORT_SUSPEND): - USB_RH_PRINTF("Root-Hub: C Port Suspend Port %d\n", wIndex); - break; - case (RH_C_PORT_OVER_CURRENT): - USB_RH_PRINTF("Root-Hub: C Port Over Current Port %d\n", - wIndex); - break; - case (RH_C_PORT_RESET): - USB_RH_PRINTF("Root-Hub: C Port reset Port %d\n", wIndex); - break; - default: - USB_RH_PRINTF("Root-Hub: unknown %x %x\n", wValue, wIndex); - break; - } -} - -#endif - -/*#ifdef USB_UHCI_DEBUG*/ - -static int usb_display_td(uhci_td_t * td) -{ - unsigned long tmp; - int valid; - - printf("TD at %p:\n", td); - - tmp = swap_32(READ32(&td->link)); - printf("Link points to 0x%08lX, %s first, %s, %s\n", tmp & 0xfffffff0, - ((tmp & 0x4) == 0x4) ? "Depth" : "Breath", - ((tmp & 0x2) == 0x2) ? "QH" : "TD", - ((tmp & 0x1) == 0x1) ? "invalid" : "valid"); - valid = ((tmp & 0x1) == 0x0); - tmp = swap_32(READ32(&td->status)); - printf - (" %s %ld Errors %s %s %s \n %s %s %s %s %s %s\n Len 0x%lX\n", - (((tmp >> 29) & 0x1) == 0x1) ? "SPD Enable" : "SPD Disable", - ((tmp >> 28) & 0x3), - (((tmp >> 26) & 0x1) == 0x1) ? "Low Speed" : "Full Speed", - (((tmp >> 25) & 0x1) == 0x1) ? "ISO " : "", - (((tmp >> 24) & 0x1) == 0x1) ? "IOC " : "", - (((tmp >> 23) & 0x1) == 0x1) ? "Active " : "Inactive ", - (((tmp >> 22) & 0x1) == 0x1) ? "Stalled" : "", - (((tmp >> 21) & 0x1) == 0x1) ? "Data Buffer Error" : "", - (((tmp >> 20) & 0x1) == 0x1) ? "Babble" : "", - (((tmp >> 19) & 0x1) == 0x1) ? "NAK" : "", - (((tmp >> 18) & 0x1) == 0x1) ? "Bitstuff Error" : "", - (tmp & 0x7ff)); - tmp = swap_32(READ32(&td->info)); - printf(" MaxLen 0x%lX\n", ((tmp >> 21) & 0x7FF)); - printf(" %sEndpoint 0x%lX Dev Addr 0x%lX PID 0x%lX\n", - ((tmp >> 19) & 0x1) == 0x1 ? "TOGGLE " : "", ((tmp >> 15) & 0xF), - ((tmp >> 8) & 0x7F), tmp & 0xFF); - tmp = swap_32(READ32(&td->buffer)); - printf(" Buffer 0x%08lX\n", tmp); - printf(" DEV %08lX\n", td->dev_ptr); - return valid; -} - -void usb_show_td(int max) -{ - int i; - if (max > 0) { - for (i = 0; i < max; i++) { - usb_display_td(&tmp_td[i]); - } - } else { - i = 0; - do { - printf("tmp_td[%d]\n", i); - } while (usb_display_td(&tmp_td[i++])); - } -} - -void grusb_show_regs(void) -{ - unsigned int tmp; - - tmp = in16r(usb_base_addr + USBCMD); - printf(" USBCMD: 0x%04x\n", tmp); - tmp = in16r(usb_base_addr + USBSTS); - printf(" USBSTS: 0x%04x\n", tmp); - tmp = in16r(usb_base_addr + USBINTR); - printf(" USBINTR: 0x%04x\n", tmp); - tmp = in16r(usb_base_addr + USBFRNUM); - printf(" FRNUM: 0x%04x\n", tmp); - tmp = in32r(usb_base_addr + USBFLBASEADD); - printf(" FLBASEADD: 0x%08x\n", tmp); - tmp = in16r(usb_base_addr + USBSOF); - printf(" SOFMOD: 0x%04x\n", tmp); - tmp = in16r(usb_base_addr + USBPORTSC1); - printf(" PORTSC1: 0x%04x\n", tmp); -} - -/*#endif*/ -#endif /* CONFIG_USB_UHCI */ - -/* EOF */ diff --git a/cpu/leon3/usb_uhci.h b/cpu/leon3/usb_uhci.h deleted file mode 100644 index bf572a6..0000000 --- a/cpu/leon3/usb_uhci.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - * (C) Copyright 2001 - * Denis Peter, MPL AG Switzerland - * - * 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 - * - * Note: Part of this code has been derived from linux - * - */ -#ifndef _USB_UHCI_H_ -#define _USB_UHCI_H_ - -/* Command register */ -#define USBCMD 0 -#define USBCMD_RS 0x0001 /* Run/Stop */ -#define USBCMD_HCRESET 0x0002 /* Host reset */ -#define USBCMD_GRESET 0x0004 /* Global reset */ -#define USBCMD_EGSM 0x0008 /* Global Suspend Mode */ -#define USBCMD_FGR 0x0010 /* Force Global Resume */ -#define USBCMD_SWDBG 0x0020 /* SW Debug mode */ -#define USBCMD_CF 0x0040 /* Config Flag (sw only) */ -#define USBCMD_MAXP 0x0080 /* Max Packet (0 = 32, 1 = 64) */ - -/* Status register */ -#define USBSTS 2 -#define USBSTS_USBINT 0x0001 /* Interrupt due to IOC */ -#define USBSTS_ERROR 0x0002 /* Interrupt due to error */ -#define USBSTS_RD 0x0004 /* Resume Detect */ -#define USBSTS_HSE 0x0008 /* Host System Error - basically PCI problems */ -#define USBSTS_HCPE 0x0010 /* Host Controller Process Error - the scripts were buggy */ -#define USBSTS_HCH 0x0020 /* HC Halted */ - -/* Interrupt enable register */ -#define USBINTR 4 -#define USBINTR_TIMEOUT 0x0001 /* Timeout/CRC error enable */ -#define USBINTR_RESUME 0x0002 /* Resume interrupt enable */ -#define USBINTR_IOC 0x0004 /* Interrupt On Complete enable */ -#define USBINTR_SP 0x0008 /* Short packet interrupt enable */ - -#define USBFRNUM 6 -#define USBFLBASEADD 8 -#define USBSOF 12 - -/* USB port status and control registers */ -#define USBPORTSC1 16 -#define USBPORTSC2 18 -#define USBPORTSC_CCS 0x0001 /* Current Connect Status ("device present") */ -#define USBPORTSC_CSC 0x0002 /* Connect Status Change */ -#define USBPORTSC_PE 0x0004 /* Port Enable */ -#define USBPORTSC_PEC 0x0008 /* Port Enable Change */ -#define USBPORTSC_LS 0x0030 /* Line Status */ -#define USBPORTSC_RD 0x0040 /* Resume Detect */ -#define USBPORTSC_LSDA 0x0100 /* Low Speed Device Attached */ -#define USBPORTSC_PR 0x0200 /* Port Reset */ -#define USBPORTSC_SUSP 0x1000 /* Suspend */ - -/* Legacy support register */ -#define USBLEGSUP 0xc0 -#define USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */ - -#define UHCI_NULL_DATA_SIZE 0x7ff /* for UHCI controller TD */ -#define UHCI_PID 0xff /* PID MASK */ - -#define UHCI_PTR_BITS 0x000F -#define UHCI_PTR_TERM 0x0001 -#define UHCI_PTR_QH 0x0002 -#define UHCI_PTR_DEPTH 0x0004 - -/* for TD <status>: */ -#define TD_CTRL_SPD (1 << 29) /* Short Packet Detect */ -#define TD_CTRL_C_ERR_MASK (3 << 27) /* Error Counter bits */ -#define TD_CTRL_LS (1 << 26) /* Low Speed Device */ -#define TD_CTRL_IOS (1 << 25) /* Isochronous Select */ -#define TD_CTRL_IOC (1 << 24) /* Interrupt on Complete */ -#define TD_CTRL_ACTIVE (1 << 23) /* TD Active */ -#define TD_CTRL_STALLED (1 << 22) /* TD Stalled */ -#define TD_CTRL_DBUFERR (1 << 21) /* Data Buffer Error */ -#define TD_CTRL_BABBLE (1 << 20) /* Babble Detected */ -#define TD_CTRL_NAK (1 << 19) /* NAK Received */ -#define TD_CTRL_CRCTIMEO (1 << 18) /* CRC/Time Out Error */ -#define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */ -#define TD_CTRL_ACTLEN_MASK 0x7ff /* actual length, encoded as n - 1 */ - -#define TD_CTRL_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \ - TD_CTRL_BABBLE | TD_CTRL_CRCTIME | TD_CTRL_BITSTUFF) - -#define TD_TOKEN_TOGGLE 19 - -/* ------------------------------------------------------------------------------------ - Virtual Root HUB - ------------------------------------------------------------------------------------ */ -/* destination of request */ -#define RH_INTERFACE 0x01 -#define RH_ENDPOINT 0x02 -#define RH_OTHER 0x03 - -#define RH_CLASS 0x20 -#define RH_VENDOR 0x40 - -/* Requests: bRequest << 8 | bmRequestType */ -#define RH_GET_STATUS 0x0080 -#define RH_CLEAR_FEATURE 0x0100 -#define RH_SET_FEATURE 0x0300 -#define RH_SET_ADDRESS 0x0500 -#define RH_GET_DESCRIPTOR 0x0680 -#define RH_SET_DESCRIPTOR 0x0700 -#define RH_GET_CONFIGURATION 0x0880 -#define RH_SET_CONFIGURATION 0x0900 -#define RH_GET_STATE 0x0280 -#define RH_GET_INTERFACE 0x0A80 -#define RH_SET_INTERFACE 0x0B00 -#define RH_SYNC_FRAME 0x0C80 -/* Our Vendor Specific Request */ -#define RH_SET_EP 0x2000 - -/* Hub port features */ -#define RH_PORT_CONNECTION 0x00 -#define RH_PORT_ENABLE 0x01 -#define RH_PORT_SUSPEND 0x02 -#define RH_PORT_OVER_CURRENT 0x03 -#define RH_PORT_RESET 0x04 -#define RH_PORT_POWER 0x08 -#define RH_PORT_LOW_SPEED 0x09 -#define RH_C_PORT_CONNECTION 0x10 -#define RH_C_PORT_ENABLE 0x11 -#define RH_C_PORT_SUSPEND 0x12 -#define RH_C_PORT_OVER_CURRENT 0x13 -#define RH_C_PORT_RESET 0x14 - -/* Hub features */ -#define RH_C_HUB_LOCAL_POWER 0x00 -#define RH_C_HUB_OVER_CURRENT 0x01 - -#define RH_DEVICE_REMOTE_WAKEUP 0x00 -#define RH_ENDPOINT_STALL 0x01 - -/* Our Vendor Specific feature */ -#define RH_REMOVE_EP 0x00 - -#define RH_ACK 0x01 -#define RH_REQ_ERR -1 -#define RH_NACK 0x00 - -/* Transfer descriptor structure */ -typedef struct { - unsigned long link; /* next td/qh (LE) */ - unsigned long status; /* status of the td */ - unsigned long info; /* Max Lenght / Endpoint / device address and PID */ - unsigned long buffer; /* pointer to data buffer (LE) */ - unsigned long dev_ptr; /* pointer to the assigned device (BE) */ - unsigned long res[3]; /* reserved (TDs must be 8Byte aligned) */ -} uhci_td_t, *puhci_td_t; - -/* Queue Header structure */ -typedef struct { - unsigned long head; /* Next QH (LE) */ - unsigned long element; /* Queue element pointer (LE) */ - unsigned long res[5]; /* reserved */ - unsigned long dev_ptr; /* if 0 no tds have been assigned to this qh */ -} uhci_qh_t, *puhci_qh_t; - -struct virt_root_hub { - int devnum; /* Address of Root Hub endpoint */ - int numports; /* number of ports */ - int c_p_r[8]; /* C_PORT_RESET */ -}; - -#endif /* _USB_UHCI_H_ */ |