1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter.git synced 2025-03-09 15:40:20 +00:00

Add a directory by kernel instead of a common root, add qnap-301w and rpi4 kernel 6.1 suppport

This commit is contained in:
Ycarus (Yannick Chabanois) 2023-04-22 08:07:24 +02:00
parent e910436a7a
commit 46837ec4c0
9459 changed files with 362648 additions and 116345 deletions

View file

@ -0,0 +1,33 @@
#
# (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
#
CROSS_COMPILE ?= nios2-elf-
CONFIG_STANDALONE_LOAD_ADDR ?= 0x02000000
PLATFORM_CPPFLAGS += -DCONFIG_NIOS2 -D__NIOS2__
PLATFORM_CPPFLAGS += -G0
LDFLAGS_FINAL += --gc-sections
PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections

View file

@ -0,0 +1,49 @@
#
# (C) Copyright 2000-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).o
START = start.o
SOBJS = exceptions.o
COBJS = cpu.o interrupts.o sysid.o traps.o epcs.o
COBJS += fdt.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)
$(call cmd_link_o_target, $(OBJS))
#########################################################################
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################

View file

@ -0,0 +1,65 @@
/*
* (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>
#include <asm/cache.h>
#if defined (CONFIG_SYS_NIOS_SYSID_BASE)
extern void display_sysid (void);
#endif /* CONFIG_SYS_NIOS_SYSID_BASE */
int checkcpu (void)
{
printf ("CPU : Nios-II\n");
#if !defined(CONFIG_SYS_NIOS_SYSID_BASE)
printf ("SYSID : <unknown>\n");
#else
display_sysid ();
#endif
return (0);
}
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
disable_interrupts();
/* indirect call to go beyond 256MB limitation of toolchain */
nios2_callr(CONFIG_SYS_RESET_ADDR);
return 0;
}
int dcache_status(void)
{
return 1;
}
void dcache_enable(void)
{
flush_dcache(CONFIG_SYS_DCACHE_SIZE, CONFIG_SYS_DCACHELINE_SIZE);
}
void dcache_disable(void)
{
flush_dcache(CONFIG_SYS_DCACHE_SIZE, CONFIG_SYS_DCACHELINE_SIZE);
}

View file

@ -0,0 +1,733 @@
/*
* (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>
#if defined(CONFIG_SYS_NIOS_EPCSBASE)
#include <command.h>
#include <asm/io.h>
#include <nios2-io.h>
#include <nios2-epcs.h>
/*-----------------------------------------------------------------------*/
#define SHORT_HELP\
"epcs - read/write Cyclone EPCS configuration device.\n"
#define LONG_HELP\
"\n"\
"epcs erase start [end]\n"\
" - erase sector start or sectors start through end.\n"\
"epcs info\n"\
" - display EPCS device information.\n"\
"epcs protect on | off\n"\
" - turn device protection on or off.\n"\
"epcs read addr offset count\n"\
" - read count bytes from offset to addr.\n"\
"epcs write addr offset count\n"\
" - write count bytes to offset from addr.\n"\
"epcs verify addr offset count\n"\
" - verify count bytes at offset from addr."
/*-----------------------------------------------------------------------*/
/* Operation codes for serial configuration devices
*/
#define EPCS_WRITE_ENA 0x06 /* Write enable */
#define EPCS_WRITE_DIS 0x04 /* Write disable */
#define EPCS_READ_STAT 0x05 /* Read status */
#define EPCS_READ_BYTES 0x03 /* Read bytes */
#define EPCS_READ_ID 0xab /* Read silicon id */
#define EPCS_WRITE_STAT 0x01 /* Write status */
#define EPCS_WRITE_BYTES 0x02 /* Write bytes */
#define EPCS_ERASE_BULK 0xc7 /* Erase entire device */
#define EPCS_ERASE_SECT 0xd8 /* Erase sector */
/* Device status register bits
*/
#define EPCS_STATUS_WIP (1<<0) /* Write in progress */
#define EPCS_STATUS_WEL (1<<1) /* Write enable latch */
/* Misc
*/
#define EPCS_TIMEOUT 100 /* 100 msec timeout */
static nios_spi_t *epcs = (nios_spi_t *)CONFIG_SYS_NIOS_EPCSBASE;
/***********************************************************************
* Device access
***********************************************************************/
static int epcs_cs (int assert)
{
ulong start;
unsigned tmp;
if (assert) {
tmp = readl (&epcs->control);
writel (tmp | NIOS_SPI_SSO, &epcs->control);
} else {
/* Let all bits shift out */
start = get_timer (0);
while ((readl (&epcs->status) & NIOS_SPI_TMT) == 0)
if (get_timer (start) > EPCS_TIMEOUT)
return (-1);
tmp = readl (&epcs->control);
writel (tmp & ~NIOS_SPI_SSO, &epcs->control);
}
return (0);
}
static int epcs_tx (unsigned char c)
{
ulong start;
start = get_timer (0);
while ((readl (&epcs->status) & NIOS_SPI_TRDY) == 0)
if (get_timer (start) > EPCS_TIMEOUT)
return (-1);
writel (c, &epcs->txdata);
return (0);
}
static int epcs_rx (void)
{
ulong start;
start = get_timer (0);
while ((readl (&epcs->status) & NIOS_SPI_RRDY) == 0)
if (get_timer (start) > EPCS_TIMEOUT)
return (-1);
return (readl (&epcs->rxdata));
}
static unsigned char bitrev[] = {
0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f
};
static unsigned char epcs_bitrev (unsigned char c)
{
unsigned char val;
val = bitrev[c>>4];
val |= bitrev[c & 0x0f]<<4;
return (val);
}
static void epcs_rcv (unsigned char *dst, int len)
{
while (len--) {
epcs_tx (0);
*dst++ = epcs_rx ();
}
}
static void epcs_rrcv (unsigned char *dst, int len)
{
while (len--) {
epcs_tx (0);
*dst++ = epcs_bitrev (epcs_rx ());
}
}
static void epcs_snd (unsigned char *src, int len)
{
while (len--) {
epcs_tx (*src++);
epcs_rx ();
}
}
static void epcs_rsnd (unsigned char *src, int len)
{
while (len--) {
epcs_tx (epcs_bitrev (*src++));
epcs_rx ();
}
}
static void epcs_wr_enable (void)
{
epcs_cs (1);
epcs_tx (EPCS_WRITE_ENA);
epcs_rx ();
epcs_cs (0);
}
static unsigned char epcs_status_rd (void)
{
unsigned char status;
epcs_cs (1);
epcs_tx (EPCS_READ_STAT);
epcs_rx ();
epcs_tx (0);
status = epcs_rx ();
epcs_cs (0);
return (status);
}
static void epcs_status_wr (unsigned char status)
{
epcs_wr_enable ();
epcs_cs (1);
epcs_tx (EPCS_WRITE_STAT);
epcs_rx ();
epcs_tx (status);
epcs_rx ();
epcs_cs (0);
return;
}
/***********************************************************************
* Device information
***********************************************************************/
static struct epcs_devinfo_t devinfo[] = {
{ "EPCS1 ", 0x10, 17, 4, 15, 8, 0x0c },
{ "EPCS4 ", 0x12, 19, 8, 16, 8, 0x1c },
{ "EPCS16", 0x14, 21, 32, 16, 8, 0x1c },
{ "EPCS64", 0x16, 23,128, 16, 8, 0x1c },
{ 0, 0, 0, 0, 0, 0 }
};
int epcs_reset (void)
{
/* When booting from an epcs controller, the epcs bootrom
* code may leave the slave select in an asserted state.
* This causes two problems: (1) The initial epcs access
* will fail -- not a big deal, and (2) a software reset
* will cause the bootrom code to hang since it does not
* ensure the select is negated prior to first access -- a
* big deal. Here we just negate chip select and everything
* gets better :-)
*/
epcs_cs (0); /* Negate chip select */
return (0);
}
epcs_devinfo_t *epcs_dev_find (void)
{
unsigned char buf[4];
unsigned char id;
int i;
struct epcs_devinfo_t *dev = NULL;
/* Read silicon id requires 3 "dummy bytes" before it's put
* on the wire.
*/
buf[0] = EPCS_READ_ID;
buf[1] = 0;
buf[2] = 0;
buf[3] = 0;
epcs_cs (1);
epcs_snd (buf,4);
epcs_rcv (buf,1);
if (epcs_cs (0) == -1)
return (NULL);
id = buf[0];
/* Find the info struct */
i = 0;
while (devinfo[i].name) {
if (id == devinfo[i].id) {
dev = &devinfo[i];
break;
}
i++;
}
return (dev);
}
/***********************************************************************
* Misc Utilities
***********************************************************************/
int epcs_cfgsz (void)
{
int sz = 0;
unsigned char buf[128];
unsigned char *p;
struct epcs_devinfo_t *dev = epcs_dev_find ();
if (!dev)
return (-1);
/* Read in the first 128 bytes of the device */
buf[0] = EPCS_READ_BYTES;
buf[1] = 0;
buf[2] = 0;
buf[3] = 0;
epcs_cs (1);
epcs_snd (buf,4);
epcs_rrcv (buf, sizeof(buf));
epcs_cs (0);
/* Search for the starting 0x6a which is followed by the
* 4-byte 'register' and 4-byte bit-count.
*/
p = buf;
while (p < buf + sizeof(buf)-8) {
if ( *p == 0x6a ) {
/* Point to bit count and extract */
p += 5;
sz = *p++;
sz |= *p++ << 8;
sz |= *p++ << 16;
sz |= *p++ << 24;
/* Convert to byte count */
sz += 7;
sz >>= 3;
} else if (*p == 0xff) {
/* 0xff is ok ... just skip */
p++;
continue;
} else {
/* Not 0xff or 0x6a ... something's not
* right ... report 'unknown' (sz=0).
*/
break;
}
}
return (sz);
}
int epcs_erase (unsigned start, unsigned end)
{
unsigned off, sectsz;
unsigned char buf[4];
struct epcs_devinfo_t *dev = epcs_dev_find ();
if (!dev || (start>end))
return (-1);
/* Erase the requested sectors. An address is required
* that lies within the requested sector -- we'll just
* use the first address in the sector.
*/
printf ("epcs erasing sector %d ", start);
if (start != end)
printf ("to %d ", end);
sectsz = (1 << dev->sz_sect);
while (start <= end) {
off = start * sectsz;
start++;
buf[0] = EPCS_ERASE_SECT;
buf[1] = off >> 16;
buf[2] = off >> 8;
buf[3] = off;
epcs_wr_enable ();
epcs_cs (1);
epcs_snd (buf,4);
epcs_cs (0);
printf ("."); /* Some user feedback */
/* Wait for erase to complete */
while (epcs_status_rd() & EPCS_STATUS_WIP)
;
}
printf (" done.\n");
return (0);
}
int epcs_read (ulong addr, ulong off, ulong cnt)
{
unsigned char buf[4];
struct epcs_devinfo_t *dev = epcs_dev_find ();
if (!dev)
return (-1);
buf[0] = EPCS_READ_BYTES;
buf[1] = off >> 16;
buf[2] = off >> 8;
buf[3] = off;
epcs_cs (1);
epcs_snd (buf,4);
epcs_rrcv ((unsigned char *)addr, cnt);
epcs_cs (0);
return (0);
}
int epcs_write (ulong addr, ulong off, ulong cnt)
{
ulong wrcnt;
unsigned pgsz;
unsigned char buf[4];
struct epcs_devinfo_t *dev = epcs_dev_find ();
if (!dev)
return (-1);
pgsz = (1<<dev->sz_page);
while (cnt) {
if (off % pgsz)
wrcnt = pgsz - (off % pgsz);
else
wrcnt = pgsz;
wrcnt = (wrcnt > cnt) ? cnt : wrcnt;
buf[0] = EPCS_WRITE_BYTES;
buf[1] = off >> 16;
buf[2] = off >> 8;
buf[3] = off;
epcs_wr_enable ();
epcs_cs (1);
epcs_snd (buf,4);
epcs_rsnd ((unsigned char *)addr, wrcnt);
epcs_cs (0);
/* Wait for write to complete */
while (epcs_status_rd() & EPCS_STATUS_WIP)
;
cnt -= wrcnt;
off += wrcnt;
addr += wrcnt;
}
return (0);
}
int epcs_verify (ulong addr, ulong off, ulong cnt, ulong *err)
{
ulong rdcnt;
unsigned char buf[256];
unsigned char *start,*end;
int i;
start = end = (unsigned char *)addr;
while (cnt) {
rdcnt = (cnt>sizeof(buf)) ? sizeof(buf) : cnt;
epcs_read ((ulong)buf, off, rdcnt);
for (i=0; i<rdcnt; i++) {
if (*end != buf[i]) {
*err = end - start;
return(-1);
}
end++;
}
cnt -= rdcnt;
off += rdcnt;
}
return (0);
}
static int epcs_sect_erased (int sect, unsigned *offset,
struct epcs_devinfo_t *dev)
{
unsigned char buf[128];
unsigned off, end;
unsigned sectsz;
int i;
sectsz = (1 << dev->sz_sect);
off = sectsz * sect;
end = off + sectsz;
while (off < end) {
epcs_read ((ulong)buf, off, sizeof(buf));
for (i=0; i < sizeof(buf); i++) {
if (buf[i] != 0xff) {
*offset = off + i;
return (0);
}
}
off += sizeof(buf);
}
return (1);
}
/***********************************************************************
* Commands
***********************************************************************/
static
void do_epcs_info (struct epcs_devinfo_t *dev, int argc, char * const argv[])
{
int i;
unsigned char stat;
unsigned tmp;
int erased;
/* Basic device info */
printf ("%s: %d kbytes (%d sectors x %d kbytes,"
" %d bytes/page)\n",
dev->name, 1 << (dev->size-10),
dev->num_sects, 1 << (dev->sz_sect-10),
1 << dev->sz_page );
/* Status -- for now protection is all-or-nothing */
stat = epcs_status_rd();
printf ("status: 0x%02x (WIP:%d, WEL:%d, PROT:%s)\n",
stat,
(stat & EPCS_STATUS_WIP) ? 1 : 0,
(stat & EPCS_STATUS_WEL) ? 1 : 0,
(stat & dev->prot_mask) ? "on" : "off" );
/* Configuration */
tmp = epcs_cfgsz ();
if (tmp) {
printf ("config: 0x%06x (%d) bytes\n", tmp, tmp );
} else {
printf ("config: unknown\n" );
}
/* Sector info */
for (i=0; (i < dev->num_sects) && (argc > 1); i++) {
erased = epcs_sect_erased (i, &tmp, dev);
if ((i & 0x03) == 0) printf ("\n");
printf ("%4d: %07x ",
i, i*(1<<dev->sz_sect) );
if (erased)
printf ("E ");
else
printf (" ");
}
printf ("\n");
return;
}
static
void do_epcs_erase (struct epcs_devinfo_t *dev, int argc, char * const argv[])
{
unsigned start,end;
if ((argc < 3) || (argc > 4)) {
printf ("USAGE: epcs erase sect [end]\n");
return;
}
if ((epcs_status_rd() & dev->prot_mask) != 0) {
printf ( "epcs: device protected.\n");
return;
}
start = simple_strtoul (argv[2], NULL, 10);
if (argc > 3)
end = simple_strtoul (argv[3], NULL, 10);
else
end = start;
if ((start >= dev->num_sects) || (start > end)) {
printf ("epcs: invalid sector range: [%d:%d]\n",
start, end );
return;
}
epcs_erase (start, end);
return;
}
static
void do_epcs_protect (struct epcs_devinfo_t *dev, int argc, char * const argv[])
{
unsigned char stat;
/* For now protection is all-or-nothing to keep things
* simple. The protection bits don't map in a linear
* fashion ... and we would rather protect the bottom
* of the device since it contains the config data and
* leave the top unprotected for app use. But unfortunately
* protection works from top-to-bottom so it does
* really help very much from a software app point-of-view.
*/
if (argc < 3) {
printf ("USAGE: epcs protect on | off\n");
return;
}
if (!dev)
return;
/* Protection on/off is just a matter of setting/clearing
* all protection bits in the status register.
*/
stat = epcs_status_rd ();
if (strcmp ("on", argv[2]) == 0) {
stat |= dev->prot_mask;
} else if (strcmp ("off", argv[2]) == 0 ) {
stat &= ~dev->prot_mask;
} else {
printf ("epcs: unknown protection: %s\n", argv[2]);
return;
}
epcs_status_wr (stat);
return;
}
static
void do_epcs_read (struct epcs_devinfo_t *dev, int argc, char * const argv[])
{
ulong addr,off,cnt;
ulong sz;
if (argc < 5) {
printf ("USAGE: epcs read addr offset count\n");
return;
}
sz = 1 << dev->size;
addr = simple_strtoul (argv[2], NULL, 16);
off = simple_strtoul (argv[3], NULL, 16);
cnt = simple_strtoul (argv[4], NULL, 16);
if (off > sz) {
printf ("offset is greater than device size"
"... aborting.\n");
return;
}
if ((off + cnt) > sz) {
printf ("request exceeds device size"
"... truncating.\n");
cnt = sz - off;
}
printf ("epcs: read %08lx <- %06lx (0x%lx bytes)\n",
addr, off, cnt);
epcs_read (addr, off, cnt);
return;
}
static
void do_epcs_write (struct epcs_devinfo_t *dev, int argc, char * const argv[])
{
ulong addr,off,cnt;
ulong sz;
ulong err;
if (argc < 5) {
printf ("USAGE: epcs write addr offset count\n");
return;
}
if ((epcs_status_rd() & dev->prot_mask) != 0) {
printf ( "epcs: device protected.\n");
return;
}
sz = 1 << dev->size;
addr = simple_strtoul (argv[2], NULL, 16);
off = simple_strtoul (argv[3], NULL, 16);
cnt = simple_strtoul (argv[4], NULL, 16);
if (off > sz) {
printf ("offset is greater than device size"
"... aborting.\n");
return;
}
if ((off + cnt) > sz) {
printf ("request exceeds device size"
"... truncating.\n");
cnt = sz - off;
}
printf ("epcs: write %08lx -> %06lx (0x%lx bytes)\n",
addr, off, cnt);
epcs_write (addr, off, cnt);
if (epcs_verify (addr, off, cnt, &err) != 0)
printf ("epcs: write error at offset %06lx\n", err);
return;
}
static
void do_epcs_verify (struct epcs_devinfo_t *dev, int argc, char * const argv[])
{
ulong addr,off,cnt;
ulong sz;
ulong err;
if (argc < 5) {
printf ("USAGE: epcs verify addr offset count\n");
return;
}
sz = 1 << dev->size;
addr = simple_strtoul (argv[2], NULL, 16);
off = simple_strtoul (argv[3], NULL, 16);
cnt = simple_strtoul (argv[4], NULL, 16);
if (off > sz) {
printf ("offset is greater than device size"
"... aborting.\n");
return;
}
if ((off + cnt) > sz) {
printf ("request exceeds device size"
"... truncating.\n");
cnt = sz - off;
}
printf ("epcs: verify %08lx -> %06lx (0x%lx bytes)\n",
addr, off, cnt);
if (epcs_verify (addr, off, cnt, &err) != 0)
printf ("epcs: verify error at offset %06lx\n", err);
return;
}
/*-----------------------------------------------------------------------*/
int do_epcs (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int len;
struct epcs_devinfo_t *dev = epcs_dev_find ();
if (!dev) {
printf ("epcs: device not found.\n");
return (-1);
}
if (argc < 2) {
do_epcs_info (dev, argc, argv);
return (0);
}
len = strlen (argv[1]);
if (strncmp ("info", argv[1], len) == 0) {
do_epcs_info (dev, argc, argv);
} else if (strncmp ("erase", argv[1], len) == 0) {
do_epcs_erase (dev, argc, argv);
} else if (strncmp ("protect", argv[1], len) == 0) {
do_epcs_protect (dev, argc, argv);
} else if (strncmp ("read", argv[1], len) == 0) {
do_epcs_read (dev, argc, argv);
} else if (strncmp ("write", argv[1], len) == 0) {
do_epcs_write (dev, argc, argv);
} else if (strncmp ("verify", argv[1], len) == 0) {
do_epcs_verify (dev, argc, argv);
} else {
printf ("epcs: unknown operation: %s\n", argv[1]);
}
return (0);
}
/*-----------------------------------------------------------------------*/
U_BOOT_CMD( epcs, 5, 0, do_epcs, SHORT_HELP, LONG_HELP );
#endif /* CONFIG_NIOS_EPCS */

View file

@ -0,0 +1,155 @@
/*
* (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
.set noat
.set nobreak
_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
/*-------------------------------------------------------------*/

View file

@ -0,0 +1,53 @@
/*
* (C) Copyright 2011, Missing Link Electronics
* Joachim Foerster <joachim@missinglinkelectronics.com>
*
* Taken from arch/powerpc/cpu/ppc4xx/fdt.c:
*
* (C) Copyright 2007-2008
* Stefan Roese, DENX Software Engineering, sr@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 <common.h>
#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
#include <libfdt.h>
#include <libfdt_env.h>
#include <fdt_support.h>
DECLARE_GLOBAL_DATA_PTR;
void __ft_board_setup(void *blob, bd_t *bd)
{
ft_cpu_setup(blob, bd);
}
void ft_board_setup(void *blob, bd_t *bd) \
__attribute__((weak, alias("__ft_board_setup")));
void ft_cpu_setup(void *blob, bd_t *bd)
{
/*
* Fixup all ethernet nodes
* Note: aliases in the dts are required for this
*/
fdt_fixup_ethernet(blob);
}
#endif /* CONFIG_OF_LIBFDT && CONFIG_OF_BOARD_SETUP */

View file

@ -0,0 +1,280 @@
/*
* (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/types.h>
#include <asm/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(CONFIG_SYS_NIOS_TMRBASE) && !defined(CONFIG_SYS_NIOS_TMRIRQ)
#error CONFIG_SYS_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)
{
nios_timer_t *tmr =(nios_timer_t *)CONFIG_SYS_NIOS_TMRBASE;
/* From Embedded Peripherals Handbook:
*
* "When the hardware is configured with Writeable period
* disabled, writing to one of the period_n registers causes
* the counter to reset to the fixed Timeout Period specified
* at system generation time."
*
* Here we force a reload to prevent early timeouts from
* get_timer() when the interrupt period is greater than
* than 1 msec.
*
* Simply write to periodl with its own value to force an
* internal counter reload, THEN reset the timestamp.
*/
writel (readl (&tmr->periodl), &tmr->periodl);
timestamp = 0;
/* From Embedded Peripherals Handbook:
*
* "Writing to one of the period_n registers stops the internal
* counter, except when the hardware is configured with Start/Stop
* control bits off. If Start/Stop control bits is off, writing
* either register does not stop the counter."
*
* In order to accomodate either configuration, the control
* register is re-written. If the counter is stopped, it will
* be restarted. If it is running, the write is essentially
* a nop.
*/
writel (NIOS_TIMER_ITO | NIOS_TIMER_CONT | NIOS_TIMER_START,
&tmr->control);
}
ulong get_timer (ulong base)
{
WATCHDOG_RESET ();
return (timestamp - base);
}
/*
* This function is derived from Blackfin code (read timebase as long long).
* On Nios2 it just returns the timer value.
*/
unsigned long long get_ticks(void)
{
return get_timer(0);
}
/*
* This function is derived from Blackfin code.
* On Nios2 it returns the number of timer ticks per second.
*/
ulong get_tbclk(void)
{
ulong tbclk;
tbclk = CONFIG_SYS_HZ;
return tbclk;
}
/* The board must handle this interrupt if a timer is not
* provided.
*/
#if defined(CONFIG_SYS_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.
*/
writel (0, &tmr->status);
timestamp += CONFIG_SYS_NIOS_TMRMS;
#ifdef CONFIG_STATUS_LED
status_led_tick(timestamp);
#endif
}
static void tmr_init (void)
{
nios_timer_t *tmr =(nios_timer_t *)CONFIG_SYS_NIOS_TMRBASE;
writel (0, &tmr->status);
writel (0, &tmr->control);
writel (NIOS_TIMER_STOP, &tmr->control);
#if defined(CONFIG_SYS_NIOS_TMRCNT)
writel (CONFIG_SYS_NIOS_TMRCNT & 0xffff, &tmr->periodl);
writel ((CONFIG_SYS_NIOS_TMRCNT >> 16) & 0xffff, &tmr->periodh);
#endif
writel (NIOS_TIMER_ITO | NIOS_TIMER_CONT | NIOS_TIMER_START,
&tmr->control);
irq_install_handler (CONFIG_SYS_NIOS_TMRIRQ, tmr_isr, (void *)tmr);
}
#endif /* CONFIG_SYS_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(CONFIG_SYS_NIOS_TMRBASE)
tmr_init ();
#endif
enable_interrupts ();
return (0);
}
/*************************************************************************/
#if defined(CONFIG_CMD_IRQ)
int do_irqinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const 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

View file

@ -0,0 +1,202 @@
/*
* (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-offsets.h>
#include <config.h>
#include <version.h>
/*************************************************************************
* RESTART
************************************************************************/
.text
.global _start
_start:
wrctl status, r0 /* Disable interrupts */
/* 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.
*/
ori r4, r0, %lo(CONFIG_SYS_ICACHELINE_SIZE)
movhi r5, %hi(CONFIG_SYS_ICACHE_SIZE)
ori r5, r5, %lo(CONFIG_SYS_ICACHE_SIZE)
0: initi r5
sub r5, r5, r4
bgt r5, r0, 0b
br _except_end /* Skip the tramp */
/* EXCEPTION TRAMPOLINE -- the following gets copied
* to the exception address (below), but is otherwise at the
* default exception vector offset (0x0020).
*/
_except_start:
movhi et, %hi(_exception)
ori et, et, %lo(_exception)
jmp et
_except_end:
/* INTERRUPTS -- for now, all interrupts masked and globally
* disabled.
*/
wrctl ienable, r0 /* All disabled */
/* DCACHE INIT -- if dcache not implemented, initd behaves as
* nop.
*/
movhi r4, %hi(CONFIG_SYS_DCACHELINE_SIZE)
ori r4, r4, %lo(CONFIG_SYS_DCACHELINE_SIZE)
movhi r5, %hi(CONFIG_SYS_DCACHE_SIZE)
ori r5, r5, %lo(CONFIG_SYS_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 __bss_end__.
*/
movhi r5, %hi(__bss_start)
ori r5, r5, %lo(__bss_start)
movhi r6, %hi(__bss_end__)
ori r6, r6, %lo(__bss_end__)
beq r5, r6, 5f
4: stwio r0, 0(r5)
addi r5, r5, 4
bne r5, r6, 4b
5:
/* 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. Define CONFIG_ROM_STUBS to prevent
* the copy (e.g. exception in flash or in other
* softare/firmware component).
*/
#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(CONFIG_SYS_EXCEPTION_ADDR)
ori r6, r6, %lo(CONFIG_SYS_EXCEPTION_ADDR)
beq r4, r6, 7f /* Skip if at proper addr */
6: ldwio r7, 0(r4)
stwio r7, 0(r6)
addi r4, r4, 4
addi r6, r6, 4
bne r4, r5, 6b
7:
#endif
/* STACK INIT -- zero top two words for call back chain.
*/
movhi sp, %hi(CONFIG_SYS_INIT_SP)
ori sp, sp, %lo(CONFIG_SYS_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
/*
* 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 (CONFIG_SYS_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
.data
.globl version_string
version_string:
.ascii U_BOOT_VERSION_STRING, "\0"

View file

@ -0,0 +1,58 @@
/*
* (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>
#if defined (CONFIG_SYS_NIOS_SYSID_BASE)
#include <command.h>
#include <asm/io.h>
#include <nios2-io.h>
#include <linux/time.h>
void display_sysid (void)
{
struct nios_sysid_t *sysid = (struct nios_sysid_t *)CONFIG_SYS_NIOS_SYSID_BASE;
struct tm t;
char asc[32];
time_t stamp;
stamp = readl (&sysid->timestamp);
localtime_r (&stamp, &t);
asctime_r (&t, asc);
printf ("SYSID : %08lx, %s", readl (&sysid->id), asc);
}
int do_sysid (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
display_sysid ();
return (0);
}
U_BOOT_CMD(
sysid, 1, 1, do_sysid,
"display Nios-II system id",
""
);
#endif /* CONFIG_SYS_NIOS_SYSID_BASE */

View file

@ -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 ();
}

View file

@ -0,0 +1,135 @@
/*
* (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
*/
OUTPUT_FORMAT("elf32-littlenios2")
OUTPUT_ARCH(nios2)
ENTRY(_start)
SECTIONS
{
.text :
{
arch/nios2/cpu/start.o (.text)
*(.text)
*(.text.*)
*(.gnu.linkonce.t*)
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
*(.gnu.linkonce.r*)
}
. = ALIGN (4);
_etext = .;
PROVIDE (etext = .);
/* CMD TABLE - sandwich this in between text and data so
* the initialization code relocates the command table as
* well -- admittedly, this is just pure laziness ;-)
*/
__u_boot_cmd_start = .;
.u_boot_cmd :
{
*(.u_boot_cmd)
}
. = ALIGN(4);
__u_boot_cmd_end = .;
/* INIT DATA sections - "Small" data (see the gcc -G option)
* is always gp-relative. Here we make all init data sections
* adjacent to simplify the startup code -- and provide
* the global pointer for gp-relative access.
*/
_data = .;
.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
}
. = ALIGN(16);
_gp = .; /* Global pointer addr */
PROVIDE (gp = .);
.sdata :
{
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
}
. = ALIGN(4);
_edata = .;
PROVIDE (edata = .);
/* UNINIT DATA - Small uninitialized data is first so it's
* adjacent to sdata and can be referenced via gp. The normal
* bss follows. We keep it adjacent to simplify init code.
*/
__bss_start = .;
.sbss (NOLOAD) :
{
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
}
. = ALIGN(4);
.bss (NOLOAD) :
{
*(.bss)
*(.bss.*)
*(.dynbss)
*(COMMON)
*(.scommon)
}
. = ALIGN(4);
__bss_end__ = .;
PROVIDE (end = .);
/* DEBUG -- symbol table, string table, etc. etc.
*/
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

View file

@ -0,0 +1,32 @@
/*
* (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
*/
#ifndef __ASM_NIOS2_BITOPS_H_
#define __ASM_NIOS2_BITOPS_H_
/* copied from linux-2.6/include/asm-generic/bitops */
#include <asm/bitops/atomic.h>
#include <asm/bitops/non-atomic.h>
#include <asm/bitops/ffs.h>
#endif /* __ASM_NIOS2_BITOPS_H */

View file

@ -0,0 +1,189 @@
#ifndef _ASM_GENERIC_BITOPS_ATOMIC_H_
#define _ASM_GENERIC_BITOPS_ATOMIC_H_
#include <asm/types.h>
#include <asm/system.h>
#ifdef CONFIG_SMP
#include <asm/spinlock.h>
#include <asm/cache.h> /* we use L1_CACHE_BYTES */
/* Use an array of spinlocks for our atomic_ts.
* Hash function to index into a different SPINLOCK.
* Since "a" is usually an address, use one spinlock per cacheline.
*/
# define ATOMIC_HASH_SIZE 4
# define ATOMIC_HASH(a) (&(__atomic_hash[ (((unsigned long) a)/L1_CACHE_BYTES) & (ATOMIC_HASH_SIZE-1) ]))
extern raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned;
/* Can't use raw_spin_lock_irq because of #include problems, so
* this is the substitute */
#define _atomic_spin_lock_irqsave(l,f) do { \
raw_spinlock_t *s = ATOMIC_HASH(l); \
local_irq_save(f); \
__raw_spin_lock(s); \
} while(0)
#define _atomic_spin_unlock_irqrestore(l,f) do { \
raw_spinlock_t *s = ATOMIC_HASH(l); \
__raw_spin_unlock(s); \
local_irq_restore(f); \
} while(0)
#else
# define _atomic_spin_lock_irqsave(l,f) do { local_irq_save(f); } while (0)
# define _atomic_spin_unlock_irqrestore(l,f) do { local_irq_restore(f); } while (0)
#endif
/*
* NMI events can occur at any time, including when interrupts have been
* disabled by *_irqsave(). So you can get NMI events occurring while a
* *_bit function is holding a spin lock. If the NMI handler also wants
* to do bit manipulation (and they do) then you can get a deadlock
* between the original caller of *_bit() and the NMI handler.
*
* by Keith Owens
*/
/**
* set_bit - Atomically set a bit in memory
* @nr: the bit to set
* @addr: the address to start counting from
*
* This function is atomic and may not be reordered. See __set_bit()
* if you do not require the atomic guarantees.
*
* Note: there are no guarantees that this function will not be reordered
* on non x86 architectures, so if you are writing portable code,
* make sure not to rely on its reordering guarantees.
*
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*/
static inline void set_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long flags;
_atomic_spin_lock_irqsave(p, flags);
*p |= mask;
_atomic_spin_unlock_irqrestore(p, flags);
}
/**
* clear_bit - Clears a bit in memory
* @nr: Bit to clear
* @addr: Address to start counting from
*
* clear_bit() is atomic and may not be reordered. However, it does
* not contain a memory barrier, so if it is used for locking purposes,
* you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
* in order to ensure changes are visible on other processors.
*/
static inline void clear_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long flags;
_atomic_spin_lock_irqsave(p, flags);
*p &= ~mask;
_atomic_spin_unlock_irqrestore(p, flags);
}
/**
* change_bit - Toggle a bit in memory
* @nr: Bit to change
* @addr: Address to start counting from
*
* change_bit() is atomic and may not be reordered. It may be
* reordered on other architectures than x86.
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*/
static inline void change_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long flags;
_atomic_spin_lock_irqsave(p, flags);
*p ^= mask;
_atomic_spin_unlock_irqrestore(p, flags);
}
/**
* test_and_set_bit - Set a bit and return its old value
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It may be reordered on other architectures than x86.
* It also implies a memory barrier.
*/
static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old;
unsigned long flags;
_atomic_spin_lock_irqsave(p, flags);
old = *p;
*p = old | mask;
_atomic_spin_unlock_irqrestore(p, flags);
return (old & mask) != 0;
}
/**
* test_and_clear_bit - Clear a bit and return its old value
* @nr: Bit to clear
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It can be reorderdered on other architectures other than x86.
* It also implies a memory barrier.
*/
static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old;
unsigned long flags;
_atomic_spin_lock_irqsave(p, flags);
old = *p;
*p = old & ~mask;
_atomic_spin_unlock_irqrestore(p, flags);
return (old & mask) != 0;
}
/**
* test_and_change_bit - Change a bit and return its old value
* @nr: Bit to change
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old;
unsigned long flags;
_atomic_spin_lock_irqsave(p, flags);
old = *p;
*p = old ^ mask;
_atomic_spin_unlock_irqrestore(p, flags);
return (old & mask) != 0;
}
#endif /* _ASM_GENERIC_BITOPS_ATOMIC_H */

View file

@ -0,0 +1,41 @@
#ifndef _ASM_GENERIC_BITOPS_FFS_H_
#define _ASM_GENERIC_BITOPS_FFS_H_
/**
* ffs - find first bit set
* @x: the word to search
*
* This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from the above ffz (man ffs).
*/
static inline int ffs(int x)
{
int r = 1;
if (!x)
return 0;
if (!(x & 0xffff)) {
x >>= 16;
r += 16;
}
if (!(x & 0xff)) {
x >>= 8;
r += 8;
}
if (!(x & 0xf)) {
x >>= 4;
r += 4;
}
if (!(x & 3)) {
x >>= 2;
r += 2;
}
if (!(x & 1)) {
x >>= 1;
r += 1;
}
return r;
}
#endif /* _ASM_GENERIC_BITOPS_FFS_H_ */

View file

@ -0,0 +1,108 @@
#ifndef _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
#define _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
#include <asm/types.h>
/**
* __set_bit - Set a bit in memory
* @nr: the bit to set
* @addr: the address to start counting from
*
* Unlike set_bit(), this function is non-atomic and may be reordered.
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*/
static inline void __set_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
*p |= mask;
}
static inline void __clear_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
*p &= ~mask;
}
/**
* __change_bit - Toggle a bit in memory
* @nr: the bit to change
* @addr: the address to start counting from
*
* Unlike change_bit(), this function is non-atomic and may be reordered.
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*/
static inline void __change_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
*p ^= mask;
}
/**
* __test_and_set_bit - Set a bit and return its old value
* @nr: Bit to set
* @addr: Address to count from
*
* This operation is non-atomic and can be reordered.
* If two examples of this operation race, one can appear to succeed
* but actually fail. You must protect multiple accesses with a lock.
*/
static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old = *p;
*p = old | mask;
return (old & mask) != 0;
}
/**
* __test_and_clear_bit - Clear a bit and return its old value
* @nr: Bit to clear
* @addr: Address to count from
*
* This operation is non-atomic and can be reordered.
* If two examples of this operation race, one can appear to succeed
* but actually fail. You must protect multiple accesses with a lock.
*/
static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old = *p;
*p = old & ~mask;
return (old & mask) != 0;
}
/* WARNING: non atomic and it can be reordered! */
static inline int __test_and_change_bit(int nr,
volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old = *p;
*p = old ^ mask;
return (old & mask) != 0;
}
/**
* test_bit - Determine whether a bit is set
* @nr: bit number to test
* @addr: Address to start counting from
*/
static inline int test_bit(int nr, const volatile unsigned long *addr)
{
return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
}
#endif /* _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ */

View file

@ -0,0 +1,36 @@
/*
* (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
*/
#ifndef __ASM_NIOS2_BYTEORDER_H_
#define __ASM_NIOS2_BYTEORDER_H_
#include <asm/types.h>
#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
# define __BYTEORDER_HAS_U64__
# define __SWAB_64_THRU_32__
#endif
#include <linux/byteorder/little_endian.h>
#endif /* __ASM_NIOS2_BYTEORDER_H_ */

View file

@ -0,0 +1,41 @@
/*
* (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
*/
#ifndef __ASM_NIOS2_CACHE_H_
#define __ASM_NIOS2_CACHE_H_
extern void flush_dcache (unsigned long start, unsigned long size);
extern void flush_icache (unsigned long start, unsigned long size);
/*
* Valid L1 data cache line sizes for the NIOS2 architecture are 4, 16, and 32
* bytes. If the board configuration has not specified one we default to the
* largest of these values for alignment of DMA buffers.
*/
#ifdef CONFIG_SYS_CACHELINE_SIZE
#define ARCH_DMA_MINALIGN CONFIG_SYS_CACHELINE_SIZE
#else
#define ARCH_DMA_MINALIGN 32
#endif
#endif /* __ASM_NIOS2_CACHE_H_ */

View file

@ -0,0 +1,24 @@
/*
* Copyright 2009 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#ifndef _ASM_CONFIG_H_
#define _ASM_CONFIG_H_
#endif

View file

@ -0,0 +1,23 @@
#ifndef __ASM_NIOS2_DMA_MAPPING_H
#define __ASM_NIOS2_DMA_MAPPING_H
/* dma_alloc_coherent() return cache-line aligned allocation which is mapped
* to uncached io region.
*
* IO_REGION_BASE should be defined in board config header file
* 0x80000000 for nommu, 0xe0000000 for mmu
*/
static inline void *dma_alloc_coherent(size_t len, unsigned long *handle)
{
void *addr = malloc(len + CONFIG_SYS_DCACHELINE_SIZE);
if (!addr)
return 0;
flush_dcache((unsigned long)addr, len + CONFIG_SYS_DCACHELINE_SIZE);
*handle = ((unsigned long)addr +
(CONFIG_SYS_DCACHELINE_SIZE - 1)) &
~(CONFIG_SYS_DCACHELINE_SIZE - 1) & ~(IO_REGION_BASE);
return (void *)(*handle | IO_REGION_BASE);
}
#endif /* __ASM_NIOS2_DMA_MAPPING_H */

View file

@ -0,0 +1 @@
#include <asm-generic/errno.h>

View file

@ -0,0 +1,59 @@
/*
* (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
*/
#ifndef __ASM_NIOS2_GLOBALDATA_H_
#define __ASM_NIOS2_GLOBALDATA_H_
typedef struct global_data {
bd_t *bd;
unsigned long flags;
unsigned long baudrate;
unsigned long cpu_clk; /* CPU clock in Hz! */
unsigned long have_console; /* serial_init() was called */
#ifdef CONFIG_PRE_CONSOLE_BUFFER
unsigned long precon_buf_idx; /* Pre-Console buffer index */
#endif
phys_size_t ram_size; /* RAM size */
unsigned long env_addr; /* Address of Environment struct */
unsigned long env_valid; /* Checksum of Environment valid */
#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
unsigned long post_log_word; /* Record POST activities */
unsigned long post_log_res; /* success of POST test */
unsigned long post_init_f_time; /* When post_init_f started */
#endif
void **jt; /* Standalone app jump table */
char env_buf[32]; /* buffer for getenv() before reloc. */
} gd_t;
/* flags */
#define GD_FLG_RELOC 0x00001 /* Code was relocated to RAM */
#define GD_FLG_DEVINIT 0x00002 /* Devices have been initialized */
#define GD_FLG_SILENT 0x00004 /* Silent mode */
#define GD_FLG_POSTFAIL 0x00008 /* Critical POST test failed */
#define GD_FLG_POSTSTOP 0x00010 /* POST seqeunce aborted */
#define GD_FLG_LOGINIT 0x00020 /* Log Buffer has been initialized */
#define GD_FLG_DISABLE_CONSOLE 0x00040 /* Disable console (in & out) */
#define GD_FLG_ENV_READY 0x00080 /* Environment imported into hash table */
#define DECLARE_GLOBAL_DATA_PTR register gd_t *gd asm ("gp")
#endif /* __ASM_NIOS2_GLOBALDATA_H_ */

View file

@ -0,0 +1,79 @@
/*
* nios2 gpio driver
*
* This gpio core is described in http://nioswiki.com/GPIO
* bit[0] data
* bit[1] output enable
*
* When CONFIG_SYS_GPIO_BASE is not defined, the board may either
* provide its own driver or the altera_pio driver may be used.
*
* Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _ASM_NIOS2_GPIO_H_
#define _ASM_NIOS2_GPIO_H_
#ifdef CONFIG_SYS_GPIO_BASE
#include <asm/io.h>
static inline int gpio_request(unsigned gpio, const char *label)
{
return 0;
}
static inline int gpio_free(unsigned gpio)
{
return 0;
}
static inline int gpio_direction_input(unsigned gpio)
{
writel(1, CONFIG_SYS_GPIO_BASE + (gpio << 2));
return 0;
}
static inline int gpio_direction_output(unsigned gpio, int value)
{
writel(value ? 3 : 2, CONFIG_SYS_GPIO_BASE + (gpio << 2));
return 0;
}
static inline int gpio_get_value(unsigned gpio)
{
return readl(CONFIG_SYS_GPIO_BASE + (gpio << 2));
}
static inline void gpio_set_value(unsigned gpio, int value)
{
writel(value ? 3 : 2, CONFIG_SYS_GPIO_BASE + (gpio << 2));
}
static inline int gpio_is_valid(int number)
{
return ((unsigned)number) < CONFIG_SYS_GPIO_WIDTH;
}
#else
#ifdef CONFIG_ALTERA_PIO
extern int altera_pio_init(u32 base, u8 width, char iot,
u32 rstval, u32 negmask,
const char *label);
extern void altera_pio_info(void);
#define gpio_status() altera_pio_info()
#endif
extern int gpio_request(unsigned gpio, const char *label);
extern int gpio_free(unsigned gpio);
extern int gpio_direction_input(unsigned gpio);
extern int gpio_direction_output(unsigned gpio, int value);
extern int gpio_get_value(unsigned gpio);
extern void gpio_set_value(unsigned gpio, int value);
extern int gpio_is_valid(int number);
#endif /* CONFIG_SYS_GPIO_BASE */
#endif /* _ASM_NIOS2_GPIO_H_ */

View file

@ -0,0 +1,130 @@
/*
* (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
*/
#ifndef __ASM_NIOS2_IO_H_
#define __ASM_NIOS2_IO_H_
static inline void sync(void)
{
__asm__ __volatile__ ("sync" : : : "memory");
}
/*
* Given a physical address and a length, return a virtual address
* that can be used to access the memory range with the caching
* properties specified by "flags".
*/
#define MAP_NOCACHE (0)
#define MAP_WRCOMBINE (0)
#define MAP_WRBACK (0)
#define MAP_WRTHROUGH (0)
static inline void *
map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
{
return (void *)paddr;
}
/*
* Take down a mapping set up by map_physmem().
*/
static inline void unmap_physmem(void *vaddr, unsigned long flags)
{
}
static inline phys_addr_t virt_to_phys(void * vaddr)
{
return (phys_addr_t)(vaddr);
}
extern unsigned char inb (unsigned char *port);
extern unsigned short inw (unsigned short *port);
extern unsigned inl (unsigned port);
#define __raw_writeb(v,a) (*(volatile unsigned char *)(a) = (v))
#define __raw_writew(v,a) (*(volatile unsigned short *)(a) = (v))
#define __raw_writel(v,a) (*(volatile unsigned int *)(a) = (v))
#define __raw_readb(a) (*(volatile unsigned char *)(a))
#define __raw_readw(a) (*(volatile unsigned short *)(a))
#define __raw_readl(a) (*(volatile unsigned int *)(a))
#define readb(addr)\
({unsigned char val;\
asm volatile( "ldbio %0, 0(%1)" :"=r"(val) : "r" (addr)); val;})
#define readw(addr)\
({unsigned short val;\
asm volatile( "ldhio %0, 0(%1)" :"=r"(val) : "r" (addr)); val;})
#define readl(addr)\
({unsigned long val;\
asm volatile( "ldwio %0, 0(%1)" :"=r"(val) : "r" (addr)); val;})
#define writeb(val,addr)\
asm volatile ("stbio %0, 0(%1)" : : "r" (val), "r" (addr))
#define writew(val,addr)\
asm volatile ("sthio %0, 0(%1)" : : "r" (val), "r" (addr))
#define writel(val,addr)\
asm volatile ("stwio %0, 0(%1)" : : "r" (val), "r" (addr))
#define inb(addr) readb(addr)
#define inw(addr) readw(addr)
#define inl(addr) readl(addr)
#define outb(val, addr) writeb(val,addr)
#define outw(val, addr) writew(val,addr)
#define outl(val, addr) writel(val,addr)
static inline void insb (unsigned long port, void *dst, unsigned long count)
{
unsigned char *p = dst;
while (count--) *p++ = inb (port);
}
static inline void insw (unsigned long port, void *dst, unsigned long count)
{
unsigned short *p = dst;
while (count--) *p++ = inw (port);
}
static inline void insl (unsigned long port, void *dst, unsigned long count)
{
unsigned long *p = dst;
while (count--) *p++ = inl (port);
}
static inline void outsb (unsigned long port, const void *src, unsigned long count)
{
const unsigned char *p = src;
while (count--) outb (*p++, port);
}
static inline void outsw (unsigned long port, const void *src, unsigned long count)
{
const unsigned short *p = src;
while (count--) outw (*p++, port);
}
static inline void outsl (unsigned long port, const void *src, unsigned long count)
{
const unsigned long *p = src;
while (count--) outl (*p++, port);
}
#endif /* __ASM_NIOS2_IO_H_ */

View file

@ -0,0 +1,131 @@
/*
* (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
*/
#ifndef __ASM_NIOS2_OPCODES_H_
#define __ASM_NIOS2_OPCODES_H_
#define OPCODE_OP(inst) ((inst) & 0x3f)
#define OPCODE_OPX(inst) (((inst)>>11) & 0x3f)
#define OPCODE_RA(inst) (((inst)>>27) & 01f)
#define OPCODE_RB(inst) (((inst)>>22) & 01f)
#define OPCODE_RC(inst) (((inst)>>17) & 01f)
/* I-TYPE (immediate) and J-TYPE (jump) opcodes
*/
#define OPCODE_CALL 0x00
#define OPCODE_LDBU 0x03
#define OPCODE_ADDI 0x04
#define OPCODE_STB 0x05
#define OPCODE_BR 0x06
#define OPCODE_LDB 0x07
#define OPCODE_CMPGEI 0x08
#define OPCODE_LDHU 0x0B
#define OPCODE_ANDI 0x0C
#define OPCODE_STH 0x0D
#define OPCODE_BGE 0x0E
#define OPCODE_LDH 0x0F
#define OPCODE_CMPLTI 0x10
#define OPCODE_XORI 0x1C
#define OPCODE_ORI 0x14
#define OPCODE_STW 0x15
#define OPCODE_BLT 0x16
#define OPCODE_LDW 0x17
#define OPCODE_CMPNEI 0x18
#define OPCODE_BNE 0x1E
#define OPCODE_CMPEQI 0x20
#define OPCODE_LDBUIO 0x23
#define OPCODE_MULI 0x24
#define OPCODE_STBIO 0x25
#define OPCODE_BEQ 0x26
#define OPCODE_LDBIO 0x27
#define OPCODE_CMPGEUI 0x28
#define OPCODE_ANDHI 0x2C
#define OPCODE_STHIO 0x2D
#define OPCODE_BGEU 0x2E
#define OPCODE_LDHIO 0x2F
#define OPCODE_CMPLTUI 0x30
#define OPCODE_CUSTOM 0x32
#define OPCODE_INITD 0x33
#define OPCODE_ORHI 0x34
#define OPCODE_STWIO 0x35
#define OPCODE_BLTU 0x36
#define OPCODE_LDWIO 0x37
#define OPCODE_RTYPE 0x3A
#define OPCODE_LDHUIO 0x2B
#define OPCODE_FLUSHD 0x3B
#define OPCODE_XORHI 0x3C
/* R-Type (register) OPX field encodings
*/
#define OPCODE_ERET 0x01
#define OPCODE_ROLI 0x02
#define OPCODE_ROL 0x03
#define OPCODE_FLUSHP 0x04
#define OPCODE_RET 0x05
#define OPCODE_NOR 0x06
#define OPCODE_MULXUU 0x07
#define OPCODE_CMPGE 0x08
#define OPCODE_BRET 0x09
#define OPCODE_ROR 0x0B
#define OPCODE_FLUSHI 0x0C
#define OPCODE_JMP 0x0D
#define OPCODE_AND 0x0E
#define OPCODE_CMPLT 0x10
#define OPCODE_SLLI 0x12
#define OPCODE_SLL 0x13
#define OPCODE_OR 0x16
#define OPCODE_MULXSU 0x17
#define OPCODE_CMPNE 0x18
#define OPCODE_SRLI 0x1A
#define OPCODE_SRL 0x1B
#define OPCODE_NEXTPC 0x1C
#define OPCODE_CALLR 0x1D
#define OPCODE_XOR 0x1E
#define OPCODE_MULXSS 0x1F
#define OPCODE_CMPEQ 0x20
#define OPCODE_CMPLTU 0x30
#define OPCODE_ADD 0x31
#define OPCODE_DIVU 0x24
#define OPCODE_DIV 0x25
#define OPCODE_RDCTL 0x26
#define OPCODE_MUL 0x27
#define OPCODE_CMPGEU 0x28
#define OPCODE_TRAP 0x2D
#define OPCODE_WRCTL 0x2E
#define OPCODE_BREAK 0x34
#define OPCODE_SYNC 0x36
#define OPCODE_INITI 0x29
#define OPCODE_SUB 0x39
#define OPCODE_SRAI 0x3A
#define OPCODE_SRA 0x3B
/*Full instruction encodings for R-Type, without the R's ;-)
*
* TODO: BREAK, BRET, ERET, RET, SYNC (as needed)
*/
#define OPC_TRAP 0x003b683a
#endif /* __ASM_NIOS2_OPCODES_H_ */

View file

@ -0,0 +1,63 @@
#ifndef __ASM_NIOS2_POSIX_TYPES_H_
#define __ASM_NIOS2_POSIX_TYPES_H_
/*
* This file is generally used by user-level software, so you need to
* be a little careful about namespace pollution etc. Also, we cannot
* assume GCC is being used.
*/
typedef unsigned short __kernel_dev_t;
typedef unsigned long __kernel_ino_t;
typedef unsigned short __kernel_mode_t;
typedef unsigned short __kernel_nlink_t;
typedef long __kernel_off_t;
typedef int __kernel_pid_t;
typedef unsigned short __kernel_ipc_pid_t;
typedef unsigned short __kernel_uid_t;
typedef unsigned short __kernel_gid_t;
typedef unsigned long __kernel_size_t;
typedef long __kernel_ssize_t;
typedef int __kernel_ptrdiff_t;
typedef long __kernel_time_t;
typedef long __kernel_suseconds_t;
typedef long __kernel_clock_t;
typedef int __kernel_daddr_t;
typedef char * __kernel_caddr_t;
typedef unsigned short __kernel_uid16_t;
typedef unsigned short __kernel_gid16_t;
typedef unsigned int __kernel_uid32_t;
typedef unsigned int __kernel_gid32_t;
typedef unsigned short __kernel_old_uid_t;
typedef unsigned short __kernel_old_gid_t;
#ifdef __GNUC__
typedef long long __kernel_loff_t;
#endif
typedef struct {
#if defined(__KERNEL__) || defined(__USE_ALL)
int val[2];
#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
int __val[2];
#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
} __kernel_fsid_t;
#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
#undef __FD_SET
#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
#undef __FD_CLR
#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
#undef __FD_ISSET
#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
#undef __FD_ZERO
#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
#endif /* __ASM_NIOS2_POSIX_TYPES_H_ */

View file

@ -0,0 +1,26 @@
/*
* (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
*/
#ifndef __ASM_NIOS2_PROCESSOR_H_
#define __ASM_NIOS2_PROCESSOR_H_
#endif /* __ASM_NIOS2_PROCESSOR_H_ */

View file

@ -0,0 +1,28 @@
/*
* (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
*/
#ifndef __ASM_NIOS2_PSR_H_
#define __ASM_NIOS2_PSR_H_
#endif /* __ASM_NIOS2_PSR_H_ */

View file

@ -0,0 +1,33 @@
/*
* (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
*/
#ifndef __ASM_NIOS2_PTRACE_H_
#define __ASM_NIOS2_PTRACE_H_
struct pt_regs {
unsigned reg[32];
unsigned status;
};
#endif /* __ASM_NIOS2_PTRACE_H_ */

View file

@ -0,0 +1,31 @@
/*
* (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
*/
#ifndef __ASM_STATUS_LED_H__
#define __ASM_STATUS_LED_H__
typedef unsigned led_id_t;
extern void __led_init (led_id_t mask, int state);
extern void __led_set (led_id_t mask, int state);
inline void __led_toggle (led_id_t mask);
#endif /* __ASM_STATUS_LED_H__ */

View file

@ -0,0 +1,47 @@
/*
* (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
*/
#ifndef __ASM_NIOS2_STRING_H_
#define __ASM_NIOS2_STRING_H_
#undef __HAVE_ARCH_STRRCHR
extern char * strrchr(const char * s, int c);
#undef __HAVE_ARCH_STRCHR
extern char * strchr(const char * s, int c);
#undef __HAVE_ARCH_MEMCPY
extern void * memcpy(void *, const void *, __kernel_size_t);
#undef __HAVE_ARCH_MEMMOVE
extern void * memmove(void *, const void *, __kernel_size_t);
#undef __HAVE_ARCH_MEMCHR
extern void * memchr(const void *, int, __kernel_size_t);
#undef __HAVE_ARCH_MEMSET
extern void * memset(void *, int, __kernel_size_t);
#undef __HAVE_ARCH_MEMZERO
extern void memzero(void *ptr, __kernel_size_t n);
#endif /* __ASM_NIOS2_STRING_H_ */

View file

@ -0,0 +1,64 @@
/*
* (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
*/
#ifndef __ASM_NIOS2_SYSTEM_H_
#define __ASM_NIOS2_SYSTEM_H_
#define local_irq_enable() __asm__ __volatile__ ( \
"rdctl r8, status\n" \
"ori r8, r8, 1\n" \
"wrctl status, r8\n" \
: : : "r8")
#define local_irq_disable() __asm__ __volatile__ ( \
"rdctl r8, status\n" \
"andi r8, r8, 0xfffe\n" \
"wrctl status, r8\n" \
: : : "r8")
#define local_save_flags(x) __asm__ __volatile__ ( \
"rdctl r8, status\n" \
"mov %0, r8\n" \
: "=r" (x) : : "r8", "memory")
#define local_irq_restore(x) __asm__ __volatile__ ( \
"mov r8, %0\n" \
"wrctl status, r8\n" \
: : "r" (x) : "r8", "memory")
/* For spinlocks etc */
#define local_irq_save(x) do { local_save_flags(x); local_irq_disable(); } \
while (0)
#define irqs_disabled() \
({ \
unsigned long flags; \
local_save_flags(flags); \
((flags & NIOS2_STATUS_PIE_MSK) == 0x0); \
})
/* indirect call to go beyond 256MB limitation of toolchain */
#define nios2_callr(addr) __asm__ __volatile__ ( \
"callr %0" \
: : "r" (addr))
#endif /* __ASM_NIOS2_SYSTEM_H */

View file

@ -0,0 +1,60 @@
#ifndef __ASM_NIOS2_TYPES_H_
#define __ASM_NIOS2_TYPES_H_
/*
* This file is never included by application software unless
* explicitly requested (e.g., via linux/types.h) in which case the
* application is Linux specific so (user-) name space pollution is
* not a major issue. However, for interoperability, libraries still
* need to be careful to avoid a name clashes.
*/
typedef unsigned short umode_t;
/*
* __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
* header files exported to user space
*/
typedef __signed__ char __s8;
typedef unsigned char __u8;
typedef __signed__ short __s16;
typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
#if defined(__GNUC__)
__extension__ typedef __signed__ long long __s64;
__extension__ typedef unsigned long long __u64;
#endif
/*
* These aren't exported outside the kernel to avoid name space clashes
*/
#ifdef __KERNEL__
typedef signed char s8;
typedef unsigned char u8;
typedef signed short s16;
typedef unsigned short u16;
typedef signed int s32;
typedef unsigned int u32;
typedef signed long long s64;
typedef unsigned long long u64;
#define BITS_PER_LONG 32
/* Dma addresses are 32-bits wide. */
typedef u32 dma_addr_t;
typedef unsigned long phys_addr_t;
typedef unsigned long phys_size_t;
#endif /* __KERNEL__ */
#endif /* __ASM_NIOS2_TYPES_H */

View file

@ -0,0 +1,48 @@
/*
* (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
*
********************************************************************
* NOTE: This header file defines an interface to U-Boot. Including
* this (unmodified) header file in another file is considered normal
* use of U-Boot, and does *not* fall under the heading of "derived
* work".
********************************************************************
*/
#ifndef __ASM_NIOS2_U_BOOT_H_
#define __ASM_NIOS2_U_BOOT_H_
typedef struct bd_info {
unsigned long bi_memstart; /* start of DRAM memory */
phys_size_t bi_memsize; /* size of DRAM memory in bytes */
unsigned long bi_flashstart; /* start of FLASH memory */
unsigned long bi_flashsize; /* size of FLASH memory */
unsigned long bi_flashoffset; /* reserved area for startup monitor */
unsigned long bi_sramstart; /* start of SRAM memory */
unsigned long bi_sramsize; /* size of SRAM memory */
unsigned long bi_baudrate; /* Console Baudrate */
} bd_t;
/* For image.h:image_check_target_arch() */
#define IH_ARCH_DEFAULT IH_ARCH_NIOS2
#endif /* __ASM_NIOS2_U_BOOT_H_ */

View file

@ -0,0 +1,6 @@
#ifndef _ASM_NIOS2_UNALIGNED_H
#define _ASM_NIOS2_UNALIGNED_H
#include <asm-generic/unaligned.h>
#endif /* _ASM_NIOS2_UNALIGNED_H */

View file

@ -0,0 +1,48 @@
#
# (C) Copyright 2000-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$(ARCH).o
SOBJS-y += cache.o
COBJS-y += board.o
COBJS-y += bootm.o
COBJS-y += libgcc.o
COBJS-y += time.o
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
$(LIB): $(obj).depend $(OBJS)
$(call cmd_link_o_target, $(OBJS))
#########################################################################
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################

View file

@ -0,0 +1,176 @@
/*
* (C) Copyright 2003, Psyent Corporation <www.psyent.com>
* Scott McNutt <smcnutt@psyent.com>
*
* (C) Copyright 2000-2002
* 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 <common.h>
#include <stdio_dev.h>
#include <watchdog.h>
#include <malloc.h>
#include <mmc.h>
#include <net.h>
#ifdef CONFIG_STATUS_LED
#include <status_led.h>
#endif
#if defined(CONFIG_SYS_NIOS_EPCSBASE)
#include <nios2-epcs.h>
#endif
#ifdef CONFIG_CMD_NAND
#include <nand.h> /* cannot even include nand.h if it isnt configured */
#endif
DECLARE_GLOBAL_DATA_PTR;
/*
* All attempts to come up with a "common" initialization sequence
* that works for all boards and architectures failed: some of the
* requirements are just _too_ different. To get rid of the resulting
* mess of board dependend #ifdef'ed code we now make the whole
* initialization sequence configurable to the user.
*
* The requirements for any new initalization function is simple: it
* receives a pointer to the "global data" structure as it's only
* argument, and returns an integer return code, where 0 means
* "continue" and != 0 means "fatal error, hang the system".
*/
typedef int (init_fnc_t) (void);
/************************************************************************
* Initialization sequence *
***********************************************************************/
init_fnc_t *init_sequence[] = {
#if defined(CONFIG_BOARD_EARLY_INIT_F)
board_early_init_f, /* Call board-specific init code early.*/
#endif
#if defined(CONFIG_SYS_NIOS_EPCSBASE)
epcs_reset,
#endif
env_init,
serial_init,
console_init_f,
display_options,
checkcpu,
checkboard,
NULL, /* Terminate this list */
};
/***********************************************************************/
void board_init (void)
{
bd_t *bd;
init_fnc_t **init_fnc_ptr;
static gd_t gd_data;
static bd_t bd_data;
/* Pointer is writable since we allocated a register for it. */
gd = &gd_data;
/* compiler optimization barrier needed for GCC >= 3.4 */
__asm__ __volatile__("": : :"memory");
gd->bd = &bd_data;
gd->baudrate = CONFIG_BAUDRATE;
gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
bd = gd->bd;
bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;
bd->bi_memsize = CONFIG_SYS_SDRAM_SIZE;
#ifndef CONFIG_SYS_NO_FLASH
bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
#endif
#if defined(CONFIG_SYS_SRAM_BASE) && defined(CONFIG_SYS_SRAM_SIZE)
bd->bi_sramstart= CONFIG_SYS_SRAM_BASE;
bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE;
#endif
bd->bi_baudrate = CONFIG_BAUDRATE;
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
WATCHDOG_RESET ();
if ((*init_fnc_ptr) () != 0) {
hang ();
}
}
WATCHDOG_RESET ();
/* The Malloc area is immediately below the monitor copy in RAM */
mem_malloc_init(CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN);
#ifndef CONFIG_SYS_NO_FLASH
WATCHDOG_RESET ();
bd->bi_flashsize = flash_init();
#endif
#ifdef CONFIG_CMD_NAND
puts("NAND: ");
nand_init();
#endif
#ifdef CONFIG_GENERIC_MMC
puts("MMC: ");
mmc_initialize(bd);
#endif
WATCHDOG_RESET ();
env_relocate();
WATCHDOG_RESET ();
stdio_init();
jumptable_init();
console_init_r();
WATCHDOG_RESET ();
interrupt_init ();
#if defined(CONFIG_BOARD_LATE_INIT)
board_late_init ();
#endif
#if defined(CONFIG_CMD_NET)
puts ("Net: ");
eth_initialize (bd);
#endif
/* main_loop */
for (;;) {
WATCHDOG_RESET ();
main_loop ();
}
}
/***********************************************************************/
void hang (void)
{
disable_interrupts ();
puts("### ERROR ### Please reset board ###\n");
for (;;);
}

View file

@ -0,0 +1,71 @@
/*
* (C) Copyright 2003, 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 <command.h>
#include <asm/byteorder.h>
#include <asm/cache.h>
#define NIOS_MAGIC 0x534f494e /* enable command line and initrd passing */
int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images)
{
void (*kernel)(int, int, int, char *) = (void *)images->ep;
char *commandline = getenv("bootargs");
ulong initrd_start = images->rd_start;
ulong initrd_end = images->rd_end;
char *of_flat_tree = NULL;
#if defined(CONFIG_OF_LIBFDT)
/* did generic code already find a device tree? */
if (images->ft_len)
of_flat_tree = images->ft_addr;
#endif
if (!of_flat_tree && argc > 3)
of_flat_tree = (char *)simple_strtoul(argv[3], NULL, 16);
if (of_flat_tree)
initrd_end = (ulong)of_flat_tree;
if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
return 1;
/* flushes data and instruction caches before calling the kernel */
disable_interrupts();
flush_dcache((ulong)kernel, CONFIG_SYS_DCACHE_SIZE);
flush_icache((ulong)kernel, CONFIG_SYS_ICACHE_SIZE);
debug("bootargs=%s @ 0x%lx\n", commandline, (ulong)&commandline);
debug("initrd=0x%lx-0x%lx\n", (ulong)initrd_start, (ulong)initrd_end);
/* kernel parameters passing
* r4 : NIOS magic
* r5 : initrd start
* r6 : initrd end or fdt
* r7 : kernel command line
* fdt is passed to kernel via r6, the same as initrd_end. fdt will be
* verified with fdt magic. when both initrd and fdt are used at the
* same time, fdt must follow immediately after initrd.
*/
kernel(NIOS_MAGIC, initrd_start, initrd_end, commandline);
/* does not return */
return 1;
}

View file

@ -0,0 +1,84 @@
/*
* (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>
.text
.global flush_dcache
flush_dcache:
add r5, r5, r4
movhi r8, %hi(CONFIG_SYS_DCACHELINE_SIZE)
ori r8, r8, %lo(CONFIG_SYS_DCACHELINE_SIZE)
0: flushd 0(r4)
add r4, r4, r8
bltu r4, r5, 0b
ret
.global flush_icache
flush_icache:
add r5, r5, r4
movhi r8, %hi(CONFIG_SYS_ICACHELINE_SIZE)
ori r8, r8, %lo(CONFIG_SYS_ICACHELINE_SIZE)
1: flushi r4
add r4, r4, r8
bltu r4, r5, 1b
ret
.global flush_dcache_range
flush_dcache_range:
movhi r8, %hi(CONFIG_SYS_DCACHELINE_SIZE)
ori r8, r8, %lo(CONFIG_SYS_DCACHELINE_SIZE)
0: flushd 0(r4)
add r4, r4, r8
bltu r4, r5, 0b
ret
.global flush_cache
flush_cache:
add r5, r5, r4
mov r9, r4
mov r10, r5
movhi r8, %hi(CONFIG_SYS_DCACHELINE_SIZE)
ori r8, r8, %lo(CONFIG_SYS_DCACHELINE_SIZE)
0: flushd 0(r4)
add r4, r4, r8
bltu r4, r5, 0b
mov r4, r9
mov r5, r10
movhi r8, %hi(CONFIG_SYS_ICACHELINE_SIZE)
ori r8, r8, %lo(CONFIG_SYS_ICACHELINE_SIZE)
1: flushi r4
add r4, r4, r8
bltu r4, r5, 1b
sync
flushp
ret

View file

@ -0,0 +1,592 @@
/*
* This file is part of GNU CC.
*
* GNU CC 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, or (at your
* option) any later version.
*
* GNU CC 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 GNU CC; see the file COPYING. If not, write
* to the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
typedef unsigned int UWtype;
typedef unsigned int UHWtype;
typedef unsigned long long UDWtype;
#define W_TYPE_SIZE 32
typedef unsigned char UQItype;
typedef long SItype;
typedef unsigned long USItype;
typedef long long DItype;
typedef unsigned long long DSItype;
#include "longlong.h"
typedef int word_type;
typedef long Wtype;
typedef long long DWtype;
struct DWstruct { Wtype low, high;};
typedef union
{
struct DWstruct s;
DWtype ll;
} DWunion;
#define BITS_PER_UNIT 8
UDWtype
__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp);
const UQItype __clz_tab[256] =
{
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
};
DWtype
__ashldi3 (DWtype u, word_type b)
{
if (b == 0)
return u;
const DWunion uu = {.ll = u};
const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
DWunion w;
if (bm <= 0)
{
w.s.low = 0;
w.s.high = (UWtype) uu.s.low << -bm;
}
else
{
const UWtype carries = (UWtype) uu.s.low >> bm;
w.s.low = (UWtype) uu.s.low << b;
w.s.high = ((UWtype) uu.s.high << b) | carries;
}
return w.ll;
}
DWtype
__ashrdi3 (DWtype u, word_type b)
{
if (b == 0)
return u;
const DWunion uu = {.ll = u};
const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
DWunion w;
if (bm <= 0)
{
/* w.s.high = 1..1 or 0..0 */
w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
w.s.low = uu.s.high >> -bm;
}
else
{
const UWtype carries = (UWtype) uu.s.high << bm;
w.s.high = uu.s.high >> b;
w.s.low = ((UWtype) uu.s.low >> b) | carries;
}
return w.ll;
}
DWtype
__lshrdi3 (DWtype u, word_type b)
{
if (b == 0)
return u;
const DWunion uu = {.ll = u};
const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
DWunion w;
if (bm <= 0)
{
w.s.high = 0;
w.s.low = (UWtype) uu.s.high >> -bm;
}
else
{
const UWtype carries = (UWtype) uu.s.high << bm;
w.s.high = (UWtype) uu.s.high >> b;
w.s.low = ((UWtype) uu.s.low >> b) | carries;
}
return w.ll;
}
word_type
__cmpdi2 (DWtype a, DWtype b)
{
const DWunion au = {.ll = a};
const DWunion bu = {.ll = b};
if (au.s.high < bu.s.high)
return 0;
else if (au.s.high > bu.s.high)
return 2;
if ((UWtype) au.s.low < (UWtype) bu.s.low)
return 0;
else if ((UWtype) au.s.low > (UWtype) bu.s.low)
return 2;
return 1;
}
UDWtype
__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
{
const DWunion nn = {.ll = n};
const DWunion dd = {.ll = d};
DWunion rr;
UWtype d0, d1, n0, n1, n2;
UWtype q0, q1;
UWtype b, bm;
d0 = dd.s.low;
d1 = dd.s.high;
n0 = nn.s.low;
n1 = nn.s.high;
#if !UDIV_NEEDS_NORMALIZATION
if (d1 == 0)
{
if (d0 > n1)
{
/* 0q = nn / 0D */
udiv_qrnnd (q0, n0, n1, n0, d0);
q1 = 0;
/* Remainder in n0. */
}
else
{
/* qq = NN / 0d */
if (d0 == 0)
d0 = 1 / d0; /* Divide intentionally by zero. */
udiv_qrnnd (q1, n1, 0, n1, d0);
udiv_qrnnd (q0, n0, n1, n0, d0);
/* Remainder in n0. */
}
if (rp != 0)
{
rr.s.low = n0;
rr.s.high = 0;
*rp = rr.ll;
}
}
#else /* UDIV_NEEDS_NORMALIZATION */
if (d1 == 0)
{
if (d0 > n1)
{
/* 0q = nn / 0D */
count_leading_zeros (bm, d0);
if (bm != 0)
{
/* Normalize, i.e. make the most significant bit of the
denominator set. */
d0 = d0 << bm;
n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
n0 = n0 << bm;
}
udiv_qrnnd (q0, n0, n1, n0, d0);
q1 = 0;
/* Remainder in n0 >> bm. */
}
else
{
/* qq = NN / 0d */
if (d0 == 0)
d0 = 1 / d0; /* Divide intentionally by zero. */
count_leading_zeros (bm, d0);
if (bm == 0)
{
/* From (n1 >= d0) /\ (the most significant bit of d0 is set),
conclude (the most significant bit of n1 is set) /\ (the
leading quotient digit q1 = 1).
This special case is necessary, not an optimization.
(Shifts counts of W_TYPE_SIZE are undefined.) */
n1 -= d0;
q1 = 1;
}
else
{
/* Normalize. */
b = W_TYPE_SIZE - bm;
d0 = d0 << bm;
n2 = n1 >> b;
n1 = (n1 << bm) | (n0 >> b);
n0 = n0 << bm;
udiv_qrnnd (q1, n1, n2, n1, d0);
}
/* n1 != d0... */
udiv_qrnnd (q0, n0, n1, n0, d0);
/* Remainder in n0 >> bm. */
}
if (rp != 0)
{
rr.s.low = n0 >> bm;
rr.s.high = 0;
*rp = rr.ll;
}
}
#endif /* UDIV_NEEDS_NORMALIZATION */
else
{
if (d1 > n1)
{
/* 00 = nn / DD */
q0 = 0;
q1 = 0;
/* Remainder in n1n0. */
if (rp != 0)
{
rr.s.low = n0;
rr.s.high = n1;
*rp = rr.ll;
}
}
else
{
/* 0q = NN / dd */
count_leading_zeros (bm, d1);
if (bm == 0)
{
/* From (n1 >= d1) /\ (the most significant bit of d1 is set),
conclude (the most significant bit of n1 is set) /\ (the
quotient digit q0 = 0 or 1).
This special case is necessary, not an optimization. */
/* The condition on the next line takes advantage of that
n1 >= d1 (true due to program flow). */
if (n1 > d1 || n0 >= d0)
{
q0 = 1;
sub_ddmmss (n1, n0, n1, n0, d1, d0);
}
else
q0 = 0;
q1 = 0;
if (rp != 0)
{
rr.s.low = n0;
rr.s.high = n1;
*rp = rr.ll;
}
}
else
{
UWtype m1, m0;
/* Normalize. */
b = W_TYPE_SIZE - bm;
d1 = (d1 << bm) | (d0 >> b);
d0 = d0 << bm;
n2 = n1 >> b;
n1 = (n1 << bm) | (n0 >> b);
n0 = n0 << bm;
udiv_qrnnd (q0, n1, n2, n1, d1);
umul_ppmm (m1, m0, q0, d0);
if (m1 > n1 || (m1 == n1 && m0 > n0))
{
q0--;
sub_ddmmss (m1, m0, m1, m0, d1, d0);
}
q1 = 0;
/* Remainder in (n1n0 - m1m0) >> bm. */
if (rp != 0)
{
sub_ddmmss (n1, n0, n1, n0, m1, m0);
rr.s.low = (n1 << b) | (n0 >> bm);
rr.s.high = n1 >> bm;
*rp = rr.ll;
}
}
}
}
const DWunion ww = {{.low = q0, .high = q1}};
return ww.ll;
}
DWtype
__divdi3 (DWtype u, DWtype v)
{
word_type c = 0;
DWunion uu = {.ll = u};
DWunion vv = {.ll = v};
DWtype w;
if (uu.s.high < 0)
c = ~c,
uu.ll = -uu.ll;
if (vv.s.high < 0)
c = ~c,
vv.ll = -vv.ll;
w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
if (c)
w = -w;
return w;
}
DWtype
__negdi2 (DWtype u)
{
const DWunion uu = {.ll = u};
const DWunion w = { {.low = -uu.s.low,
.high = -uu.s.high - ((UWtype) -uu.s.low > 0) } };
return w.ll;
}
DWtype
__muldi3 (DWtype u, DWtype v)
{
const DWunion uu = {.ll = u};
const DWunion vv = {.ll = v};
DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)};
w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
+ (UWtype) uu.s.high * (UWtype) vv.s.low);
return w.ll;
}
DWtype
__moddi3 (DWtype u, DWtype v)
{
word_type c = 0;
DWunion uu = {.ll = u};
DWunion vv = {.ll = v};
DWtype w;
if (uu.s.high < 0)
c = ~c,
uu.ll = -uu.ll;
if (vv.s.high < 0)
vv.ll = -vv.ll;
(void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w);
if (c)
w = -w;
return w;
}
word_type
__ucmpdi2 (DWtype a, DWtype b)
{
const DWunion au = {.ll = a};
const DWunion bu = {.ll = b};
if ((UWtype) au.s.high < (UWtype) bu.s.high)
return 0;
else if ((UWtype) au.s.high > (UWtype) bu.s.high)
return 2;
if ((UWtype) au.s.low < (UWtype) bu.s.low)
return 0;
else if ((UWtype) au.s.low > (UWtype) bu.s.low)
return 2;
return 1;
}
UDWtype
__udivdi3 (UDWtype n, UDWtype d)
{
return __udivmoddi4 (n, d, (UDWtype *) 0);
}
UDWtype
__umoddi3 (UDWtype u, UDWtype v)
{
UDWtype w;
(void) __udivmoddi4 (u, v, &w);
return w;
}
static USItype
udivmodsi4(USItype num, USItype den, word_type modwanted)
{
USItype bit = 1;
USItype res = 0;
while (den < num && bit && !(den & (1L<<31)))
{
den <<=1;
bit <<=1;
}
while (bit)
{
if (num >= den)
{
num -= den;
res |= bit;
}
bit >>=1;
den >>=1;
}
if (modwanted) return num;
return res;
}
SItype
__divsi3 (SItype a, SItype b)
{
word_type neg = 0;
SItype res;
if (a < 0)
{
a = -a;
neg = !neg;
}
if (b < 0)
{
b = -b;
neg = !neg;
}
res = udivmodsi4 (a, b, 0);
if (neg)
res = -res;
return res;
}
SItype
__udivsi3 (SItype a, SItype b)
{
return udivmodsi4 (a, b, 0);
}
SItype
__modsi3 (SItype a, SItype b)
{
word_type neg = 0;
SItype res;
if (a < 0)
{
a = -a;
neg = 1;
}
if (b < 0)
b = -b;
res = udivmodsi4 (a, b, 1);
if (neg)
res = -res;
return res;
}
SItype
__mulsi3 (SItype a, SItype b)
{
SItype res = 0;
USItype cnt = a;
while (cnt)
{
if (cnt & 1)
{
res += b;
}
b <<= 1;
cnt >>= 1;
}
return res;
}
SItype
__umodsi3 (SItype a, SItype b)
{
return udivmodsi4 (a, b, 1);
}
int
__gcc_bcmp (const unsigned char *s1, const unsigned char *s2, unsigned long size)
{
while (size > 0)
{
const unsigned char c1 = *s1++, c2 = *s2++;
if (c1 != c2)
return c1 - c2;
size--;
}
return 0;
}

View file

@ -0,0 +1,263 @@
/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2004,
2005 Free Software Foundation, Inc.
This definition file 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, or (at your option) any later version.
This definition file 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., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
/* You have to define the following before including this file:
UWtype -- An unsigned type, default type for operations (typically a "word")
UHWtype -- An unsigned type, at least half the size of UWtype.
UDWtype -- An unsigned type, at least twice as large a UWtype
W_TYPE_SIZE -- size in bits of UWtype
UQItype -- Unsigned 8 bit type.
SItype, USItype -- Signed and unsigned 32 bit types.
DItype, UDItype -- Signed and unsigned 64 bit types.
On a 32 bit machine UWtype should typically be USItype;
on a 64 bit machine, UWtype should typically be UDItype. */
#define __BITS4 (W_TYPE_SIZE / 4)
#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
#ifndef W_TYPE_SIZE
#define W_TYPE_SIZE 32
#define UWtype USItype
#define UHWtype USItype
#define UDWtype UDItype
#endif
extern const UQItype __clz_tab[256];
/* Define auxiliary asm macros.
1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two
UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype
word product in HIGH_PROD and LOW_PROD.
2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a
UDWtype product. This is just a variant of umul_ppmm.
3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
denominator) divides a UDWtype, composed by the UWtype integers
HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less
than DENOMINATOR for correct operation. If, in addition, the most
significant bit of DENOMINATOR must be 1, then the pre-processor symbol
UDIV_NEEDS_NORMALIZATION is defined to 1.
4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
denominator). Like udiv_qrnnd but the numbers are signed. The quotient
is rounded towards 0.
5) count_leading_zeros(count, x) counts the number of zero-bits from the
msb to the first nonzero bit in the UWtype X. This is the number of
steps X needs to be shifted left to set the msb. Undefined for X == 0,
unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value.
6) count_trailing_zeros(count, x) like count_leading_zeros, but counts
from the least significant end.
7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
high_addend_2, low_addend_2) adds two UWtype integers, composed by
HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2
respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow
(i.e. carry out) is not stored anywhere, and is lost.
8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE
and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
and is lost.
If any of these macros are left undefined for a particular CPU,
C macros are used. */
/* The CPUs come in alphabetical order below.
Please add support for more CPUs here, or improve the current support
for the CPUs below!
(E.g. WE32100, IBM360.) */
/* Snipped per CPU support */
/* If this machine has no inline assembler, use C macros. */
#if !defined (add_ssaaaa)
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
do { \
UWtype __x; \
__x = (al) + (bl); \
(sh) = (ah) + (bh) + (__x < (al)); \
(sl) = __x; \
} while (0)
#endif
#if !defined (sub_ddmmss)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
do { \
UWtype __x; \
__x = (al) - (bl); \
(sh) = (ah) - (bh) - (__x > (al)); \
(sl) = __x; \
} while (0)
#endif
/* If we lack umul_ppmm but have smul_ppmm, define umul_ppmm in terms of
smul_ppmm. */
#if !defined (umul_ppmm) && defined (smul_ppmm)
#define umul_ppmm(w1, w0, u, v) \
do { \
UWtype __w1; \
UWtype __xm0 = (u), __xm1 = (v); \
smul_ppmm (__w1, w0, __xm0, __xm1); \
(w1) = __w1 + (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1) \
+ (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0); \
} while (0)
#endif
/* If we still don't have umul_ppmm, define it using plain C. */
#if !defined (umul_ppmm)
#define umul_ppmm(w1, w0, u, v) \
do { \
UWtype __x0, __x1, __x2, __x3; \
UHWtype __ul, __vl, __uh, __vh; \
\
__ul = __ll_lowpart (u); \
__uh = __ll_highpart (u); \
__vl = __ll_lowpart (v); \
__vh = __ll_highpart (v); \
\
__x0 = (UWtype) __ul * __vl; \
__x1 = (UWtype) __ul * __vh; \
__x2 = (UWtype) __uh * __vl; \
__x3 = (UWtype) __uh * __vh; \
\
__x1 += __ll_highpart (__x0);/* this can't give carry */ \
__x1 += __x2; /* but this indeed can */ \
if (__x1 < __x2) /* did we get it? */ \
__x3 += __ll_B; /* yes, add it in the proper pos. */ \
\
(w1) = __x3 + __ll_highpart (__x1); \
(w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
} while (0)
#endif
#if !defined (__umulsidi3)
#define __umulsidi3(u, v) \
({DWunion __w; \
umul_ppmm (__w.s.high, __w.s.low, u, v); \
__w.ll; })
#endif
/* Define this unconditionally, so it can be used for debugging. */
#define __udiv_qrnnd_c(q, r, n1, n0, d) \
do { \
UWtype __d1, __d0, __q1, __q0; \
UWtype __r1, __r0, __m; \
__d1 = __ll_highpart (d); \
__d0 = __ll_lowpart (d); \
\
__r1 = (n1) % __d1; \
__q1 = (n1) / __d1; \
__m = (UWtype) __q1 * __d0; \
__r1 = __r1 * __ll_B | __ll_highpart (n0); \
if (__r1 < __m) \
{ \
__q1--, __r1 += (d); \
if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
if (__r1 < __m) \
__q1--, __r1 += (d); \
} \
__r1 -= __m; \
\
__r0 = __r1 % __d1; \
__q0 = __r1 / __d1; \
__m = (UWtype) __q0 * __d0; \
__r0 = __r0 * __ll_B | __ll_lowpart (n0); \
if (__r0 < __m) \
{ \
__q0--, __r0 += (d); \
if (__r0 >= (d)) \
if (__r0 < __m) \
__q0--, __r0 += (d); \
} \
__r0 -= __m; \
\
(q) = (UWtype) __q1 * __ll_B | __q0; \
(r) = __r0; \
} while (0)
/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
__udiv_w_sdiv (defined in libgcc or elsewhere). */
#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
#define udiv_qrnnd(q, r, nh, nl, d) \
do { \
USItype __r; \
(q) = __udiv_w_sdiv (&__r, nh, nl, d); \
(r) = __r; \
} while (0)
#endif
/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
#if !defined (udiv_qrnnd)
#define UDIV_NEEDS_NORMALIZATION 1
#define udiv_qrnnd __udiv_qrnnd_c
#endif
#if !defined (count_leading_zeros)
#define count_leading_zeros(count, x) \
do { \
UWtype __xr = (x); \
UWtype __a; \
\
if (W_TYPE_SIZE <= 32) \
{ \
__a = __xr < ((UWtype)1<<2*__BITS4) \
? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4) \
: (__xr < ((UWtype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
} \
else \
{ \
for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \
if (((__xr >> __a) & 0xff) != 0) \
break; \
} \
\
(count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
} while (0)
#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
#endif
#if !defined (count_trailing_zeros)
/* Define count_trailing_zeros using count_leading_zeros. The latter might be
defined in asm, but if it is not, the C version above is good enough. */
#define count_trailing_zeros(count, x) \
do { \
UWtype __ctz_x = (x); \
UWtype __ctz_c; \
count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \
(count) = W_TYPE_SIZE - 1 - __ctz_c; \
} while (0)
#endif
#ifndef UDIV_NEEDS_NORMALIZATION
#define UDIV_NEEDS_NORMALIZATION 0
#endif

View file

@ -0,0 +1,38 @@
/*
* (C) Copyright 2003, 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>
extern void dly_clks( unsigned long ticks );
void __udelay(unsigned long usec)
{
/* The Nios core doesn't have a timebase, so we do our
* best for now and call a low-level loop that counts
* cpu clocks.
*/
unsigned long cnt = (CONFIG_SYS_CLK_FREQ/1000000) * usec;
dly_clks (cnt);
}