Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>master
parent
bf3d8b3116
commit
1e9a164e22
@ -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 |
||||
|
||||
#########################################################################
|
@ -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); |
||||
} |
@ -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
|
@ -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); |
||||
} |
||||
|
||||
/* ------------------------------------------------------------------------- */ |
@ -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; |
||||
} |
@ -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 |
File diff suppressed because it is too large
Load Diff
@ -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; |
||||
} |
@ -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 |
File diff suppressed because it is too large
Load Diff
@ -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_ */ |
@ -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 |
@ -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 */ |
@ -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 |
@ -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 |
Loading…
Reference in new issue