diff options
Diffstat (limited to 'cpu')
| -rw-r--r-- | cpu/mpc85xx/pci.c | 1 | ||||
| -rw-r--r-- | cpu/nios2/Makefile | 44 | ||||
| -rw-r--r-- | cpu/nios2/config.mk | 24 | ||||
| -rw-r--r-- | cpu/nios2/cpu.c | 62 | ||||
| -rw-r--r-- | cpu/nios2/exceptions.S | 152 | ||||
| -rw-r--r-- | cpu/nios2/interrupts.c | 229 | ||||
| -rw-r--r-- | cpu/nios2/serial.c | 144 | ||||
| -rw-r--r-- | cpu/nios2/start.S | 211 | ||||
| -rw-r--r-- | cpu/nios2/traps.c | 42 | 
9 files changed, 908 insertions, 1 deletions
| diff --git a/cpu/mpc85xx/pci.c b/cpu/mpc85xx/pci.c index b61aab51f..069fe4e69 100644 --- a/cpu/mpc85xx/pci.c +++ b/cpu/mpc85xx/pci.c @@ -114,7 +114,6 @@ pci_mpc85xx_init(struct pci_controller *hose)  					  PCI_HEADER_TYPE,  					  &header_type);  	} -	  #endif  	hose->last_busno = pci_hose_scan(hose); diff --git a/cpu/nios2/Makefile b/cpu/nios2/Makefile new file mode 100644 index 000000000..76b324a7a --- /dev/null +++ b/cpu/nios2/Makefile @@ -0,0 +1,44 @@ +# +# (C) Copyright 2000 +# 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	= lib$(CPU).a + +START	= start.o +AOBJS	= exceptions.o +OBJS	= cpu.o interrupts.o serial.o traps.o + +all:	.depend $(START) $(LIB) + +$(LIB):	$(OBJS) $(AOBJS) +	$(AR) crv $@ $(OBJS) $(AOBJS) + +######################################################################### + +.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S) +	$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S) > $@ + +sinclude .depend + +######################################################################### diff --git a/cpu/nios2/config.mk b/cpu/nios2/config.mk new file mode 100644 index 000000000..f228d7219 --- /dev/null +++ b/cpu/nios2/config.mk @@ -0,0 +1,24 @@ +# +# (C) Copyright 2000 +# 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 += diff --git a/cpu/nios2/cpu.c b/cpu/nios2/cpu.c new file mode 100644 index 000000000..c9db12761 --- /dev/null +++ b/cpu/nios2/cpu.c @@ -0,0 +1,62 @@ +/* + * (C) Copyright 2004, Psyent Corporation <www.psyent.com> + * Scott McNutt <smcnutt@psyent.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 <nios2.h> +#include <nios2-io.h> + +#if defined (CFG_NIOS_SYSID_BASE) +#include <linux/time.h> +static void check_sysid (void) +{ +	struct nios_sysid_t *sysid = +		(struct nios_sysid_t *)CACHE_BYPASS(CFG_NIOS_SYSID_BASE); +	struct tm t; +	char asc[32]; + +	localtime_r ((time_t *)&sysid->timestamp, &t); +	asctime_r (&t, asc); +	printf ("SYSID : %08x, %s", sysid->id, asc); + +} +#endif /* CFG_NIOS_SYSID_BASE */ + +int checkcpu (void) +{ +	printf ("CPU   : Nios-II\n"); +#if !defined(CFG_NIOS_SYSID_BASE) +	printf ("SYSID : <unknown>\n"); +#else +	check_sysid (); +#endif +	return (0); +} + + +int do_reset (void) +{ +	void (*rst)(void) = (void(*)(void))CFG_RESET_ADDR; +	disable_interrupts (); +	rst(); +	return(0); +} diff --git a/cpu/nios2/exceptions.S b/cpu/nios2/exceptions.S new file mode 100644 index 000000000..d3b95cfc7 --- /dev/null +++ b/cpu/nios2/exceptions.S @@ -0,0 +1,152 @@ +/* + * (C) Copyright 2004, Psyent Corporation <www.psyent.com> + * Scott McNutt <smcnutt@psyent.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/opcodes.h> + + +	.text +	.align	4 + +	.global _exception + +_exception: +	/* SAVE ALL REGS -- this allows trap and unimplemented +	 * instruction handlers to be coded conveniently in C +	 */ +	addi	sp, sp, -(33*4) +	stw	r0, 0(sp) +	stw	r1, 4(sp) +	stw	r2, 8(sp) +	stw	r3, 12(sp) +	stw	r4, 16(sp) +	stw	r5, 20(sp) +	stw	r6, 24(sp) +	stw	r7, 28(sp) +	stw	r8, 32(sp) +	stw	r9, 36(sp) +	stw	r10, 40(sp) +	stw	r11, 44(sp) +	stw	r12, 48(sp) +	stw	r13, 52(sp) +	stw	r14, 56(sp) +	stw	r15, 60(sp) +	stw	r16, 64(sp) +	stw	r17, 68(sp) +	stw	r19, 72(sp) +	stw	r19, 76(sp) +	stw	r20, 80(sp) +	stw	r21, 84(sp) +	stw	r22, 88(sp) +	stw	r23, 92(sp) +	stw	r24, 96(sp) +	stw	r25, 100(sp) +	stw	r26, 104(sp) +	stw	r27, 108(sp) +	stw	r28, 112(sp) +	stw	r29, 116(sp) +	stw	r30, 120(sp) +	stw	r31, 124(sp) +	rdctl	et, estatus +	stw	et, 128(sp) + +	/* If interrupts are disabled -- software interrupt */ +	rdctl	et, estatus +	andi	et, et, 1 +	beq	et, r0, 0f + +	/* If no interrupts are pending -- software interrupt */ +	rdctl	et, ipending +	beq	et, r0, 0f + +	/* HARDWARE INTERRUPT: Call interrupt handler */ +	movhi	r3, %hi(external_interrupt) +	ori	r3, r3, %lo(external_interrupt) +	mov	r4, sp		/* ptr to regs */ +	callr	r3 + +	/* Return address fixup: execution resumes by re-issue of +	 * interrupted instruction at ea-4 (ea == r29). Here we do +	 * simple fixup to allow common exception return. +	 */ +	ldw	r3, 116(sp) +	addi	r3, r3, -4 +	stw	r3, 116(sp) +	br	_exception_return + +0: +	/* TRAP EXCEPTION */ +	movhi	r3, %hi(OPC_TRAP) +	ori	r3, r3, %lo(OPC_TRAP) +	addi	r1, ea, -4 +	ldw	r1, 0(r1) +	bne	r1, r3, 1f +	movhi	r3, %hi(trap_handler) +	ori	r3, r3, %lo(trap_handler) +	mov	r4, sp		/* ptr to regs */ +	callr	r3 +	br	_exception_return + +1: +	/* UNIMPLEMENTED INSTRUCTION EXCEPTION */ +	movhi	r3, %hi(soft_emulation) +	ori	r3, r3, %lo(soft_emulation) +	mov	r4, sp		/* ptr to regs */ +	callr	r3 + +	/* Restore regsisters and return from exception*/ +_exception_return: +	ldw	r1, 4(sp) +	ldw	r2, 8(sp) +	ldw	r3, 12(sp) +	ldw	r4, 16(sp) +	ldw	r5, 20(sp) +	ldw	r6, 24(sp) +	ldw	r7, 28(sp) +	ldw	r8, 32(sp) +	ldw	r9, 36(sp) +	ldw	r10, 40(sp) +	ldw	r11, 44(sp) +	ldw	r12, 48(sp) +	ldw	r13, 52(sp) +	ldw	r14, 56(sp) +	ldw	r15, 60(sp) +	ldw	r16, 64(sp) +	ldw	r17, 68(sp) +	ldw	r19, 72(sp) +	ldw	r19, 76(sp) +	ldw	r20, 80(sp) +	ldw	r21, 84(sp) +	ldw	r22, 88(sp) +	ldw	r23, 92(sp) +	ldw	r24, 96(sp) +	ldw	r25, 100(sp) +	ldw	r26, 104(sp) +	ldw	r27, 108(sp) +	ldw	r28, 112(sp) +	ldw	r29, 116(sp) +	ldw	r30, 120(sp) +	ldw	r31, 124(sp) +	addi	sp, sp, (33*4) +	eret +/*-------------------------------------------------------------*/ diff --git a/cpu/nios2/interrupts.c b/cpu/nios2/interrupts.c new file mode 100644 index 000000000..4a6da582b --- /dev/null +++ b/cpu/nios2/interrupts.c @@ -0,0 +1,229 @@ +/* + * (C) Copyright 2000-2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2004, Psyent Corporation <www.psyent.com> + * Scott McNutt <smcnutt@psyent.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 <nios2.h> +#include <nios2-io.h> +#include <asm/ptrace.h> +#include <common.h> +#include <command.h> +#include <watchdog.h> +#ifdef CONFIG_STATUS_LED +#include <status_led.h> +#endif + +#if defined(CFG_NIOS_TMRBASE) && !defined(CFG_NIOS_TMRIRQ) +#error CFG_NIOS_TMRIRQ not defined (see documentation) +#endif + +/****************************************************************************/ + +struct	irq_action { +	interrupt_handler_t *handler; +	void *arg; +	int count; +}; + +static struct irq_action vecs[32]; + +/*************************************************************************/ +volatile ulong timestamp = 0; + +void reset_timer (void) +{ +	timestamp = 0; +} + +ulong get_timer (ulong base) +{ +	WATCHDOG_RESET (); +	return (timestamp - base); +} + +void set_timer (ulong t) +{ +	timestamp = t; +} + + +/* The board must handle this interrupt if a timer is not + * provided. + */ +#if defined(CFG_NIOS_TMRBASE) +void tmr_isr (void *arg) +{ +	nios_timer_t *tmr = (nios_timer_t *)arg; +	/* Interrupt is cleared by writing anything to the +	 * status register. +	 */ +	tmr->status = 0; +	timestamp += CFG_NIOS_TMRMS; +#ifdef CONFIG_STATUS_LED +	status_led_tick(timestamp); +#endif +} + +static void tmr_init (void) +{ +	nios_timer_t *tmr =(nios_timer_t *)CACHE_BYPASS(CFG_NIOS_TMRBASE); + +	tmr->control &= ~(NIOS_TIMER_START | NIOS_TIMER_ITO); +	tmr->control |= NIOS_TIMER_STOP; +#if defined(CFG_NIOS_TMRCNT) +	tmr->periodl = CFG_NIOS_TMRCNT & 0xffff; +	tmr->periodh = (CFG_NIOS_TMRCNT >> 16) & 0xffff; +#endif +	tmr->control |= ( NIOS_TIMER_ITO | +			  NIOS_TIMER_CONT | +			  NIOS_TIMER_START ); +	irq_install_handler (CFG_NIOS_TMRIRQ, tmr_isr, (void *)tmr); +} + +#endif /* CFG_NIOS_TMRBASE */ + +/*************************************************************************/ +int disable_interrupts (void) +{ +	int val = rdctl (CTL_STATUS); +	wrctl (CTL_STATUS, val & ~STATUS_IE); +	return (val & STATUS_IE); +} + +void enable_interrupts( void ) +{ +	int val = rdctl (CTL_STATUS); +	wrctl (CTL_STATUS, val | STATUS_IE); +} + +void external_interrupt (struct pt_regs *regs) +{ +	unsigned irqs; +	struct irq_action *act; + +	/* Evaluate only irqs that are both enabled AND pending */ +	irqs = rdctl (CTL_IENABLE) & rdctl (CTL_IPENDING); +	act = vecs; + +	/* Assume (as does the Nios2 HAL) that bit 0 is highest +	 * priority. NOTE: There is ALWAYS a handler assigned +	 * (the default if no other). +	 */ +	while (irqs) { +		if (irqs & 1) { +			act->handler (act->arg); +			act->count++; +		} +		irqs >>=1; +		act++; +	} +} + +static void def_hdlr (void *arg) +{ +	unsigned irqs = rdctl (CTL_IENABLE); + +	/* Disable the individual interrupt -- with gratuitous +	 * warning. +	 */ +	irqs &= ~(1 << (int)arg); +	wrctl (CTL_IENABLE, irqs); +	printf ("WARNING: Disabling unhandled interrupt: %d\n", +			(int)arg); +} + +/*************************************************************************/ +void irq_install_handler (int irq, interrupt_handler_t *hdlr, void *arg) +{ + +	int flag; +	struct irq_action *act; +	unsigned ena = rdctl (CTL_IENABLE); + +	if ((irq < 0) || (irq > 31)) +		return; +	act = &vecs[irq]; + +	flag = disable_interrupts (); +	if (hdlr) { +		act->handler = hdlr; +		act->arg = arg; +		ena |= (1 << irq);		/* enable */ +	} else { +		act->handler = def_hdlr; +		act->arg = (void *)irq; +		ena &= ~(1 << irq);		/* disable */ +	} +	wrctl (CTL_IENABLE, ena); +	if (flag) enable_interrupts (); +} + + +int interrupt_init (void) +{ +	int i; + +	/* Assign the default handler to all */ +	for (i = 0; i < 32; i++) { +		vecs[i].handler = def_hdlr; +		vecs[i].arg = (void *)i; +		vecs[i].count = 0; +	} + +#if defined(CFG_NIOS_TMRBASE) +	tmr_init (); +#endif + +	enable_interrupts (); +	return (0); +} + + +/*************************************************************************/ +#if (CONFIG_COMMANDS & CFG_CMD_IRQ) +int do_irqinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +	int i; +	struct irq_action *act = vecs; + +	printf ("\nInterrupt-Information:\n\n"); +	printf ("Nr  Routine   Arg       Count\n"); +	printf ("-----------------------------\n"); + +	for (i=0; i<32; i++) { +		if (act->handler != def_hdlr) { +			printf ("%02d  %08lx  %08lx  %d\n", +				i, +				(ulong)act->handler, +				(ulong)act->arg, +				act->count); +		} +		act++; +	} +	printf ("\n"); + +	return (0); +} +#endif  /* CONFIG_COMMANDS & CFG_CMD_IRQ */ diff --git a/cpu/nios2/serial.c b/cpu/nios2/serial.c new file mode 100644 index 000000000..2d08c93d0 --- /dev/null +++ b/cpu/nios2/serial.c @@ -0,0 +1,144 @@ +/* + * (C) Copyright 2004, Psyent Corporation <www.psyent.com> + * Scott McNutt <smcnutt@psyent.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 <nios2.h> +#include <nios2-io.h> + +/*------------------------------------------------------------------ + * JTAG acts as the serial port + *-----------------------------------------------------------------*/ +#if defined(CONFIG_CONSOLE_JTAG) + +static nios_jtag_t *jtag = +	(nios_jtag_t *)CACHE_BYPASS(CFG_NIOS_CONSOLE); + +void serial_setbrg( void ){ return; } +int serial_init( void ) { return(0);} + +void serial_putc (char c) +{ +	unsigned val; + +	while (NIOS_JTAG_WSPACE (jtag->control) == 0) +		WATCHDOG_RESET (); +	jtag->data = (unsigned char)c; +} + +void serial_puts (const char *s) +{ +	while (*s != 0) +		serial_putc (*s++); +} + +int serial_tstc (void) +{ +	return (jtag->control & NIOS_JTAG_RRDY); +} + +int serial_getc (void) +{ +	int c; +	unsigned val; + +	while (1) { +		WATCHDOG_RESET (); +		val = jtag->data; +		if (val & NIOS_JTAG_RVALID) +			break; +	} +	c = val & 0x0ff; +	return (c); +} + +/*------------------------------------------------------------------ + * UART the serial port + *-----------------------------------------------------------------*/ +#else + +static nios_uart_t *uart = (nios_uart_t *) +	CACHE_BYPASS(CFG_NIOS_CONSOLE); + +#if defined(CFG_NIOS_FIXEDBAUD) + +/* Everything's already setup for fixed-baud PTF + * assignment + */ +void serial_setbrg (void){ return; } +int serial_init (void) { return (0);} + +#else + +void serial_setbrg (void) +{ +	DECLARE_GLOBAL_DATA_PTR; +	unsigned div; + +	div = (CONFIG_SYS_CLK_FREQ/gd->baudrate)-1; +	uart->divisor = div; +	return; +} + +int serial_init (void) +{ +	serial_setbrg (); +	return (0); +} + +#endif /* CFG_NIOS_FIXEDBAUD */ + + +/*----------------------------------------------------------------------- + * UART CONSOLE + *---------------------------------------------------------------------*/ +void serial_putc (char c) +{ +	if (c == '\n') +		serial_putc ('\r'); +	while ((uart->status & NIOS_UART_TRDY) == 0) +		WATCHDOG_RESET (); +	uart->txdata = (unsigned char)c; +} + +void serial_puts (const char *s) +{ +	while (*s != 0) { +		serial_putc (*s++); +	} +} + +int serial_tstc (void) +{ +	return (uart->status & NIOS_UART_RRDY); +} + +int serial_getc (void) +{ +	while (serial_tstc () == 0) +		WATCHDOG_RESET (); +	return( uart->rxdata & 0x00ff ); +} + +#endif /* CONFIG_JTAG_CONSOLE */ diff --git a/cpu/nios2/start.S b/cpu/nios2/start.S new file mode 100644 index 000000000..281d42c21 --- /dev/null +++ b/cpu/nios2/start.S @@ -0,0 +1,211 @@ +/* + * (C) Copyright 2004, Psyent Corporation <www.psyent.com> + * Scott McNutt <smcnutt@psyent.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 <version.h> + +/************************************************************************* + * RESTART + ************************************************************************/ + +	.text +	.global _start + +_start: +	/* ICACHE INIT -- only the icache line at the reset address +	 * is invalidated at reset. So the init must stay within +	 * the cache line size (8 words). If GERMS is used, we'll +	 * just be invalidating the cache a second time. If cache +	 * is not implemented initi behaves as nop. +	 */ +	movhi	r4, %hi(CFG_ICACHELINE_SIZE) +	ori	r4, r4, %lo(CFG_ICACHELINE_SIZE) +	movhi	r5, %hi(CFG_ICACHE_SIZE) +	ori	r5, r5, %lo(CFG_ICACHE_SIZE) +	mov	r6, r0 +0:	initi	r6 +	add	r6, r6, r4 +	bltu	r6, r5, 0b + +	/* INTERRUPTS -- for now, all interrupts masked and globally +	 * disabled. +	 */ +	wrctl	status, r0		/* Disable interrupts */ +	wrctl	ienable, r0		/* All disabled	*/ + +	/* DCACHE INIT -- if dcache not implemented, initd behaves as +	 * nop. +	 */ +	movhi	r4, %hi(CFG_DCACHELINE_SIZE) +	ori	r4, r4, %lo(CFG_DCACHELINE_SIZE) +	movhi	r5, %hi(CFG_DCACHE_SIZE) +	ori	r5, r5, %lo(CFG_DCACHE_SIZE) +	mov	r6, r0 +1:	initd	0(r6) +	add	r6, r6, r4 +	bltu	r6, r5, 1b + +	/* RELOCATE CODE, DATA & COMMAND TABLE -- the following code +	 * assumes code, data and the command table are all +	 * contiguous. This lets us relocate everything as a single +	 * block. Make sure the linker script matches this ;-) +	 */ +	nextpc	r4 +_cur:	movhi	r5, %hi(_cur - _start) +	ori	r5, r5, %lo(_cur - _start) +	sub	r4, r4, r5		/* r4 <- cur _start */ +	mov	r8, r4 +	movhi	r5, %hi(_start) +	ori	r5, r5, %lo(_start)	/* r5 <- linked _start */ +	beq	r4, r5, 3f + +	movhi	r6, %hi(_edata) +	ori	r6, r6, %lo(_edata) +2:	ldwio	r7, 0(r4) +	addi	r4, r4, 4 +	stwio	r7, 0(r5) +	addi	r5, r5, 4 +	bne	r5, r6, 2b +3: + +	/* ZERO BSS/SBSS -- bss and sbss are assumed to be adjacent +	 * and between __bss_start and _end. +	 */ +	 movhi	r5, %hi(__bss_start) +	 ori	r5, r5, %lo(__bss_start) +	 movhi	r6, %hi(_end) +	 ori	r6, r6, %lo(_end) +	 beq	r5, r6, 5f + +4:	stwio	r0, 0(r5) +	 addi	r5, r5, 4 +	 bne	r5, r6, 4b +5: + +	/* GLOBAL POINTER -- the global pointer is used to reference +	 * "small data" (see -G switch). The linker script must +	 * provide the gp address. +	 */ +	 movhi	gp, %hi(_gp) +	 ori	gp, gp, %lo(_gp) + +	/* JUMP TO RELOC ADDR */ +	movhi	r4, %hi(_reloc) +	ori	r4, r4, %lo(_reloc) +	jmp	r4 +_reloc: + +	/* COPY EXCEPTION TRAMPOLINE -- copy the tramp to the +	 * exception address. +	 */ +#if !defined(CONFIG_ROM_STUBS) +	movhi	r4, %hi(_except_start) +	ori	r4, r4, %lo(_except_start) +	movhi	r5, %hi(_except_end) +	ori	r5, r5, %lo(_except_end) +	movhi	r6, %hi(CFG_EXCEPTION_ADDR) +	ori	r6, r6, %lo(CFG_EXCEPTION_ADDR) + +6:	ldwio	r7, 0(r4) +	stwio	r7, 0(r6) +	addi	r4, r4, 4 +	addi	r6, r6, 4 +	bne	r4, r5, 6b +#endif + +	/* STACK INIT -- zero top two words for call back chain. +	 */ +	movhi	sp, %hi(CFG_INIT_SP) +	ori	sp, sp, %lo(CFG_INIT_SP) +	addi	sp, sp, -8 +	stw	r0, 0(sp) +	stw	r0, 4(sp) +	mov	fp, sp + +	/* +	 * Call board_init -- never returns +	 */ +	movhi	r4, %hi(board_init@h) +	ori	r4, r4, %lo(board_init@h) +	callr	r4 + +	/* NEVER RETURNS -- but branch to the _start just +	 * in case ;-) +	 */ +	br	_start + +	/* EXCEPTION TRAMPOLINE -- the following gets copied +	 * to the exception address. +	 */ +_except_start: +	movhi	et, %hi(_exception) +	ori	et, et, %lo(_exception) +	jmp	et +_except_end: + + +/* + * dly_clks -- Nios2 (like Nios1) doesn't have a timebase in + * the core. For simple delay loops, we do our best by counting + * instruction cycles. + * + * Instruction performance varies based on the core. For cores + * with icache and static/dynamic branch prediction (II/f, II/s): + * + * 	Normal ALU (e.g. add, cmp, etc):	1 cycle + * 	Branch (correctly predicted, taken):	2 cycles + *	Negative offset is predicted (II/s). + * + * For cores without icache and no branch prediction (II/e): + * + * 	Normal ALU (e.g. add, cmp, etc):	6 cycles + * 	Branch (no prediction):			6 cycles + * + * For simplicity, if an instruction cache is implemented we + * assume II/f or II/s. Otherwise, we use the II/e. + * + */ + 	.globl dly_clks + +dly_clks: + +#if (CFG_ICACHE_SIZE > 0) +	subi	r4, r4, 3		/* 3 clocks/loop	*/ +#else +	subi	r4, r4, 12		/* 12 clocks/loop	*/ +#endif +	bge	r4, r0, dly_clks +	ret + + +#if !defined(CONFIG_IDENT_STRING) +#define CONFIG_IDENT_STRING "" +#endif +	.data +	.globl	version_string + +version_string: +	.ascii U_BOOT_VERSION +	.ascii " (", __DATE__, " - ", __TIME__, ")" +	.ascii CONFIG_IDENT_STRING, "\0" diff --git a/cpu/nios2/traps.c b/cpu/nios2/traps.c new file mode 100644 index 000000000..3f1517d61 --- /dev/null +++ b/cpu/nios2/traps.c @@ -0,0 +1,42 @@ +/* + * (C) Copyright 2004, Psyent Corporation <www.psyent.com> + * Scott McNutt <smcnutt@psyent.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 <asm/ptrace.h> +#include <common.h> + +void trap_handler (struct pt_regs *regs) +{ +	/* Just issue warning */ +	printf ("\n\n*** WARNING: unimplemented trap @ %08x\n\n", +			regs->reg[29] - 4); +} + +void soft_emulation (struct pt_regs *regs) +{ +	/* TODO: Software emulation of mul/div etc. Until this is +	 * implemented, generate warning and hang. +	 */ +	printf ("\n\n*** ERROR: unimplemented instruction @ %08x\n", +			regs->reg[29] - 4); +	hang (); +} |