mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-06-09 23:36:03 +09:00
SPARC: Added support for SPARC LEON3 SOC processor.
Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
This commit is contained in:
parent
bf3d8b3116
commit
1e9a164e22
3
Makefile
3
Makefile
|
@ -2898,6 +2898,9 @@ r2dplus_config : unconfig
|
||||||
#========================================================================
|
#========================================================================
|
||||||
# SPARC
|
# SPARC
|
||||||
#========================================================================
|
#========================================================================
|
||||||
|
#########################################################################
|
||||||
|
## LEON3
|
||||||
|
#########################################################################
|
||||||
|
|
||||||
#########################################################################
|
#########################################################################
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
1
README
1
README
|
@ -153,6 +153,7 @@ Directory Hierarchy:
|
||||||
- at32ap Files specific to Atmel AVR32 AP CPUs
|
- at32ap Files specific to Atmel AVR32 AP CPUs
|
||||||
- i386 Files specific to i386 CPUs
|
- i386 Files specific to i386 CPUs
|
||||||
- ixp Files specific to Intel XScale IXP CPUs
|
- ixp Files specific to Intel XScale IXP CPUs
|
||||||
|
- leon3 Files specific to Gaisler LEON3 SPARC CPU
|
||||||
- mcf52x2 Files specific to Freescale ColdFire MCF52x2 CPUs
|
- mcf52x2 Files specific to Freescale ColdFire MCF52x2 CPUs
|
||||||
- mcf5227x Files specific to Freescale ColdFire MCF5227x CPUs
|
- mcf5227x Files specific to Freescale ColdFire MCF5227x CPUs
|
||||||
- mcf532x Files specific to Freescale ColdFire MCF5329 CPUs
|
- mcf532x Files specific to Freescale ColdFire MCF5329 CPUs
|
||||||
|
|
54
cpu/leon3/Makefile
Normal file
54
cpu/leon3/Makefile
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#
|
||||||
|
# (C) Copyright 2003-2006
|
||||||
|
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||||
|
#
|
||||||
|
# See file CREDITS for list of people who contributed to this
|
||||||
|
# project.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License as
|
||||||
|
# published by the Free Software Foundation; either version 2 of
|
||||||
|
# the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
# MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
|
||||||
|
include $(TOPDIR)/config.mk
|
||||||
|
|
||||||
|
LIB = $(obj)lib$(CPU).a
|
||||||
|
|
||||||
|
START = start.o
|
||||||
|
SOBJS =
|
||||||
|
COBJS = cpu_init.o serial.o cpu.o ambapp.o interrupts.o prom.o usb_uhci.o
|
||||||
|
|
||||||
|
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||||
|
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||||
|
START := $(addprefix $(obj),$(START))
|
||||||
|
|
||||||
|
all: $(obj).depend $(START) $(LIB)
|
||||||
|
|
||||||
|
$(LIB): $(OBJS)
|
||||||
|
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||||
|
|
||||||
|
#########################################################################
|
||||||
|
|
||||||
|
# defines $(obj).depend target
|
||||||
|
include $(SRCTREE)/rules.mk
|
||||||
|
|
||||||
|
$(START): $(START:.o=.S)
|
||||||
|
$(CC) -D__ASSEMBLY__ $(DBGFLAGS) $(OPTFLAGS) -D__KERNEL__ -DTEXT_BASE=$(TEXT_BASE) \
|
||||||
|
-I$(TOPDIR)/include -fno-builtin -ffreestanding -nostdinc -isystem $(gccincdir) -pipe \
|
||||||
|
$(PLATFORM_CPPFLAGS) -Wall -Wstrict-prototypes \
|
||||||
|
-I$(TOPDIR)/board -c -o $(START) $(START:.o=.S)
|
||||||
|
|
||||||
|
sinclude $(obj).depend
|
||||||
|
|
||||||
|
#########################################################################
|
339
cpu/leon3/ambapp.c
Normal file
339
cpu/leon3/ambapp.c
Normal file
|
@ -0,0 +1,339 @@
|
||||||
|
/* Gaisler AMBA Plug&Play bus scanning. Functions
|
||||||
|
* ending on _nomem is inteded to be used only during
|
||||||
|
* initialization, only registers are used (no ram).
|
||||||
|
*
|
||||||
|
* (C) Copyright 2007
|
||||||
|
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
|
||||||
|
*
|
||||||
|
* See file CREDITS for list of people who contributed to this
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <command.h>
|
||||||
|
#include <ambapp.h>
|
||||||
|
|
||||||
|
static int ambapp_apb_scan(unsigned int vendor, /* Plug&Play Vendor ID */
|
||||||
|
unsigned int driver, /* Plug&Play Device ID */
|
||||||
|
ambapp_apbdev * dev, /* Result(s) is placed here */
|
||||||
|
int index, /* Index of device to start copying Plug&Play
|
||||||
|
* info into dev
|
||||||
|
*/
|
||||||
|
int max_cnt /* Maximal count that dev can hold, if dev
|
||||||
|
* is NULL function will stop scanning after
|
||||||
|
* max_cnt devices are found.
|
||||||
|
*/
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int i, cnt = 0;
|
||||||
|
unsigned int apbmst_base;
|
||||||
|
ambapp_ahbdev apbmst;
|
||||||
|
apbctrl_pp_dev *apb;
|
||||||
|
|
||||||
|
if (max_cnt == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Get AMBA APB Master */
|
||||||
|
if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_APBMST, &apbmst) != 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get APB CTRL Plug&Play info area */
|
||||||
|
apbmst_base = apbmst.address[0] & LEON3_IO_AREA;
|
||||||
|
apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA);
|
||||||
|
|
||||||
|
for (i = 0; i < LEON3_APB_SLAVES; i++) {
|
||||||
|
if ((amba_vendor(apb->conf) == vendor) &&
|
||||||
|
(amba_device(apb->conf) == driver) && ((index < 0)
|
||||||
|
|| (index-- == 0))) {
|
||||||
|
/* Convert Plug&Play info into a more readable format */
|
||||||
|
cnt++;
|
||||||
|
if (dev) {
|
||||||
|
dev->irq = amba_irq(apb->conf);
|
||||||
|
dev->ver = amba_ver(apb->conf);
|
||||||
|
dev->address =
|
||||||
|
(apbmst_base |
|
||||||
|
(((apb->
|
||||||
|
bar & 0xfff00000) >> 12))) & (((apb->
|
||||||
|
bar &
|
||||||
|
0x0000fff0)
|
||||||
|
<< 4) |
|
||||||
|
0xfff00000);
|
||||||
|
dev++;
|
||||||
|
}
|
||||||
|
/* found max devices? */
|
||||||
|
if (cnt >= max_cnt)
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
/* Get next Plug&Play entry */
|
||||||
|
apb++;
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int ambapp_apb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */
|
||||||
|
register unsigned int driver, /* Plug&Play Device ID */
|
||||||
|
register int index)
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
register ahbctrl_pp_dev *apbmst;
|
||||||
|
register apbctrl_pp_dev *apb;
|
||||||
|
register unsigned int apbmst_base;
|
||||||
|
|
||||||
|
/* APBMST is a AHB Slave */
|
||||||
|
apbmst = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0);
|
||||||
|
if (!apbmst)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
apbmst_base = amba_membar_start(apbmst->bars[0]);
|
||||||
|
if (amba_membar_type(apbmst->bars[0]) == AMBA_TYPE_AHBIO)
|
||||||
|
apbmst_base = AMBA_TYPE_AHBIO_ADDR(apbmst_base);
|
||||||
|
apbmst_base &= LEON3_IO_AREA;
|
||||||
|
|
||||||
|
/* Find the vendor/driver device on the first APB bus */
|
||||||
|
apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA);
|
||||||
|
|
||||||
|
for (i = 0; i < LEON3_APB_SLAVES; i++) {
|
||||||
|
if ((amba_vendor(apb->conf) == vendor) &&
|
||||||
|
(amba_device(apb->conf) == driver) && ((index < 0)
|
||||||
|
|| (index-- == 0))) {
|
||||||
|
/* Convert Plug&Play info info a more readable format */
|
||||||
|
return (apbmst_base | (((apb->bar & 0xfff00000) >> 12)))
|
||||||
|
& (((apb->bar & 0x0000fff0) << 4) | 0xfff00000);
|
||||||
|
}
|
||||||
|
/* Get next Plug&Play entry */
|
||||||
|
apb++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************** APB SLAVES ******************************/
|
||||||
|
|
||||||
|
int ambapp_apb_count(unsigned int vendor, unsigned int driver)
|
||||||
|
{
|
||||||
|
return ambapp_apb_scan(vendor, driver, NULL, 0, LEON3_APB_SLAVES);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ambapp_apb_first(unsigned int vendor,
|
||||||
|
unsigned int driver, ambapp_apbdev * dev)
|
||||||
|
{
|
||||||
|
return ambapp_apb_scan(vendor, driver, dev, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ambapp_apb_next(unsigned int vendor,
|
||||||
|
unsigned int driver, ambapp_apbdev * dev, int index)
|
||||||
|
{
|
||||||
|
return ambapp_apb_scan(vendor, driver, dev, index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ambapp_apbs_first(unsigned int vendor,
|
||||||
|
unsigned int driver, ambapp_apbdev * dev, int max_cnt)
|
||||||
|
{
|
||||||
|
return ambapp_apb_scan(vendor, driver, dev, 0, max_cnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AHB_SCAN_MASTER = 0,
|
||||||
|
AHB_SCAN_SLAVE = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Scan AMBA Plug&Play bus for AMBA AHB Masters or AHB Slaves
|
||||||
|
* for a certain matching Vendor and Device ID.
|
||||||
|
*
|
||||||
|
* Return number of devices found.
|
||||||
|
*
|
||||||
|
* Compact edition...
|
||||||
|
*/
|
||||||
|
static int ambapp_ahb_scan(unsigned int vendor, /* Plug&Play Vendor ID */
|
||||||
|
unsigned int driver, /* Plug&Play Device ID */
|
||||||
|
ambapp_ahbdev * dev, /* Result(s) is placed here */
|
||||||
|
int index, /* Index of device to start copying Plug&Play
|
||||||
|
* info into dev
|
||||||
|
*/
|
||||||
|
int max_cnt, /* Maximal count that dev can hold, if dev
|
||||||
|
* is NULL function will stop scanning after
|
||||||
|
* max_cnt devices are found.
|
||||||
|
*/
|
||||||
|
int type /* Selectes what type of devices to scan.
|
||||||
|
* 0=AHB Masters
|
||||||
|
* 1=AHB Slaves
|
||||||
|
*/
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int i, j, cnt = 0, max_pp_devs;
|
||||||
|
unsigned int addr;
|
||||||
|
ahbctrl_info *info = (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA);
|
||||||
|
ahbctrl_pp_dev *ahb;
|
||||||
|
|
||||||
|
if (max_cnt == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (type == 0) {
|
||||||
|
max_pp_devs = LEON3_AHB_MASTERS;
|
||||||
|
ahb = info->masters;
|
||||||
|
} else {
|
||||||
|
max_pp_devs = LEON3_AHB_SLAVES;
|
||||||
|
ahb = info->slaves;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < max_pp_devs; i++) {
|
||||||
|
if ((amba_vendor(ahb->conf) == vendor) &&
|
||||||
|
(amba_device(ahb->conf) == driver) &&
|
||||||
|
((index < 0) || (index-- == 0))) {
|
||||||
|
/* Convert Plug&Play info info a more readable format */
|
||||||
|
cnt++;
|
||||||
|
if (dev) {
|
||||||
|
dev->irq = amba_irq(ahb->conf);
|
||||||
|
dev->ver = amba_ver(ahb->conf);
|
||||||
|
dev->userdef[0] = ahb->userdef[0];
|
||||||
|
dev->userdef[1] = ahb->userdef[1];
|
||||||
|
dev->userdef[2] = ahb->userdef[2];
|
||||||
|
for (j = 0; j < 4; j++) {
|
||||||
|
addr = amba_membar_start(ahb->bars[j]);
|
||||||
|
if (amba_membar_type(ahb->bars[j]) ==
|
||||||
|
AMBA_TYPE_AHBIO)
|
||||||
|
addr =
|
||||||
|
AMBA_TYPE_AHBIO_ADDR(addr);
|
||||||
|
dev->address[j] = addr;
|
||||||
|
}
|
||||||
|
dev++;
|
||||||
|
}
|
||||||
|
/* found max devices? */
|
||||||
|
if (cnt >= max_cnt)
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
/* Get next Plug&Play entry */
|
||||||
|
ahb++;
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info)
|
||||||
|
{
|
||||||
|
register unsigned int ret;
|
||||||
|
|
||||||
|
if (!ahb)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (info) {
|
||||||
|
default:
|
||||||
|
info = 0;
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
/* Get Address from PnP Info */
|
||||||
|
ret = amba_membar_start(ahb->bars[info]);
|
||||||
|
if (amba_membar_type(ahb->bars[info]) == AMBA_TYPE_AHBIO)
|
||||||
|
ret = AMBA_TYPE_AHBIO_ADDR(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ahbctrl_pp_dev *ambapp_ahb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */
|
||||||
|
register unsigned int driver, /* Plug&Play Device ID */
|
||||||
|
register unsigned int opts, /* 1=slave, 0=master */
|
||||||
|
register int index)
|
||||||
|
{
|
||||||
|
register ahbctrl_pp_dev *ahb;
|
||||||
|
register ahbctrl_info *info =
|
||||||
|
(ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA);
|
||||||
|
register int i;
|
||||||
|
register int max_pp_devs;
|
||||||
|
|
||||||
|
if (opts == 0) {
|
||||||
|
max_pp_devs = LEON3_AHB_MASTERS;
|
||||||
|
ahb = info->masters;
|
||||||
|
} else {
|
||||||
|
max_pp_devs = LEON3_AHB_SLAVES;
|
||||||
|
ahb = info->slaves;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < max_pp_devs; i++) {
|
||||||
|
if ((amba_vendor(ahb->conf) == vendor) &&
|
||||||
|
(amba_device(ahb->conf) == driver) &&
|
||||||
|
((index < 0) || (index-- == 0))) {
|
||||||
|
/* Convert Plug&Play info info a more readable format */
|
||||||
|
return ahb;
|
||||||
|
}
|
||||||
|
/* Get next Plug&Play entry */
|
||||||
|
ahb++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************** AHB MASTERS ******************************/
|
||||||
|
int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver)
|
||||||
|
{
|
||||||
|
/* Get number of devices of this vendor&device ID */
|
||||||
|
return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_MASTERS,
|
||||||
|
AHB_SCAN_MASTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ambapp_ahbmst_first(unsigned int vendor, unsigned int driver,
|
||||||
|
ambapp_ahbdev * dev)
|
||||||
|
{
|
||||||
|
/* find first device of this */
|
||||||
|
return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_MASTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ambapp_ahbmst_next(unsigned int vendor,
|
||||||
|
unsigned int driver, ambapp_ahbdev * dev, int index)
|
||||||
|
{
|
||||||
|
/* find first device of this */
|
||||||
|
return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_MASTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ambapp_ahbmsts_first(unsigned int vendor,
|
||||||
|
unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
|
||||||
|
{
|
||||||
|
/* find first device of this */
|
||||||
|
return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt,
|
||||||
|
AHB_SCAN_MASTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************** AHB SLAVES ******************************/
|
||||||
|
int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver)
|
||||||
|
{
|
||||||
|
/* Get number of devices of this vendor&device ID */
|
||||||
|
return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_SLAVES,
|
||||||
|
AHB_SCAN_SLAVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ambapp_ahbslv_first(unsigned int vendor, unsigned int driver,
|
||||||
|
ambapp_ahbdev * dev)
|
||||||
|
{
|
||||||
|
/* find first device of this */
|
||||||
|
return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_SLAVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ambapp_ahbslv_next(unsigned int vendor,
|
||||||
|
unsigned int driver, ambapp_ahbdev * dev, int index)
|
||||||
|
{
|
||||||
|
/* find first device of this */
|
||||||
|
return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_SLAVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ambapp_ahbslvs_first(unsigned int vendor,
|
||||||
|
unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
|
||||||
|
{
|
||||||
|
/* find first device of this */
|
||||||
|
return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt, AHB_SCAN_SLAVE);
|
||||||
|
}
|
26
cpu/leon3/config.mk
Normal file
26
cpu/leon3/config.mk
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#
|
||||||
|
# (C) Copyright 2003
|
||||||
|
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||||
|
#
|
||||||
|
# See file CREDITS for list of people who contributed to this
|
||||||
|
# project.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License as
|
||||||
|
# published by the Free Software Foundation; either version 2 of
|
||||||
|
# the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
# MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
|
||||||
|
PLATFORM_RELFLAGS += -fPIC
|
||||||
|
|
||||||
|
PLATFORM_CPPFLAGS += -DCONFIG_LEON
|
67
cpu/leon3/cpu.c
Normal file
67
cpu/leon3/cpu.c
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
/* CPU specific code for the LEON3 CPU
|
||||||
|
*
|
||||||
|
* (C) Copyright 2007
|
||||||
|
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
|
||||||
|
*
|
||||||
|
* See file CREDITS for list of people who contributed to this
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <watchdog.h>
|
||||||
|
#include <command.h>
|
||||||
|
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <asm/processor.h>
|
||||||
|
|
||||||
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
extern void _reset_reloc(void);
|
||||||
|
|
||||||
|
int checkcpu(void)
|
||||||
|
{
|
||||||
|
/* check LEON version here */
|
||||||
|
printf("CPU: LEON3\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void cpu_reset(void)
|
||||||
|
{
|
||||||
|
/* Interrupts off */
|
||||||
|
disable_interrupts();
|
||||||
|
|
||||||
|
/* jump to restart in flash */
|
||||||
|
_reset_reloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
int do_reset(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
cpu_reset();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 flash_read64(void *addr)
|
||||||
|
{
|
||||||
|
return __raw_readq(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
254
cpu/leon3/cpu_init.c
Normal file
254
cpu/leon3/cpu_init.c
Normal file
|
@ -0,0 +1,254 @@
|
||||||
|
/* Initializes CPU and basic hardware such as memory
|
||||||
|
* controllers, IRQ controller and system timer 0.
|
||||||
|
*
|
||||||
|
* (C) Copyright 2007
|
||||||
|
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
|
||||||
|
*
|
||||||
|
* See file CREDITS for list of people who contributed to this
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <asm/asi.h>
|
||||||
|
#include <asm/leon.h>
|
||||||
|
#include <ambapp.h>
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
/* reset CPU (jump to 0, without reset) */
|
||||||
|
void start(void);
|
||||||
|
|
||||||
|
/* find & initialize the memory controller */
|
||||||
|
int init_memory_ctrl(void);
|
||||||
|
|
||||||
|
ambapp_dev_irqmp *irqmp = NULL;
|
||||||
|
ambapp_dev_mctrl memctrl;
|
||||||
|
ambapp_dev_gptimer *gptimer = NULL;
|
||||||
|
unsigned int gptimer_irq = 0;
|
||||||
|
int leon3_snooping_avail = 0;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
gd_t gd_area;
|
||||||
|
bd_t bd;
|
||||||
|
} global_data;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Breath some life into the CPU...
|
||||||
|
*
|
||||||
|
* Set up the memory map,
|
||||||
|
* initialize a bunch of registers.
|
||||||
|
*
|
||||||
|
* Run from FLASH/PROM:
|
||||||
|
* - until memory controller is set up, only registers avaiable
|
||||||
|
* - no global variables available for writing
|
||||||
|
* - constants avaiable
|
||||||
|
*/
|
||||||
|
|
||||||
|
void cpu_init_f(void)
|
||||||
|
{
|
||||||
|
/* these varaiable must not be initialized */
|
||||||
|
ambapp_dev_irqmp *irqmp;
|
||||||
|
ambapp_apbdev apbdev;
|
||||||
|
register unsigned int apbmst;
|
||||||
|
|
||||||
|
/* find AMBA APB Master */
|
||||||
|
apbmst = (unsigned int)
|
||||||
|
ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0);
|
||||||
|
if (!apbmst) {
|
||||||
|
/*
|
||||||
|
* no AHB/APB bridge, something is wrong
|
||||||
|
* ==> jump to start (or hang)
|
||||||
|
*/
|
||||||
|
while (1) ;
|
||||||
|
}
|
||||||
|
/* Init memory controller */
|
||||||
|
if (init_memory_ctrl()) {
|
||||||
|
while (1) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************
|
||||||
|
* From here we can use the main memory and the stack.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Find AMBA APB IRQMP Controller */
|
||||||
|
if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev) != 1) {
|
||||||
|
/* no IRQ controller, something is wrong
|
||||||
|
* ==> jump to start (or hang)
|
||||||
|
*/
|
||||||
|
while (1) ;
|
||||||
|
}
|
||||||
|
irqmp = (ambapp_dev_irqmp *) apbdev.address;
|
||||||
|
|
||||||
|
/* initialize the IRQMP */
|
||||||
|
irqmp->ilevel = 0xf; /* all IRQ off */
|
||||||
|
irqmp->iforce = 0;
|
||||||
|
irqmp->ipend = 0;
|
||||||
|
irqmp->iclear = 0xfffe; /* clear all old pending interrupts */
|
||||||
|
irqmp->cpu_mask[0] = 0; /* mask all IRQs on CPU 0 */
|
||||||
|
irqmp->cpu_force[0] = 0; /* no force IRQ on CPU 0 */
|
||||||
|
|
||||||
|
/* cache */
|
||||||
|
}
|
||||||
|
|
||||||
|
void cpu_init_f2(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* initialize higher level parts of CPU like time base and timers
|
||||||
|
*/
|
||||||
|
int cpu_init_r(void)
|
||||||
|
{
|
||||||
|
ambapp_apbdev apbdev;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find AMBA APB IRQMP Controller,
|
||||||
|
* When we come so far we know there is a IRQMP available
|
||||||
|
*/
|
||||||
|
ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev);
|
||||||
|
irqmp = (ambapp_dev_irqmp *) apbdev.address;
|
||||||
|
|
||||||
|
/* timer */
|
||||||
|
if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_GPTIMER, &apbdev) != 1) {
|
||||||
|
printf("cpu_init_r: gptimer not found!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
gptimer = (ambapp_dev_gptimer *) apbdev.address;
|
||||||
|
gptimer_irq = apbdev.irq;
|
||||||
|
|
||||||
|
/* initialize prescaler common to all timers to 1MHz */
|
||||||
|
gptimer->scalar = gptimer->scalar_reload =
|
||||||
|
(((CONFIG_SYS_CLK_FREQ / 1000) + 500) / 1000) - 1;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find & setup memory controller */
|
||||||
|
int init_memory_ctrl()
|
||||||
|
{
|
||||||
|
register ambapp_dev_mctrl *mctrl;
|
||||||
|
register ambapp_dev_sdctrl *sdctrl;
|
||||||
|
register ambapp_dev_ddrspa *ddrspa;
|
||||||
|
register ambapp_dev_ddr2spa *ddr2spa;
|
||||||
|
register ahbctrl_pp_dev *ahb;
|
||||||
|
register unsigned int base;
|
||||||
|
register int not_found_mctrl = -1;
|
||||||
|
|
||||||
|
/* find ESA Memory controller */
|
||||||
|
base = ambapp_apb_next_nomem(VENDOR_ESA, ESA_MCTRL, 0);
|
||||||
|
if (base) {
|
||||||
|
mctrl = (ambapp_dev_mctrl *) base;
|
||||||
|
|
||||||
|
/* config MCTRL memory controller */
|
||||||
|
mctrl->mcfg1 = CFG_GRLIB_MEMCFG1 | (mctrl->mcfg1 & 0x300);
|
||||||
|
mctrl->mcfg2 = CFG_GRLIB_MEMCFG2;
|
||||||
|
mctrl->mcfg3 = CFG_GRLIB_MEMCFG3;
|
||||||
|
not_found_mctrl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find Gaisler Fault Tolerant Memory controller */
|
||||||
|
base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_FTMCTRL, 0);
|
||||||
|
if (base) {
|
||||||
|
mctrl = (ambapp_dev_mctrl *) base;
|
||||||
|
|
||||||
|
/* config MCTRL memory controller */
|
||||||
|
mctrl->mcfg1 = CFG_GRLIB_FT_MEMCFG1 | (mctrl->mcfg1 & 0x300);
|
||||||
|
mctrl->mcfg2 = CFG_GRLIB_FT_MEMCFG2;
|
||||||
|
mctrl->mcfg3 = CFG_GRLIB_FT_MEMCFG3;
|
||||||
|
not_found_mctrl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find SDRAM controller */
|
||||||
|
base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_SDCTRL, 0);
|
||||||
|
if (base) {
|
||||||
|
sdctrl = (ambapp_dev_sdctrl *) base;
|
||||||
|
|
||||||
|
/* config memory controller */
|
||||||
|
sdctrl->sdcfg = CFG_GRLIB_SDRAM;
|
||||||
|
not_found_mctrl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDR2SPA, 1, 0);
|
||||||
|
if (ahb) {
|
||||||
|
ddr2spa = (ambapp_dev_ddr2spa *) ambapp_ahb_get_info(ahb, 1);
|
||||||
|
|
||||||
|
/* Config DDR2 memory controller */
|
||||||
|
ddr2spa->cfg1 = CFG_GRLIB_DDR2_CFG1;
|
||||||
|
ddr2spa->cfg3 = CFG_GRLIB_DDR2_CFG3;
|
||||||
|
not_found_mctrl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDRSPA, 1, 0);
|
||||||
|
if (ahb) {
|
||||||
|
ddrspa = (ambapp_dev_ddrspa *) ambapp_ahb_get_info(ahb, 1);
|
||||||
|
|
||||||
|
/* Config DDR memory controller */
|
||||||
|
ddrspa->ctrl = CFG_GRLIB_DDR_CFG;
|
||||||
|
not_found_mctrl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* failed to find any memory controller */
|
||||||
|
return not_found_mctrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Uses Timer 0 to get accurate
|
||||||
|
* pauses. Max 2 raised to 32 ticks
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void cpu_wait_ticks(unsigned long ticks)
|
||||||
|
{
|
||||||
|
unsigned long start = get_timer(0);
|
||||||
|
while (get_timer(start) < ticks) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initiate and setup timer0 interrupt to 1MHz
|
||||||
|
* Return irq number for timer int or a negative number for
|
||||||
|
* dealing with self
|
||||||
|
*/
|
||||||
|
int timer_interrupt_init_cpu(void)
|
||||||
|
{
|
||||||
|
/* 1ms ticks */
|
||||||
|
gptimer->e[0].val = 0;
|
||||||
|
gptimer->e[0].rld = 999; /* (((1000000 / 100) - 1)) */
|
||||||
|
gptimer->e[0].ctrl =
|
||||||
|
(LEON3_GPTIMER_EN |
|
||||||
|
LEON3_GPTIMER_RL | LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
|
||||||
|
|
||||||
|
return gptimer_irq;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is intended for SHORT delays only.
|
||||||
|
*/
|
||||||
|
unsigned long cpu_usec2ticks(unsigned long usec)
|
||||||
|
{
|
||||||
|
/* timer set to 1kHz ==> 1 clk tick = 1 msec */
|
||||||
|
if (usec < 1000)
|
||||||
|
return 1;
|
||||||
|
return (usec / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long cpu_ticks2usec(unsigned long ticks)
|
||||||
|
{
|
||||||
|
/* 1tick = 1usec */
|
||||||
|
return ticks * 1000;
|
||||||
|
}
|
219
cpu/leon3/interrupts.c
Normal file
219
cpu/leon3/interrupts.c
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2007
|
||||||
|
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
|
||||||
|
*
|
||||||
|
* (C) Copyright 2006
|
||||||
|
* Detlev Zundel, DENX Software Engineering, dzu@denx.de
|
||||||
|
*
|
||||||
|
* (C) Copyright -2003
|
||||||
|
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||||
|
*
|
||||||
|
* (C) Copyright 2001
|
||||||
|
* Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
|
||||||
|
*
|
||||||
|
* See file CREDITS for list of people who contributed to this
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <asm/stack.h>
|
||||||
|
#include <common.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <asm/processor.h>
|
||||||
|
#include <command.h>
|
||||||
|
#include <asm/irq.h>
|
||||||
|
|
||||||
|
#include <asm/leon.h>
|
||||||
|
#include <ambapp.h>
|
||||||
|
|
||||||
|
/* 15 normal irqs and a non maskable interrupt */
|
||||||
|
#define NR_IRQS 15
|
||||||
|
|
||||||
|
struct irq_action {
|
||||||
|
interrupt_handler_t *handler;
|
||||||
|
void *arg;
|
||||||
|
unsigned int count;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern ambapp_dev_irqmp *irqmp;
|
||||||
|
extern ambapp_dev_gptimer *gptimer;
|
||||||
|
|
||||||
|
static struct irq_action irq_handlers[NR_IRQS] = { {0}, };
|
||||||
|
static int spurious_irq_cnt = 0;
|
||||||
|
static int spurious_irq = 0;
|
||||||
|
|
||||||
|
static inline unsigned int irqmp_get_irqmask(unsigned int irq)
|
||||||
|
{
|
||||||
|
if ((irq < 0) || (irq >= NR_IRQS)) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return (1 << irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void leon3_ic_disable(unsigned int irq)
|
||||||
|
{
|
||||||
|
unsigned int mask, pil;
|
||||||
|
if (!irqmp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pil = intLock();
|
||||||
|
|
||||||
|
/* get mask of interrupt */
|
||||||
|
mask = irqmp_get_irqmask(irq);
|
||||||
|
|
||||||
|
/* set int level */
|
||||||
|
irqmp->cpu_mask[0] = SPARC_NOCACHE_READ(&irqmp->cpu_mask[0]) & (~mask);
|
||||||
|
|
||||||
|
intUnlock(pil);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void leon3_ic_enable(unsigned int irq)
|
||||||
|
{
|
||||||
|
unsigned int mask, pil;
|
||||||
|
if (!irqmp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pil = intLock();
|
||||||
|
|
||||||
|
/* get mask of interrupt */
|
||||||
|
mask = irqmp_get_irqmask(irq);
|
||||||
|
|
||||||
|
/* set int level */
|
||||||
|
irqmp->cpu_mask[0] = SPARC_NOCACHE_READ(&irqmp->cpu_mask[0]) | mask;
|
||||||
|
|
||||||
|
intUnlock(pil);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void handler_irq(int irq, struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
if (irq_handlers[irq].handler) {
|
||||||
|
if (((unsigned int)irq_handlers[irq].handler > CFG_RAM_END) ||
|
||||||
|
((unsigned int)irq_handlers[irq].handler < CFG_RAM_BASE)
|
||||||
|
) {
|
||||||
|
printf("handler_irq: bad handler: %x, irq number %d\n",
|
||||||
|
(unsigned int)irq_handlers[irq].handler, irq);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
irq_handlers[irq].handler(irq_handlers[irq].arg);
|
||||||
|
irq_handlers[irq].count++;
|
||||||
|
} else {
|
||||||
|
spurious_irq_cnt++;
|
||||||
|
spurious_irq = irq;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void leon3_force_int(int irq)
|
||||||
|
{
|
||||||
|
if (!irqmp || (irq >= NR_IRQS) || (irq < 0))
|
||||||
|
return;
|
||||||
|
printf("Forcing interrupt %d\n", irq);
|
||||||
|
|
||||||
|
irqmp->iforce = SPARC_NOCACHE_READ(&irqmp->iforce) | (1 << irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
int interrupt_init_cpu(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
/* Handle Timer 0 IRQ */
|
||||||
|
void timer_interrupt_cpu(void *arg)
|
||||||
|
{
|
||||||
|
gptimer->e[0].ctrl = (LEON3_GPTIMER_EN |
|
||||||
|
LEON3_GPTIMER_RL |
|
||||||
|
LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
|
||||||
|
/* nothing to do here */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Install and free a interrupt handler.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void irq_install_handler(int irq, interrupt_handler_t * handler, void *arg)
|
||||||
|
{
|
||||||
|
if (irq < 0 || irq >= NR_IRQS) {
|
||||||
|
printf("irq_install_handler: bad irq number %d\n", irq);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (irq_handlers[irq].handler != NULL)
|
||||||
|
printf("irq_install_handler: 0x%08lx replacing 0x%08lx\n",
|
||||||
|
(ulong) handler, (ulong) irq_handlers[irq].handler);
|
||||||
|
|
||||||
|
if (((unsigned int)handler > CFG_RAM_END) ||
|
||||||
|
((unsigned int)handler < CFG_RAM_BASE)
|
||||||
|
) {
|
||||||
|
printf("irq_install_handler: bad handler: %x, irq number %d\n",
|
||||||
|
(unsigned int)handler, irq);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
irq_handlers[irq].handler = handler;
|
||||||
|
irq_handlers[irq].arg = arg;
|
||||||
|
|
||||||
|
/* enable irq on IRQMP hardware */
|
||||||
|
leon3_ic_enable(irq);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void irq_free_handler(int irq)
|
||||||
|
{
|
||||||
|
if (irq < 0 || irq >= NR_IRQS) {
|
||||||
|
printf("irq_free_handler: bad irq number %d\n", irq);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* disable irq on IRQMP hardware */
|
||||||
|
leon3_ic_disable(irq);
|
||||||
|
|
||||||
|
irq_handlers[irq].handler = NULL;
|
||||||
|
irq_handlers[irq].arg = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
#if defined(CONFIG_CMD_IRQ)
|
||||||
|
void do_irqinfo(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int irq;
|
||||||
|
unsigned int pil = get_pil();
|
||||||
|
printf("PIL level: %u\n\r", pil);
|
||||||
|
printf("Spurious IRQ: %u, last unknown IRQ: %d\n",
|
||||||
|
spurious_irq_cnt, spurious_irq);
|
||||||
|
|
||||||
|
puts("\nInterrupt-Information:\n" "Nr Routine Arg Count\n");
|
||||||
|
|
||||||
|
for (irq = 0; irq < NR_IRQS; irq++) {
|
||||||
|
if (irq_handlers[irq].handler != NULL) {
|
||||||
|
printf("%02d %08lx %08lx %ld\n", irq,
|
||||||
|
(unsigned int)irq_handlers[irq].handler,
|
||||||
|
(unsigned int)irq_handlers[irq].arg,
|
||||||
|
irq_handlers[irq].count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
1078
cpu/leon3/prom.c
Normal file
1078
cpu/leon3/prom.c
Normal file
File diff suppressed because it is too large
Load Diff
139
cpu/leon3/serial.c
Normal file
139
cpu/leon3/serial.c
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
/* GRLIB APBUART Serial controller driver
|
||||||
|
*
|
||||||
|
* (C) Copyright 2007
|
||||||
|
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
|
||||||
|
*
|
||||||
|
* See file CREDITS for list of people who contributed to this
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <asm/processor.h>
|
||||||
|
#include <asm/leon.h>
|
||||||
|
#include <ambapp.h>
|
||||||
|
|
||||||
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
/* Force cache miss each time a serial controller reg is read */
|
||||||
|
#define CACHE_BYPASS 1
|
||||||
|
|
||||||
|
#ifdef CACHE_BYPASS
|
||||||
|
#define READ_BYTE(var) SPARC_NOCACHE_READ_BYTE((unsigned int)&(var))
|
||||||
|
#define READ_HWORD(var) SPARC_NOCACHE_READ_HWORD((unsigned int)&(var))
|
||||||
|
#define READ_WORD(var) SPARC_NOCACHE_READ((unsigned int)&(var))
|
||||||
|
#define READ_DWORD(var) SPARC_NOCACHE_READ_DWORD((unsigned int)&(var))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ambapp_dev_apbuart *leon3_apbuart = NULL;
|
||||||
|
|
||||||
|
int serial_init(void)
|
||||||
|
{
|
||||||
|
ambapp_apbdev apbdev;
|
||||||
|
unsigned int tmp;
|
||||||
|
|
||||||
|
/* find UART */
|
||||||
|
if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_APBUART, &apbdev) == 1) {
|
||||||
|
|
||||||
|
leon3_apbuart = (ambapp_dev_apbuart *) apbdev.address;
|
||||||
|
|
||||||
|
/* found apbuart, let's init...
|
||||||
|
*
|
||||||
|
* Set scaler / baud rate
|
||||||
|
*
|
||||||
|
* Receiver & transmitter enable
|
||||||
|
*/
|
||||||
|
leon3_apbuart->scaler = CFG_GRLIB_APBUART_SCALER;
|
||||||
|
|
||||||
|
/* Let bit 11 be unchanged (debug bit for GRMON) */
|
||||||
|
tmp = READ_WORD(leon3_apbuart->ctrl);
|
||||||
|
|
||||||
|
leon3_apbuart->ctrl = ((tmp & LEON_REG_UART_CTRL_DBG) |
|
||||||
|
LEON_REG_UART_CTRL_RE |
|
||||||
|
LEON_REG_UART_CTRL_TE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1; /* didn't find hardware */
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_putc(const char c)
|
||||||
|
{
|
||||||
|
if (c == '\n')
|
||||||
|
serial_putc_raw('\r');
|
||||||
|
|
||||||
|
serial_putc_raw(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_putc_raw(const char c)
|
||||||
|
{
|
||||||
|
if (!leon3_apbuart)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Wait for last character to go. */
|
||||||
|
while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_THE)) ;
|
||||||
|
|
||||||
|
/* Send data */
|
||||||
|
leon3_apbuart->data = c;
|
||||||
|
|
||||||
|
#ifdef LEON_DEBUG
|
||||||
|
/* Wait for data to be sent */
|
||||||
|
while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_TSE)) ;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_puts(const char *s)
|
||||||
|
{
|
||||||
|
while (*s) {
|
||||||
|
serial_putc(*s++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int serial_getc(void)
|
||||||
|
{
|
||||||
|
if (!leon3_apbuart)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Wait for a character to arrive. */
|
||||||
|
while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_DR)) ;
|
||||||
|
|
||||||
|
/* read data */
|
||||||
|
return READ_WORD(leon3_apbuart->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
int serial_tstc(void)
|
||||||
|
{
|
||||||
|
if (leon3_apbuart)
|
||||||
|
return (READ_WORD(leon3_apbuart->status) &
|
||||||
|
LEON_REG_UART_STATUS_DR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set baud rate for uart */
|
||||||
|
void serial_setbrg(void)
|
||||||
|
{
|
||||||
|
/* update baud rate settings, read it from gd->baudrate */
|
||||||
|
unsigned int scaler;
|
||||||
|
if (leon3_apbuart && (gd->baudrate > 0)) {
|
||||||
|
scaler =
|
||||||
|
(((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) -
|
||||||
|
5) / 10;
|
||||||
|
leon3_apbuart->scaler = scaler;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
616
cpu/leon3/start.S
Normal file
616
cpu/leon3/start.S
Normal file
|
@ -0,0 +1,616 @@
|
||||||
|
/* This is where the SPARC/LEON3 starts
|
||||||
|
* Copyright (C) 2007,
|
||||||
|
* Daniel Hellstrom, daniel@gaisler.com
|
||||||
|
*
|
||||||
|
* See file CREDITS for list of people who contributed to this
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <asm/asmmacro.h>
|
||||||
|
#include <asm/winmacro.h>
|
||||||
|
#include <asm/psr.h>
|
||||||
|
#include <asm/stack.h>
|
||||||
|
#include <asm/leon.h>
|
||||||
|
#include <version.h>
|
||||||
|
|
||||||
|
/* Entry for traps which jump to a programmer-specified trap handler. */
|
||||||
|
#define TRAPR(H) \
|
||||||
|
wr %g0, 0xfe0, %psr; \
|
||||||
|
mov %g0, %tbr; \
|
||||||
|
ba (H); \
|
||||||
|
mov %g0, %wim;
|
||||||
|
|
||||||
|
#define TRAP(H) \
|
||||||
|
mov %psr, %l0; \
|
||||||
|
ba (H); \
|
||||||
|
nop; nop;
|
||||||
|
|
||||||
|
#define TRAPI(ilevel) \
|
||||||
|
mov ilevel, %l7; \
|
||||||
|
mov %psr, %l0; \
|
||||||
|
b _irq_entry; \
|
||||||
|
mov %wim, %l3
|
||||||
|
|
||||||
|
/* Unexcpected trap will halt the processor by forcing it to error state */
|
||||||
|
#undef BAD_TRAP
|
||||||
|
#define BAD_TRAP ta 0; nop; nop; nop;
|
||||||
|
|
||||||
|
/* Software trap. Treat as BAD_TRAP for the time being... */
|
||||||
|
#define SOFT_TRAP TRAP(_hwerr)
|
||||||
|
|
||||||
|
#define PSR_INIT 0x1FC0 /* Disable traps, set s and ps */
|
||||||
|
#define WIM_INIT 2
|
||||||
|
|
||||||
|
/* All traps low-level code here must end with this macro. */
|
||||||
|
#define RESTORE_ALL b ret_trap_entry; clr %l6;
|
||||||
|
|
||||||
|
#define WRITE_PAUSE nop;nop;nop
|
||||||
|
|
||||||
|
WINDOWSIZE = (16 * 4)
|
||||||
|
ARGPUSHSIZE = (6 * 4)
|
||||||
|
ARGPUSH = (WINDOWSIZE + 4)
|
||||||
|
MINFRAME = (WINDOWSIZE + ARGPUSHSIZE + 4)
|
||||||
|
|
||||||
|
/* Number of register windows */
|
||||||
|
#ifndef CFG_SPARC_NWINDOWS
|
||||||
|
#error Must define number of SPARC register windows, default is 8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define STACK_ALIGN 8
|
||||||
|
#define SA(X) (((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1))
|
||||||
|
|
||||||
|
.section ".start", "ax"
|
||||||
|
.globl _start, start, _trap_table
|
||||||
|
.globl _irq_entry, nmi_trap
|
||||||
|
.globl _reset_reloc
|
||||||
|
|
||||||
|
/* at address 0
|
||||||
|
* Hardware traps
|
||||||
|
*/
|
||||||
|
start:
|
||||||
|
_start:
|
||||||
|
_trap_table:
|
||||||
|
TRAPR(_hardreset); ! 00 reset trap
|
||||||
|
BAD_TRAP; ! 01 instruction_access_exception
|
||||||
|
BAD_TRAP; ! 02 illegal_instruction
|
||||||
|
BAD_TRAP; ! 03 priveleged_instruction
|
||||||
|
BAD_TRAP; ! 04 fp_disabled
|
||||||
|
TRAP(_window_overflow); ! 05 window_overflow
|
||||||
|
TRAP(_window_underflow); ! 06 window_underflow
|
||||||
|
BAD_TRAP; ! 07 Memory Address Not Aligned
|
||||||
|
BAD_TRAP; ! 08 Floating Point Exception
|
||||||
|
BAD_TRAP; ! 09 Data Miss Exception
|
||||||
|
BAD_TRAP; ! 0a Tagged Instruction Ovrflw
|
||||||
|
BAD_TRAP; ! 0b Watchpoint Detected
|
||||||
|
BAD_TRAP; ! 0c
|
||||||
|
BAD_TRAP; ! 0d
|
||||||
|
BAD_TRAP; ! 0e
|
||||||
|
BAD_TRAP; ! 0f
|
||||||
|
BAD_TRAP; ! 10
|
||||||
|
TRAPI(1); ! 11 IRQ level 1
|
||||||
|
TRAPI(2); ! 12 IRQ level 2
|
||||||
|
TRAPI(3); ! 13 IRQ level 3
|
||||||
|
TRAPI(4); ! 14 IRQ level 4
|
||||||
|
TRAPI(5); ! 15 IRQ level 5
|
||||||
|
TRAPI(6); ! 16 IRQ level 6
|
||||||
|
TRAPI(7); ! 17 IRQ level 7
|
||||||
|
TRAPI(8); ! 18 IRQ level 8
|
||||||
|
TRAPI(9); ! 19 IRQ level 9
|
||||||
|
TRAPI(10); ! 1a IRQ level 10
|
||||||
|
TRAPI(11); ! 1b IRQ level 11
|
||||||
|
TRAPI(12); ! 1c IRQ level 12
|
||||||
|
TRAPI(13); ! 1d IRQ level 13
|
||||||
|
TRAPI(14); ! 1e IRQ level 14
|
||||||
|
TRAP(_nmi_trap); ! 1f IRQ level 15 /
|
||||||
|
! NMI (non maskable interrupt)
|
||||||
|
BAD_TRAP; ! 20 r_register_access_error
|
||||||
|
BAD_TRAP; ! 21 instruction access error
|
||||||
|
BAD_TRAP; ! 22
|
||||||
|
BAD_TRAP; ! 23
|
||||||
|
BAD_TRAP; ! 24 co-processor disabled
|
||||||
|
BAD_TRAP; ! 25 uniplemented FLUSH
|
||||||
|
BAD_TRAP; ! 26
|
||||||
|
BAD_TRAP; ! 27
|
||||||
|
BAD_TRAP; ! 28 co-processor exception
|
||||||
|
BAD_TRAP; ! 29 data access error
|
||||||
|
BAD_TRAP; ! 2a division by zero
|
||||||
|
BAD_TRAP; ! 2b data store error
|
||||||
|
BAD_TRAP; ! 2c data access MMU miss
|
||||||
|
BAD_TRAP; ! 2d
|
||||||
|
BAD_TRAP; ! 2e
|
||||||
|
BAD_TRAP; ! 2f
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 30-33
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 34-37
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 38-3b
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 3c-3f
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 40-43
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 44-47
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 48-4b
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 4c-4f
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 50-53
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 54-57
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 58-5b
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 5c-5f
|
||||||
|
|
||||||
|
/* implementaion dependent */
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 60-63
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 64-67
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 68-6b
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 6c-6f
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 70-73
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 74-77
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 78-7b
|
||||||
|
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 7c-7f
|
||||||
|
|
||||||
|
/* Software traps, not handled */
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 80-83
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 84-87
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 88-8b
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 8c-8f
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 90-93
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 94-97
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 98-9b
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 9c-9f
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! a0-a3
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! a4-a7
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! a8-ab
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! ac-af
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! b0-b3
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! b4-b7
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! b8-bb
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! bc-bf
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! c0-c3
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! c4-c7
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! c8-cb
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! cc-cf
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! d0-d3
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! d4-d7
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! d8-db
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! dc-df
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! e0-e3
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! e4-e7
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! e8-eb
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! ec-ef
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! f0-f3
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! f4-f7
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! f8-fb
|
||||||
|
SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! fc-ff
|
||||||
|
/*
|
||||||
|
* Version string
|
||||||
|
*/
|
||||||
|
|
||||||
|
.data
|
||||||
|
.extern leon3_snooping_avail
|
||||||
|
.globl version_string
|
||||||
|
version_string:
|
||||||
|
.ascii U_BOOT_VERSION
|
||||||
|
.ascii " (", __DATE__, " - ", __TIME__, ")"
|
||||||
|
.ascii CONFIG_IDENT_STRING, "\0"
|
||||||
|
|
||||||
|
.section ".text"
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
_hardreset:
|
||||||
|
1000:
|
||||||
|
flush
|
||||||
|
|
||||||
|
/* Enable I/D-Cache and Snooping */
|
||||||
|
set 0x0081000f, %g2
|
||||||
|
sta %g2, [%g0] 2
|
||||||
|
|
||||||
|
mov %g0, %y
|
||||||
|
clr %g1
|
||||||
|
clr %g2
|
||||||
|
clr %g3
|
||||||
|
clr %g4
|
||||||
|
clr %g5
|
||||||
|
clr %g6
|
||||||
|
clr %g7
|
||||||
|
|
||||||
|
mov %asr17, %g3
|
||||||
|
and %g3, 0x1f, %g3
|
||||||
|
clear_window:
|
||||||
|
mov %g0, %l0
|
||||||
|
mov %g0, %l1
|
||||||
|
mov %g0, %l2
|
||||||
|
mov %g0, %l3
|
||||||
|
mov %g0, %l4
|
||||||
|
mov %g0, %l5
|
||||||
|
mov %g0, %l6
|
||||||
|
mov %g0, %l7
|
||||||
|
mov %g0, %o0
|
||||||
|
mov %g0, %o1
|
||||||
|
mov %g0, %o2
|
||||||
|
mov %g0, %o3
|
||||||
|
mov %g0, %o4
|
||||||
|
mov %g0, %o5
|
||||||
|
mov %g0, %o6
|
||||||
|
mov %g0, %o7
|
||||||
|
subcc %g3, 1, %g3
|
||||||
|
bge clear_window
|
||||||
|
save
|
||||||
|
|
||||||
|
wininit:
|
||||||
|
set WIM_INIT, %g3
|
||||||
|
mov %g3, %wim
|
||||||
|
|
||||||
|
stackp:
|
||||||
|
set CFG_INIT_SP_OFFSET, %fp
|
||||||
|
andn %fp, 0x0f, %fp
|
||||||
|
sub %fp, 64, %sp
|
||||||
|
|
||||||
|
cpu_init_unreloc:
|
||||||
|
call cpu_init_f
|
||||||
|
nop
|
||||||
|
|
||||||
|
/* un relocated start address of monitor */
|
||||||
|
#define TEXT_START _text
|
||||||
|
|
||||||
|
/* un relocated end address of monitor */
|
||||||
|
#define DATA_END __init_end
|
||||||
|
|
||||||
|
reloc:
|
||||||
|
set TEXT_START,%g2
|
||||||
|
set DATA_END,%g3
|
||||||
|
set CFG_RELOC_MONITOR_BASE,%g4
|
||||||
|
reloc_loop:
|
||||||
|
ldd [%g2],%l0
|
||||||
|
ldd [%g2+8],%l2
|
||||||
|
std %l0,[%g4]
|
||||||
|
std %l2,[%g4+8]
|
||||||
|
inc 16,%g2
|
||||||
|
subcc %g3,%g2,%g0
|
||||||
|
bne reloc_loop
|
||||||
|
inc 16,%g4
|
||||||
|
|
||||||
|
clr %l0
|
||||||
|
clr %l1
|
||||||
|
clr %l2
|
||||||
|
clr %l3
|
||||||
|
clr %g2
|
||||||
|
|
||||||
|
/* register g4 contain address to start
|
||||||
|
* This means that BSS must be directly after data and code segments
|
||||||
|
*
|
||||||
|
* g3 is length of bss = (__bss_end-__bss_start)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
clr_bss:
|
||||||
|
/* clear bss area (the relocated) */
|
||||||
|
set __bss_start,%g2
|
||||||
|
set __bss_end,%g3
|
||||||
|
sub %g3,%g2,%g3
|
||||||
|
add %g3,%g4,%g3
|
||||||
|
clr %g1 /* std %g0 uses g0 and g1 */
|
||||||
|
/* clearing 16byte a time ==> linker script need to align to 16 byte offset */
|
||||||
|
clr_bss_16:
|
||||||
|
std %g0,[%g4]
|
||||||
|
std %g0,[%g4+8]
|
||||||
|
inc 16,%g4
|
||||||
|
cmp %g3,%g4
|
||||||
|
bne clr_bss_16
|
||||||
|
nop
|
||||||
|
|
||||||
|
/* add offsets to GOT table */
|
||||||
|
fixup_got:
|
||||||
|
set __got_start,%g4
|
||||||
|
set __got_end,%g3
|
||||||
|
/*
|
||||||
|
* new got offset = (old GOT-PTR (read with ld) -
|
||||||
|
* CFG_RELOC_MONITOR_BASE(from define) ) +
|
||||||
|
* Destination Address (from define)
|
||||||
|
*/
|
||||||
|
set CFG_RELOC_MONITOR_BASE,%g2
|
||||||
|
set TEXT_START, %g1
|
||||||
|
add %g4,%g2,%g4
|
||||||
|
sub %g4,%g1,%g4
|
||||||
|
add %g3,%g2,%g3
|
||||||
|
sub %g3,%g1,%g3
|
||||||
|
sub %g2,%g1,%g2 ! prepare register with (new base address) -
|
||||||
|
! (old base address)
|
||||||
|
got_loop:
|
||||||
|
ld [%g4],%l0 ! load old GOT-PTR
|
||||||
|
add %l0,%g2,%l0 ! increase with (new base address) -
|
||||||
|
! (old base)
|
||||||
|
st %l0,[%g4]
|
||||||
|
inc 4,%g4
|
||||||
|
cmp %g3,%g4
|
||||||
|
bne got_loop
|
||||||
|
nop
|
||||||
|
|
||||||
|
prom_relocate:
|
||||||
|
set __prom_start, %g2
|
||||||
|
set __prom_end, %g3
|
||||||
|
set CFG_PROM_OFFSET, %g4
|
||||||
|
|
||||||
|
prom_relocate_loop:
|
||||||
|
ldd [%g2],%l0
|
||||||
|
ldd [%g2+8],%l2
|
||||||
|
std %l0,[%g4]
|
||||||
|
std %l2,[%g4+8]
|
||||||
|
inc 16,%g2
|
||||||
|
subcc %g3,%g2,%g0
|
||||||
|
bne prom_relocate_loop
|
||||||
|
inc 16,%g4
|
||||||
|
|
||||||
|
/* Trap table has been moved, lets tell CPU about
|
||||||
|
* the new trap table address
|
||||||
|
*/
|
||||||
|
|
||||||
|
set CFG_RELOC_MONITOR_BASE, %g2
|
||||||
|
wr %g0, %g2, %tbr
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
|
/* If CACHE snooping is available in hardware the
|
||||||
|
* variable leon3_snooping_avail will be set to
|
||||||
|
* 0x800000 else 0.
|
||||||
|
*/
|
||||||
|
snoop_detect:
|
||||||
|
sethi %hi(0x00800000), %o0
|
||||||
|
lda [%g0] 2, %o1
|
||||||
|
and %o0, %o1, %o0
|
||||||
|
sethi %hi(leon3_snooping_avail+CFG_RELOC_MONITOR_BASE-TEXT_BASE), %o1
|
||||||
|
st %o0, [%lo(leon3_snooping_avail+CFG_RELOC_MONITOR_BASE-TEXT_BASE)+%o1]
|
||||||
|
|
||||||
|
/* call relocate*/
|
||||||
|
nop
|
||||||
|
/* Call relocated init functions */
|
||||||
|
jump:
|
||||||
|
set cpu_init_f2,%o1
|
||||||
|
set CFG_RELOC_MONITOR_BASE,%o2
|
||||||
|
add %o1,%o2,%o1
|
||||||
|
sub %o1,%g1,%o1
|
||||||
|
call %o1
|
||||||
|
clr %o0
|
||||||
|
|
||||||
|
set board_init_f,%o1
|
||||||
|
set CFG_RELOC_MONITOR_BASE,%o2
|
||||||
|
add %o1,%o2,%o1
|
||||||
|
sub %o1,%g1,%o1
|
||||||
|
call %o1
|
||||||
|
clr %o0
|
||||||
|
|
||||||
|
dead: ta 0 ! if call returns...
|
||||||
|
nop
|
||||||
|
|
||||||
|
/* Interrupt handler caller,
|
||||||
|
* reg L7: interrupt number
|
||||||
|
* reg L0: psr after interrupt
|
||||||
|
* reg L1: PC
|
||||||
|
* reg L2: next PC
|
||||||
|
* reg L3: wim
|
||||||
|
*/
|
||||||
|
_irq_entry:
|
||||||
|
SAVE_ALL
|
||||||
|
|
||||||
|
or %l0, PSR_PIL, %g2
|
||||||
|
wr %g2, 0x0, %psr
|
||||||
|
WRITE_PAUSE
|
||||||
|
wr %g2, PSR_ET, %psr
|
||||||
|
WRITE_PAUSE
|
||||||
|
mov %l7, %o0 ! irq level
|
||||||
|
set handler_irq, %o1
|
||||||
|
set (CFG_RELOC_MONITOR_BASE-TEXT_BASE), %o2
|
||||||
|
add %o1, %o2, %o1
|
||||||
|
call %o1
|
||||||
|
add %sp, SF_REGS_SZ, %o1 ! pt_regs ptr
|
||||||
|
or %l0, PSR_PIL, %g2 ! restore PIL after handler_irq
|
||||||
|
wr %g2, PSR_ET, %psr ! keep ET up
|
||||||
|
WRITE_PAUSE
|
||||||
|
|
||||||
|
RESTORE_ALL
|
||||||
|
|
||||||
|
!Window overflow trap handler.
|
||||||
|
.global _window_overflow
|
||||||
|
|
||||||
|
_window_overflow:
|
||||||
|
|
||||||
|
mov %wim, %l3 ! Calculate next WIM
|
||||||
|
mov %g1, %l7
|
||||||
|
srl %l3, 1, %g1
|
||||||
|
sll %l3, (CFG_SPARC_NWINDOWS-1) , %l4
|
||||||
|
or %l4, %g1, %g1
|
||||||
|
|
||||||
|
save ! Get into window to be saved.
|
||||||
|
mov %g1, %wim
|
||||||
|
nop;
|
||||||
|
nop;
|
||||||
|
nop
|
||||||
|
st %l0, [%sp + 0];
|
||||||
|
st %l1, [%sp + 4];
|
||||||
|
st %l2, [%sp + 8];
|
||||||
|
st %l3, [%sp + 12];
|
||||||
|
st %l4, [%sp + 16];
|
||||||
|
st %l5, [%sp + 20];
|
||||||
|
st %l6, [%sp + 24];
|
||||||
|
st %l7, [%sp + 28];
|
||||||
|
st %i0, [%sp + 32];
|
||||||
|
st %i1, [%sp + 36];
|
||||||
|
st %i2, [%sp + 40];
|
||||||
|
st %i3, [%sp + 44];
|
||||||
|
st %i4, [%sp + 48];
|
||||||
|
st %i5, [%sp + 52];
|
||||||
|
st %i6, [%sp + 56];
|
||||||
|
st %i7, [%sp + 60];
|
||||||
|
restore ! Go back to trap window.
|
||||||
|
mov %l7, %g1
|
||||||
|
jmp %l1 ! Re-execute save.
|
||||||
|
rett %l2
|
||||||
|
|
||||||
|
/* Window underflow trap handler. */
|
||||||
|
|
||||||
|
.global _window_underflow
|
||||||
|
|
||||||
|
_window_underflow:
|
||||||
|
|
||||||
|
mov %wim, %l3 ! Calculate next WIM
|
||||||
|
sll %l3, 1, %l4
|
||||||
|
srl %l3, (CFG_SPARC_NWINDOWS-1), %l5
|
||||||
|
or %l5, %l4, %l5
|
||||||
|
mov %l5, %wim
|
||||||
|
nop; nop; nop
|
||||||
|
restore ! Two restores to get into the
|
||||||
|
restore ! window to restore
|
||||||
|
ld [%sp + 0], %l0; ! Restore window from the stack
|
||||||
|
ld [%sp + 4], %l1;
|
||||||
|
ld [%sp + 8], %l2;
|
||||||
|
ld [%sp + 12], %l3;
|
||||||
|
ld [%sp + 16], %l4;
|
||||||
|
ld [%sp + 20], %l5;
|
||||||
|
ld [%sp + 24], %l6;
|
||||||
|
ld [%sp + 28], %l7;
|
||||||
|
ld [%sp + 32], %i0;
|
||||||
|
ld [%sp + 36], %i1;
|
||||||
|
ld [%sp + 40], %i2;
|
||||||
|
ld [%sp + 44], %i3;
|
||||||
|
ld [%sp + 48], %i4;
|
||||||
|
ld [%sp + 52], %i5;
|
||||||
|
ld [%sp + 56], %i6;
|
||||||
|
ld [%sp + 60], %i7;
|
||||||
|
save ! Get back to the trap window.
|
||||||
|
save
|
||||||
|
jmp %l1 ! Re-execute restore.
|
||||||
|
rett %l2
|
||||||
|
|
||||||
|
retl
|
||||||
|
|
||||||
|
_nmi_trap:
|
||||||
|
nop
|
||||||
|
jmp %l1
|
||||||
|
rett %l2
|
||||||
|
|
||||||
|
_hwerr:
|
||||||
|
ta 0
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
b _hwerr ! loop infinite
|
||||||
|
nop
|
||||||
|
|
||||||
|
/* Registers to not touch at all. */
|
||||||
|
#define t_psr l0 /* Set by caller */
|
||||||
|
#define t_pc l1 /* Set by caller */
|
||||||
|
#define t_npc l2 /* Set by caller */
|
||||||
|
#define t_wim l3 /* Set by caller */
|
||||||
|
#define t_twinmask l4 /* Set at beginning of this entry routine. */
|
||||||
|
#define t_kstack l5 /* Set right before pt_regs frame is built */
|
||||||
|
#define t_retpc l6 /* If you change this, change winmacro.h header file */
|
||||||
|
#define t_systable l7 /* Never touch this, could be the syscall table ptr. */
|
||||||
|
#define curptr g6 /* Set after pt_regs frame is built */
|
||||||
|
|
||||||
|
trap_setup:
|
||||||
|
/* build a pt_regs trap frame. */
|
||||||
|
sub %fp, (SF_REGS_SZ + PT_REGS_SZ), %t_kstack
|
||||||
|
PT_STORE_ALL(t_kstack, t_psr, t_pc, t_npc, g2)
|
||||||
|
|
||||||
|
/* See if we are in the trap window. */
|
||||||
|
mov 1, %t_twinmask
|
||||||
|
sll %t_twinmask, %t_psr, %t_twinmask ! t_twinmask = (1 << psr)
|
||||||
|
andcc %t_twinmask, %t_wim, %g0
|
||||||
|
beq 1f ! in trap window, clean up
|
||||||
|
nop
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
* Spill , adjust %wim and go.
|
||||||
|
*/
|
||||||
|
srl %t_wim, 0x1, %g2 ! begin computation of new %wim
|
||||||
|
|
||||||
|
set (CFG_SPARC_NWINDOWS-1), %g3 !NWINDOWS-1
|
||||||
|
|
||||||
|
sll %t_wim, %g3, %t_wim ! NWINDOWS-1
|
||||||
|
or %t_wim, %g2, %g2
|
||||||
|
and %g2, 0xff, %g2
|
||||||
|
|
||||||
|
save %g0, %g0, %g0 ! get in window to be saved
|
||||||
|
|
||||||
|
/* Set new %wim value */
|
||||||
|
wr %g2, 0x0, %wim
|
||||||
|
|
||||||
|
/* Save the kernel window onto the corresponding stack. */
|
||||||
|
RW_STORE(sp)
|
||||||
|
|
||||||
|
restore %g0, %g0, %g0
|
||||||
|
/*-------------------------------------------------*/
|
||||||
|
|
||||||
|
1:
|
||||||
|
/* Trap from kernel with a window available.
|
||||||
|
* Just do it...
|
||||||
|
*/
|
||||||
|
jmpl %t_retpc + 0x8, %g0 ! return to caller
|
||||||
|
mov %t_kstack, %sp ! jump onto new stack
|
||||||
|
|
||||||
|
#define twin_tmp1 l4
|
||||||
|
#define glob_tmp g4
|
||||||
|
#define curptr g6
|
||||||
|
ret_trap_entry:
|
||||||
|
wr %t_psr, 0x0, %psr ! enable nesting again, clear ET
|
||||||
|
|
||||||
|
/* Will the rett land us in the invalid window? */
|
||||||
|
mov 2, %g1
|
||||||
|
sll %g1, %t_psr, %g1
|
||||||
|
|
||||||
|
set CFG_SPARC_NWINDOWS, %g2 !NWINDOWS
|
||||||
|
|
||||||
|
srl %g1, %g2, %g2
|
||||||
|
or %g1, %g2, %g1
|
||||||
|
rd %wim, %g2
|
||||||
|
andcc %g2, %g1, %g0
|
||||||
|
be 1f ! Nope, just return from the trap
|
||||||
|
sll %g2, 0x1, %g1
|
||||||
|
|
||||||
|
/* We have to grab a window before returning. */
|
||||||
|
set (CFG_SPARC_NWINDOWS-1), %g3 !NWINDOWS-1
|
||||||
|
|
||||||
|
srl %g2, %g3, %g2
|
||||||
|
or %g1, %g2, %g1
|
||||||
|
and %g1, 0xff, %g1
|
||||||
|
|
||||||
|
wr %g1, 0x0, %wim
|
||||||
|
|
||||||
|
/* Grrr, make sure we load from the right %sp... */
|
||||||
|
PT_LOAD_ALL(sp, t_psr, t_pc, t_npc, g1)
|
||||||
|
|
||||||
|
restore %g0, %g0, %g0
|
||||||
|
RW_LOAD(sp)
|
||||||
|
b 2f
|
||||||
|
save %g0, %g0, %g0
|
||||||
|
|
||||||
|
/* Reload the entire frame in case this is from a
|
||||||
|
* kernel system call or whatever...
|
||||||
|
*/
|
||||||
|
1:
|
||||||
|
PT_LOAD_ALL(sp, t_psr, t_pc, t_npc, g1)
|
||||||
|
2:
|
||||||
|
wr %t_psr, 0x0, %psr
|
||||||
|
nop;
|
||||||
|
nop;
|
||||||
|
nop
|
||||||
|
|
||||||
|
jmp %t_pc
|
||||||
|
rett %t_npc
|
||||||
|
|
||||||
|
/* This is called from relocated C-code.
|
||||||
|
* It resets the system by jumping to _start
|
||||||
|
*/
|
||||||
|
_reset_reloc:
|
||||||
|
set start, %l0
|
||||||
|
call %l0
|
||||||
|
nop
|
1313
cpu/leon3/usb_uhci.c
Normal file
1313
cpu/leon3/usb_uhci.c
Normal file
File diff suppressed because it is too large
Load Diff
184
cpu/leon3/usb_uhci.h
Normal file
184
cpu/leon3/usb_uhci.h
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2001
|
||||||
|
* Denis Peter, MPL AG Switzerland
|
||||||
|
*
|
||||||
|
* See file CREDITS for list of people who contributed to this
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* Note: Part of this code has been derived from linux
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef _USB_UHCI_H_
|
||||||
|
#define _USB_UHCI_H_
|
||||||
|
|
||||||
|
/* Command register */
|
||||||
|
#define USBCMD 0
|
||||||
|
#define USBCMD_RS 0x0001 /* Run/Stop */
|
||||||
|
#define USBCMD_HCRESET 0x0002 /* Host reset */
|
||||||
|
#define USBCMD_GRESET 0x0004 /* Global reset */
|
||||||
|
#define USBCMD_EGSM 0x0008 /* Global Suspend Mode */
|
||||||
|
#define USBCMD_FGR 0x0010 /* Force Global Resume */
|
||||||
|
#define USBCMD_SWDBG 0x0020 /* SW Debug mode */
|
||||||
|
#define USBCMD_CF 0x0040 /* Config Flag (sw only) */
|
||||||
|
#define USBCMD_MAXP 0x0080 /* Max Packet (0 = 32, 1 = 64) */
|
||||||
|
|
||||||
|
/* Status register */
|
||||||
|
#define USBSTS 2
|
||||||
|
#define USBSTS_USBINT 0x0001 /* Interrupt due to IOC */
|
||||||
|
#define USBSTS_ERROR 0x0002 /* Interrupt due to error */
|
||||||
|
#define USBSTS_RD 0x0004 /* Resume Detect */
|
||||||
|
#define USBSTS_HSE 0x0008 /* Host System Error - basically PCI problems */
|
||||||
|
#define USBSTS_HCPE 0x0010 /* Host Controller Process Error - the scripts were buggy */
|
||||||
|
#define USBSTS_HCH 0x0020 /* HC Halted */
|
||||||
|
|
||||||
|
/* Interrupt enable register */
|
||||||
|
#define USBINTR 4
|
||||||
|
#define USBINTR_TIMEOUT 0x0001 /* Timeout/CRC error enable */
|
||||||
|
#define USBINTR_RESUME 0x0002 /* Resume interrupt enable */
|
||||||
|
#define USBINTR_IOC 0x0004 /* Interrupt On Complete enable */
|
||||||
|
#define USBINTR_SP 0x0008 /* Short packet interrupt enable */
|
||||||
|
|
||||||
|
#define USBFRNUM 6
|
||||||
|
#define USBFLBASEADD 8
|
||||||
|
#define USBSOF 12
|
||||||
|
|
||||||
|
/* USB port status and control registers */
|
||||||
|
#define USBPORTSC1 16
|
||||||
|
#define USBPORTSC2 18
|
||||||
|
#define USBPORTSC_CCS 0x0001 /* Current Connect Status ("device present") */
|
||||||
|
#define USBPORTSC_CSC 0x0002 /* Connect Status Change */
|
||||||
|
#define USBPORTSC_PE 0x0004 /* Port Enable */
|
||||||
|
#define USBPORTSC_PEC 0x0008 /* Port Enable Change */
|
||||||
|
#define USBPORTSC_LS 0x0030 /* Line Status */
|
||||||
|
#define USBPORTSC_RD 0x0040 /* Resume Detect */
|
||||||
|
#define USBPORTSC_LSDA 0x0100 /* Low Speed Device Attached */
|
||||||
|
#define USBPORTSC_PR 0x0200 /* Port Reset */
|
||||||
|
#define USBPORTSC_SUSP 0x1000 /* Suspend */
|
||||||
|
|
||||||
|
/* Legacy support register */
|
||||||
|
#define USBLEGSUP 0xc0
|
||||||
|
#define USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */
|
||||||
|
|
||||||
|
#define UHCI_NULL_DATA_SIZE 0x7ff /* for UHCI controller TD */
|
||||||
|
#define UHCI_PID 0xff /* PID MASK */
|
||||||
|
|
||||||
|
#define UHCI_PTR_BITS 0x000F
|
||||||
|
#define UHCI_PTR_TERM 0x0001
|
||||||
|
#define UHCI_PTR_QH 0x0002
|
||||||
|
#define UHCI_PTR_DEPTH 0x0004
|
||||||
|
|
||||||
|
/* for TD <status>: */
|
||||||
|
#define TD_CTRL_SPD (1 << 29) /* Short Packet Detect */
|
||||||
|
#define TD_CTRL_C_ERR_MASK (3 << 27) /* Error Counter bits */
|
||||||
|
#define TD_CTRL_LS (1 << 26) /* Low Speed Device */
|
||||||
|
#define TD_CTRL_IOS (1 << 25) /* Isochronous Select */
|
||||||
|
#define TD_CTRL_IOC (1 << 24) /* Interrupt on Complete */
|
||||||
|
#define TD_CTRL_ACTIVE (1 << 23) /* TD Active */
|
||||||
|
#define TD_CTRL_STALLED (1 << 22) /* TD Stalled */
|
||||||
|
#define TD_CTRL_DBUFERR (1 << 21) /* Data Buffer Error */
|
||||||
|
#define TD_CTRL_BABBLE (1 << 20) /* Babble Detected */
|
||||||
|
#define TD_CTRL_NAK (1 << 19) /* NAK Received */
|
||||||
|
#define TD_CTRL_CRCTIMEO (1 << 18) /* CRC/Time Out Error */
|
||||||
|
#define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */
|
||||||
|
#define TD_CTRL_ACTLEN_MASK 0x7ff /* actual length, encoded as n - 1 */
|
||||||
|
|
||||||
|
#define TD_CTRL_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \
|
||||||
|
TD_CTRL_BABBLE | TD_CTRL_CRCTIME | TD_CTRL_BITSTUFF)
|
||||||
|
|
||||||
|
#define TD_TOKEN_TOGGLE 19
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------
|
||||||
|
Virtual Root HUB
|
||||||
|
------------------------------------------------------------------------------------ */
|
||||||
|
/* destination of request */
|
||||||
|
#define RH_INTERFACE 0x01
|
||||||
|
#define RH_ENDPOINT 0x02
|
||||||
|
#define RH_OTHER 0x03
|
||||||
|
|
||||||
|
#define RH_CLASS 0x20
|
||||||
|
#define RH_VENDOR 0x40
|
||||||
|
|
||||||
|
/* Requests: bRequest << 8 | bmRequestType */
|
||||||
|
#define RH_GET_STATUS 0x0080
|
||||||
|
#define RH_CLEAR_FEATURE 0x0100
|
||||||
|
#define RH_SET_FEATURE 0x0300
|
||||||
|
#define RH_SET_ADDRESS 0x0500
|
||||||
|
#define RH_GET_DESCRIPTOR 0x0680
|
||||||
|
#define RH_SET_DESCRIPTOR 0x0700
|
||||||
|
#define RH_GET_CONFIGURATION 0x0880
|
||||||
|
#define RH_SET_CONFIGURATION 0x0900
|
||||||
|
#define RH_GET_STATE 0x0280
|
||||||
|
#define RH_GET_INTERFACE 0x0A80
|
||||||
|
#define RH_SET_INTERFACE 0x0B00
|
||||||
|
#define RH_SYNC_FRAME 0x0C80
|
||||||
|
/* Our Vendor Specific Request */
|
||||||
|
#define RH_SET_EP 0x2000
|
||||||
|
|
||||||
|
/* Hub port features */
|
||||||
|
#define RH_PORT_CONNECTION 0x00
|
||||||
|
#define RH_PORT_ENABLE 0x01
|
||||||
|
#define RH_PORT_SUSPEND 0x02
|
||||||
|
#define RH_PORT_OVER_CURRENT 0x03
|
||||||
|
#define RH_PORT_RESET 0x04
|
||||||
|
#define RH_PORT_POWER 0x08
|
||||||
|
#define RH_PORT_LOW_SPEED 0x09
|
||||||
|
#define RH_C_PORT_CONNECTION 0x10
|
||||||
|
#define RH_C_PORT_ENABLE 0x11
|
||||||
|
#define RH_C_PORT_SUSPEND 0x12
|
||||||
|
#define RH_C_PORT_OVER_CURRENT 0x13
|
||||||
|
#define RH_C_PORT_RESET 0x14
|
||||||
|
|
||||||
|
/* Hub features */
|
||||||
|
#define RH_C_HUB_LOCAL_POWER 0x00
|
||||||
|
#define RH_C_HUB_OVER_CURRENT 0x01
|
||||||
|
|
||||||
|
#define RH_DEVICE_REMOTE_WAKEUP 0x00
|
||||||
|
#define RH_ENDPOINT_STALL 0x01
|
||||||
|
|
||||||
|
/* Our Vendor Specific feature */
|
||||||
|
#define RH_REMOVE_EP 0x00
|
||||||
|
|
||||||
|
#define RH_ACK 0x01
|
||||||
|
#define RH_REQ_ERR -1
|
||||||
|
#define RH_NACK 0x00
|
||||||
|
|
||||||
|
/* Transfer descriptor structure */
|
||||||
|
typedef struct {
|
||||||
|
unsigned long link; /* next td/qh (LE) */
|
||||||
|
unsigned long status; /* status of the td */
|
||||||
|
unsigned long info; /* Max Lenght / Endpoint / device address and PID */
|
||||||
|
unsigned long buffer; /* pointer to data buffer (LE) */
|
||||||
|
unsigned long dev_ptr; /* pointer to the assigned device (BE) */
|
||||||
|
unsigned long res[3]; /* reserved (TDs must be 8Byte aligned) */
|
||||||
|
} uhci_td_t, *puhci_td_t;
|
||||||
|
|
||||||
|
/* Queue Header structure */
|
||||||
|
typedef struct {
|
||||||
|
unsigned long head; /* Next QH (LE) */
|
||||||
|
unsigned long element; /* Queue element pointer (LE) */
|
||||||
|
unsigned long res[5]; /* reserved */
|
||||||
|
unsigned long dev_ptr; /* if 0 no tds have been assigned to this qh */
|
||||||
|
} uhci_qh_t, *puhci_qh_t;
|
||||||
|
|
||||||
|
struct virt_root_hub {
|
||||||
|
int devnum; /* Address of Root Hub endpoint */
|
||||||
|
int numports; /* number of ports */
|
||||||
|
int c_p_r[8]; /* C_PORT_RESET */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _USB_UHCI_H_ */
|
380
include/ambapp.h
Normal file
380
include/ambapp.h
Normal file
|
@ -0,0 +1,380 @@
|
||||||
|
/* Interface for accessing Gaisler AMBA Plug&Play Bus.
|
||||||
|
* The AHB bus can be interfaced with a simpler bus -
|
||||||
|
* the APB bus, also freely available in GRLIB at
|
||||||
|
* www.gaisler.com.
|
||||||
|
*
|
||||||
|
* (C) Copyright 2007
|
||||||
|
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
|
||||||
|
*
|
||||||
|
* See file CREDITS for list of people who contributed to this
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __AMBAPP_H__
|
||||||
|
#define __AMBAPP_H__
|
||||||
|
|
||||||
|
/* Default location of Plug&Play info
|
||||||
|
* normally 0xfffff000 for AHB masters
|
||||||
|
* and 0xfffff800 for AHB slaves.
|
||||||
|
* Normally no need to change this.
|
||||||
|
*/
|
||||||
|
#define LEON3_IO_AREA 0xfff00000
|
||||||
|
#define LEON3_CONF_AREA 0xff000
|
||||||
|
#define LEON3_AHB_SLAVE_CONF_AREA (1 << 11)
|
||||||
|
|
||||||
|
/* Max devices this software will support */
|
||||||
|
#define LEON3_AHB_MASTERS 16
|
||||||
|
#define LEON3_AHB_SLAVES 16
|
||||||
|
/*#define LEON3_APB_MASTERS 1*//* Number of APB buses that has Plug&Play */
|
||||||
|
#define LEON3_APB_SLAVES 16 /* Total number of APB slaves per APB bus */
|
||||||
|
|
||||||
|
/* Vendor codes */
|
||||||
|
#define VENDOR_GAISLER 1
|
||||||
|
#define VENDOR_PENDER 2
|
||||||
|
#define VENDOR_ESA 4
|
||||||
|
#define VENDOR_ASTRIUM 6
|
||||||
|
#define VENDOR_OPENCHIP 7
|
||||||
|
#define VENDOR_OPENCORES 8
|
||||||
|
#define VENDOR_CONTRIB 9
|
||||||
|
#define VENDOR_EONIC 11
|
||||||
|
#define VENDOR_RADIONOR 15
|
||||||
|
#define VENDOR_GLEICHMANN 16
|
||||||
|
#define VENDOR_MENTA 17
|
||||||
|
#define VENDOR_SUN 19
|
||||||
|
#define VENDOR_EMBEDDIT 234
|
||||||
|
#define VENDOR_CAL 202
|
||||||
|
|
||||||
|
/* Gaisler Research device id's */
|
||||||
|
#define GAISLER_LEON3 0x003
|
||||||
|
#define GAISLER_LEON3DSU 0x004
|
||||||
|
#define GAISLER_ETHAHB 0x005
|
||||||
|
#define GAISLER_APBMST 0x006
|
||||||
|
#define GAISLER_AHBUART 0x007
|
||||||
|
#define GAISLER_SRCTRL 0x008
|
||||||
|
#define GAISLER_SDCTRL 0x009
|
||||||
|
#define GAISLER_APBUART 0x00C
|
||||||
|
#define GAISLER_IRQMP 0x00D
|
||||||
|
#define GAISLER_AHBRAM 0x00E
|
||||||
|
#define GAISLER_GPTIMER 0x011
|
||||||
|
#define GAISLER_PCITRG 0x012
|
||||||
|
#define GAISLER_PCISBRG 0x013
|
||||||
|
#define GAISLER_PCIFBRG 0x014
|
||||||
|
#define GAISLER_PCITRACE 0x015
|
||||||
|
#define GAISLER_PCIDMA 0x016
|
||||||
|
#define GAISLER_AHBTRACE 0x017
|
||||||
|
#define GAISLER_ETHDSU 0x018
|
||||||
|
#define GAISLER_PIOPORT 0x01A
|
||||||
|
#define GAISLER_AHBJTAG 0x01c
|
||||||
|
#define GAISLER_SPW 0x01f
|
||||||
|
#define GAISLER_ATACTRL 0x024
|
||||||
|
#define GAISLER_VGA 0x061
|
||||||
|
#define GAISLER_KBD 0X060
|
||||||
|
#define GAISLER_ETHMAC 0x01D
|
||||||
|
#define GAISLER_DDRSPA 0x025
|
||||||
|
#define GAISLER_EHCI 0x026
|
||||||
|
#define GAISLER_UHCI 0x027
|
||||||
|
#define GAISLER_SPW2 0x029
|
||||||
|
#define GAISLER_DDR2SPA 0x02E
|
||||||
|
#define GAISLER_AHBSTAT 0x052
|
||||||
|
#define GAISLER_FTMCTRL 0x054
|
||||||
|
|
||||||
|
#define GAISLER_L2TIME 0xffd /* internal device: leon2 timer */
|
||||||
|
#define GAISLER_L2C 0xffe /* internal device: leon2compat */
|
||||||
|
#define GAISLER_PLUGPLAY 0xfff /* internal device: plug & play configarea */
|
||||||
|
|
||||||
|
/* European Space Agency device id's */
|
||||||
|
#define ESA_LEON2 0x2
|
||||||
|
#define ESA_MCTRL 0xF
|
||||||
|
|
||||||
|
/* Opencores device id's */
|
||||||
|
#define OPENCORES_PCIBR 0x4
|
||||||
|
#define OPENCORES_ETHMAC 0x5
|
||||||
|
|
||||||
|
/* Vendor codes */
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Macros for manipulating Configuration registers
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define amba_vendor(x) (((x) >> 24) & 0xff)
|
||||||
|
|
||||||
|
#define amba_device(x) (((x) >> 12) & 0xfff)
|
||||||
|
|
||||||
|
#define amba_membar_start(mbar) \
|
||||||
|
(((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16))
|
||||||
|
|
||||||
|
#define amba_iobar_start(base, iobar) \
|
||||||
|
((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4)) )
|
||||||
|
|
||||||
|
#define amba_irq(conf) ((conf) & 0xf)
|
||||||
|
|
||||||
|
#define amba_ver(conf) (((conf)>>5) & 0x1f)
|
||||||
|
|
||||||
|
#define amba_membar_type(mbar) ((mbar) & 0xf)
|
||||||
|
|
||||||
|
#define amba_membar_mask(mbar) (((mbar)>>4) & 0xfff)
|
||||||
|
|
||||||
|
#define AMBA_TYPE_APBIO 0x1
|
||||||
|
#define AMBA_TYPE_MEM 0x2
|
||||||
|
#define AMBA_TYPE_AHBIO 0x3
|
||||||
|
|
||||||
|
#define AMBA_TYPE_AHBIO_ADDR(addr) (LEON3_IO_AREA | ((addr) >> 12))
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types and structure used for AMBA Plug & Play bus scanning
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* AMBA Plug&Play AHB information layout */
|
||||||
|
typedef struct {
|
||||||
|
unsigned int conf;
|
||||||
|
unsigned int userdef[3];
|
||||||
|
unsigned int bars[4];
|
||||||
|
} ahbctrl_pp_dev;
|
||||||
|
|
||||||
|
/* Prototypes for scanning AMBA Plug&Play bus for AMBA
|
||||||
|
* i) AHB Masters
|
||||||
|
* ii) AHB Slaves
|
||||||
|
* iii) APB Slaves (APB MST is a AHB Slave)
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char irq;
|
||||||
|
unsigned char ver;
|
||||||
|
unsigned int address;
|
||||||
|
} ambapp_apbdev;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char irq;
|
||||||
|
unsigned char ver;
|
||||||
|
unsigned int userdef[3];
|
||||||
|
unsigned int address[4];
|
||||||
|
} ambapp_ahbdev;
|
||||||
|
|
||||||
|
/* AMBA Plug&Play AHB Masters & Slaves information locations
|
||||||
|
* Max devices is 64 supported by HW, however often only 8
|
||||||
|
* are used.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
ahbctrl_pp_dev masters[64];
|
||||||
|
ahbctrl_pp_dev slaves[64];
|
||||||
|
} ahbctrl_info;
|
||||||
|
|
||||||
|
/* AMBA Plug&Play AHB information layout */
|
||||||
|
typedef struct {
|
||||||
|
unsigned int conf;
|
||||||
|
unsigned int bar;
|
||||||
|
} apbctrl_pp_dev;
|
||||||
|
|
||||||
|
/* All functions return the number of found devices
|
||||||
|
* 0 = no devices found
|
||||||
|
*/
|
||||||
|
|
||||||
|
/****************************** APB SLAVES ******************************/
|
||||||
|
int ambapp_apb_count(unsigned int vendor, unsigned int driver);
|
||||||
|
|
||||||
|
int ambapp_apb_first(unsigned int vendor,
|
||||||
|
unsigned int driver, ambapp_apbdev * dev);
|
||||||
|
|
||||||
|
int ambapp_apb_next(unsigned int vendor,
|
||||||
|
unsigned int driver, ambapp_apbdev * dev, int index);
|
||||||
|
|
||||||
|
int ambapp_apbs_first(unsigned int vendor,
|
||||||
|
unsigned int driver, ambapp_apbdev * dev, int max_cnt);
|
||||||
|
|
||||||
|
/****************************** AHB MASTERS ******************************/
|
||||||
|
int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver);
|
||||||
|
|
||||||
|
int ambapp_ahbmst_first(unsigned int vendor,
|
||||||
|
unsigned int driver, ambapp_ahbdev * dev);
|
||||||
|
|
||||||
|
int ambapp_ahbmst_next(unsigned int vendor,
|
||||||
|
unsigned int driver, ambapp_ahbdev * dev, int index);
|
||||||
|
|
||||||
|
int ambapp_ahbmsts_first(unsigned int vendor,
|
||||||
|
unsigned int driver, ambapp_ahbdev * dev, int max_cnt);
|
||||||
|
|
||||||
|
/****************************** AHB SLAVES ******************************/
|
||||||
|
int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver);
|
||||||
|
|
||||||
|
int ambapp_ahbslv_first(unsigned int vendor,
|
||||||
|
unsigned int driver, ambapp_ahbdev * dev);
|
||||||
|
|
||||||
|
int ambapp_ahbslv_next(unsigned int vendor,
|
||||||
|
unsigned int driver, ambapp_ahbdev * dev, int index);
|
||||||
|
|
||||||
|
int ambapp_ahbslvs_first(unsigned int vendor,
|
||||||
|
unsigned int driver, ambapp_ahbdev * dev, int max_cnt);
|
||||||
|
|
||||||
|
/*************************** AHB/APB only regs functions *************************
|
||||||
|
* During start up, no memory is available we can use the simplified functions
|
||||||
|
* to get to the memory controller.
|
||||||
|
*
|
||||||
|
* Functions uses no stack/memory, only registers.
|
||||||
|
*/
|
||||||
|
unsigned int ambapp_apb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */
|
||||||
|
register unsigned int driver, /* Plug&Play Device ID */
|
||||||
|
register int index);
|
||||||
|
|
||||||
|
ahbctrl_pp_dev *ambapp_ahb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */
|
||||||
|
register unsigned int driver, /* Plug&Play Device ID */
|
||||||
|
register unsigned int opts, /* scan for AHB 1=slave, 0=masters */
|
||||||
|
register int index);
|
||||||
|
|
||||||
|
unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info);
|
||||||
|
|
||||||
|
/*************************** AMBA Plug&Play device register MAPS *****************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following defines the bits in the LEON UART Status Registers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LEON_REG_UART_STATUS_DR 0x00000001 /* Data Ready */
|
||||||
|
#define LEON_REG_UART_STATUS_TSE 0x00000002 /* TX Send Register Empty */
|
||||||
|
#define LEON_REG_UART_STATUS_THE 0x00000004 /* TX Hold Register Empty */
|
||||||
|
#define LEON_REG_UART_STATUS_BR 0x00000008 /* Break Error */
|
||||||
|
#define LEON_REG_UART_STATUS_OE 0x00000010 /* RX Overrun Error */
|
||||||
|
#define LEON_REG_UART_STATUS_PE 0x00000020 /* RX Parity Error */
|
||||||
|
#define LEON_REG_UART_STATUS_FE 0x00000040 /* RX Framing Error */
|
||||||
|
#define LEON_REG_UART_STATUS_ERR 0x00000078 /* Error Mask */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following defines the bits in the LEON UART Ctrl Registers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LEON_REG_UART_CTRL_RE 0x00000001 /* Receiver enable */
|
||||||
|
#define LEON_REG_UART_CTRL_TE 0x00000002 /* Transmitter enable */
|
||||||
|
#define LEON_REG_UART_CTRL_RI 0x00000004 /* Receiver interrupt enable */
|
||||||
|
#define LEON_REG_UART_CTRL_TI 0x00000008 /* Transmitter interrupt enable */
|
||||||
|
#define LEON_REG_UART_CTRL_PS 0x00000010 /* Parity select */
|
||||||
|
#define LEON_REG_UART_CTRL_PE 0x00000020 /* Parity enable */
|
||||||
|
#define LEON_REG_UART_CTRL_FL 0x00000040 /* Flow control enable */
|
||||||
|
#define LEON_REG_UART_CTRL_LB 0x00000080 /* Loop Back enable */
|
||||||
|
#define LEON_REG_UART_CTRL_DBG (1<<11) /* Debug Bit used by GRMON */
|
||||||
|
|
||||||
|
#define LEON3_GPTIMER_EN 1
|
||||||
|
#define LEON3_GPTIMER_RL 2
|
||||||
|
#define LEON3_GPTIMER_LD 4
|
||||||
|
#define LEON3_GPTIMER_IRQEN 8
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following defines the bits in the LEON PS/2 Status Registers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LEON_REG_PS2_STATUS_DR 0x00000001 /* Data Ready */
|
||||||
|
#define LEON_REG_PS2_STATUS_PE 0x00000002 /* Parity error */
|
||||||
|
#define LEON_REG_PS2_STATUS_FE 0x00000004 /* Framing error */
|
||||||
|
#define LEON_REG_PS2_STATUS_KI 0x00000008 /* Keyboard inhibit */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following defines the bits in the LEON PS/2 Ctrl Registers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LEON_REG_PS2_CTRL_RE 0x00000001 /* Receiver enable */
|
||||||
|
#define LEON_REG_PS2_CTRL_TE 0x00000002 /* Transmitter enable */
|
||||||
|
#define LEON_REG_PS2_CTRL_RI 0x00000004 /* Keyboard receive interrupt */
|
||||||
|
#define LEON_REG_PS2_CTRL_TI 0x00000008 /* Keyboard transmit interrupt */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
volatile unsigned int ilevel;
|
||||||
|
volatile unsigned int ipend;
|
||||||
|
volatile unsigned int iforce;
|
||||||
|
volatile unsigned int iclear;
|
||||||
|
volatile unsigned int mstatus;
|
||||||
|
volatile unsigned int notused[11];
|
||||||
|
volatile unsigned int cpu_mask[16];
|
||||||
|
volatile unsigned int cpu_force[16];
|
||||||
|
} ambapp_dev_irqmp;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
volatile unsigned int data;
|
||||||
|
volatile unsigned int status;
|
||||||
|
volatile unsigned int ctrl;
|
||||||
|
volatile unsigned int scaler;
|
||||||
|
} ambapp_dev_apbuart;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
volatile unsigned int val;
|
||||||
|
volatile unsigned int rld;
|
||||||
|
volatile unsigned int ctrl;
|
||||||
|
volatile unsigned int unused;
|
||||||
|
} ambapp_dev_gptimer_element;
|
||||||
|
|
||||||
|
#define LEON3_GPTIMER_CTRL_EN 0x1 /* Timer enable */
|
||||||
|
#define LEON3_GPTIMER_CTRL_RS 0x2 /* Timer reStart */
|
||||||
|
#define LEON3_GPTIMER_CTRL_LD 0x4 /* Timer reLoad */
|
||||||
|
#define LEON3_GPTIMER_CTRL_IE 0x8 /* interrupt enable */
|
||||||
|
#define LEON3_GPTIMER_CTRL_IP 0x10 /* interrupt flag/pending */
|
||||||
|
#define LEON3_GPTIMER_CTRL_CH 0x20 /* Chain with previous timer */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
volatile unsigned int scalar;
|
||||||
|
volatile unsigned int scalar_reload;
|
||||||
|
volatile unsigned int config;
|
||||||
|
volatile unsigned int unused;
|
||||||
|
volatile ambapp_dev_gptimer_element e[8];
|
||||||
|
} ambapp_dev_gptimer;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
volatile unsigned int iodata;
|
||||||
|
volatile unsigned int ioout;
|
||||||
|
volatile unsigned int iodir;
|
||||||
|
volatile unsigned int irqmask;
|
||||||
|
volatile unsigned int irqpol;
|
||||||
|
volatile unsigned int irqedge;
|
||||||
|
} ambapp_dev_ioport;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
volatile unsigned int write;
|
||||||
|
volatile unsigned int dummy;
|
||||||
|
volatile unsigned int txcolor;
|
||||||
|
volatile unsigned int bgcolor;
|
||||||
|
} ambapp_dev_textvga;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
volatile unsigned int data;
|
||||||
|
volatile unsigned int status;
|
||||||
|
volatile unsigned int ctrl;
|
||||||
|
} ambapp_dev_apbps2;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int mcfg1, mcfg2, mcfg3;
|
||||||
|
} ambapp_dev_mctrl;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int sdcfg;
|
||||||
|
} ambapp_dev_sdctrl;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int cfg1;
|
||||||
|
unsigned int cfg2;
|
||||||
|
unsigned int cfg3;
|
||||||
|
} ambapp_dev_ddr2spa;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int ctrl;
|
||||||
|
unsigned int cfg;
|
||||||
|
} ambapp_dev_ddrspa;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
36
include/asm-sparc/arch-leon3/asi.h
Normal file
36
include/asm-sparc/arch-leon3/asi.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/* asi.h: Address Space Identifier values for the LEON3 sparc.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Daniel Hellstrom (daniel@gaisler.com)
|
||||||
|
*
|
||||||
|
* See file CREDITS for list of people who contributed to this
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LEON3_ASI_H
|
||||||
|
#define _LEON3_ASI_H
|
||||||
|
|
||||||
|
#define ASI_CACHEMISS 0x01 /* Force D-Cache miss on load (lda) */
|
||||||
|
#define ASI_M_FLUSH_PROBE 0x03 /* MMU Flush/Probe */
|
||||||
|
#define ASI_IFLUSH 0x10 /* Flush I-Cache */
|
||||||
|
#define ASI_DFLUSH 0x11 /* Flush D-Cache */
|
||||||
|
#define ASI_BYPASS 0x1c /* Bypass MMU (Physical address) */
|
||||||
|
#define ASI_MMUFLUSH 0x18 /* FLUSH TLB */
|
||||||
|
#define ASI_M_MMUREGS 0x19 /* READ/Write MMU Registers */
|
||||||
|
|
||||||
|
#endif /* _LEON3_ASI_H */
|
38
include/asm-sparc/leon.h
Normal file
38
include/asm-sparc/leon.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/* LEON Header File select
|
||||||
|
*
|
||||||
|
* (C) Copyright 2007
|
||||||
|
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ASM_LEON_H__
|
||||||
|
#define __ASM_LEON_H__
|
||||||
|
|
||||||
|
#if defined(CONFIG_LEON3)
|
||||||
|
|
||||||
|
#include <asm/leon3.h>
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#error Unknown LEON processor
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Common stuff */
|
||||||
|
|
||||||
|
#endif
|
37
include/asm-sparc/leon3.h
Normal file
37
include/asm-sparc/leon3.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/* LEON3 header file. LEON3 is a free GPL SOC processor available
|
||||||
|
* at www.gaisler.com.
|
||||||
|
*
|
||||||
|
* (C) Copyright 2007
|
||||||
|
* Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __LEON3_H__
|
||||||
|
#define __LEON3_H__
|
||||||
|
|
||||||
|
#ifndef CONFIG_LEON3
|
||||||
|
#error Include LEON3 header file only if LEON3 processor
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Not much to define, most is Plug and Play and GRLIB dependent
|
||||||
|
* not LEON3 dependent. See <ambapp.h> for GRLIB timers, interrupt
|
||||||
|
* ctrl, memory controllers etc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -26,8 +26,15 @@
|
||||||
|
|
||||||
#include <asm/arch/asi.h>
|
#include <asm/arch/asi.h>
|
||||||
|
|
||||||
/* Includeprocessor specific header file here */
|
#ifdef CONFIG_LEON
|
||||||
|
|
||||||
|
/* All LEON processors supported */
|
||||||
|
#include <asm/leon.h>
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* other processors */
|
||||||
#error Unknown SPARC Processor
|
#error Unknown SPARC Processor
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user