diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2011-12-15 22:58:40 +0000 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2011-12-15 22:58:40 +0000 |
commit | 8e0346d1372ed32d2c5f559e083f3bd60b281c3a (patch) | |
tree | b72116c382df57f2e7396b58d32370b731535712 /libgloss/sparc_leon/asm-leon | |
parent | e74758408e50f8980de0d73f5b3721efbd698df9 (diff) | |
download | cygnal-8e0346d1372ed32d2c5f559e083f3bd60b281c3a.tar.gz cygnal-8e0346d1372ed32d2c5f559e083f3bd60b281c3a.tar.bz2 cygnal-8e0346d1372ed32d2c5f559e083f3bd60b281c3a.zip |
2011-12-15 Konrad Eisele <konrad@gaisler.com>
* configure.in: Add SPARC LEON support.
* configure: Regenerated.
* sparc_leon/asm-leon/amba.h, sparc_leon/asm-leon/asmmacro.h,
sparc_leon/asm-leon/clock.h, sparc_leon/asm-leon/contextswitch.h,
sparc_leon/asm-leon/elfmacro.h, sparc_leon/asm-leon/head.h,
sparc_leon/asm-leon/irq.h, sparc_leon/asm-leon/jiffies.h,
sparc_leon/asm-leon/lambapp.h, sparc_leon/asm-leon/lambapp_devs.h,
sparc_leon/asm-leon/leon.h, sparc_leon/asm-leon/leon3.h,
sparc_leon/asm-leon/leonbare_debug.h, sparc_leon/asm-leon/leonbare_kernel.h,
sparc_leon/asm-leon/leonbare_kernel_queue.h, sparc_leon/asm-leon/leoncompat.h,
sparc_leon/asm-leon/leondbg.h, sparc_leon/asm-leon/leonstack.h,
sparc_leon/asm-leon/liblocks.h, sparc_leon/asm-leon/linkage.h,
sparc_leon/asm-leon/param.h, sparc_leon/asm-leon/queue.h,
sparc_leon/asm-leon/spinlock.h, sparc_leon/asm-leon/stack.h,
sparc_leon/asm-leon/time.h, sparc_leon/asm-leon/timer.h,
sparc_leon/asm-leon/types.h, sparc_leon/asm-leon/winmacros.h:
New file.
* sparc_leon/Makefile.in, sparc_leon/_exit.c,
sparc_leon/amba.c, sparc_leon/amba_dbg.c,
sparc_leon/amba_driver.c, sparc_leon/amba_scan.c,
sparc_leon/asm-leon, sparc_leon/bdinit.S,
sparc_leon/busscan.S, sparc_leon/cacheA.S,
sparc_leon/catch_interrupt.c, sparc_leon/catch_interrupt_mvt.c,
sparc_leon/catch_interrupt_pending.c, sparc_leon/catch_interrupt_svt.c,
sparc_leon/configure.in,
sparc_leon/console.c, sparc_leon/console_dbg.c,
sparc_leon/console_init.c, sparc_leon/contextswitch.c,
sparc_leon/contextswitch_asm.S, sparc_leon/crt0.S,
sparc_leon/crti.S, sparc_leon/crtn.S,
sparc_leon/etrap.S, sparc_leon/etrap_fast.S,
sparc_leon/fpu.S, sparc_leon/gettimeofday.c,
sparc_leon/initcalls.c, sparc_leon/io.c,
sparc_leon/irqinstall.S, sparc_leon/irqtrap.S,
sparc_leon/irqtrap_fast.S, sparc_leon/jiffies.c,
sparc_leon/kernel.c, sparc_leon/kernel_context.S,
sparc_leon/kernel_debug.c, sparc_leon/kernel_debug_var.c,
sparc_leon/kernel_mm.c, sparc_leon/kernel_mutex.c,
sparc_leon/kernel_queue.c, sparc_leon/kernel_sched.c,
sparc_leon/kernel_thread.c, sparc_leon/lcpuinit.S,
sparc_leon/locore.S, sparc_leon/locore_atexit.c,
sparc_leon/locore_clean.S, sparc_leon/locore_mvt.S,
sparc_leon/locore_mvt_reset.S, sparc_leon/locore_svt.S,
sparc_leon/locore_svt_reset.S, sparc_leon/locore_svtdisp.S,
sparc_leon/locore_var.S, sparc_leon/locore_var_svt.S,
sparc_leon/mmu_asm.S, sparc_leon/mutex.c,
sparc_leon/nocache.S, sparc_leon/pnpinit.c,
sparc_leon/pnpinit_malloc.c, sparc_leon/pnpinit_simple.c,
sparc_leon/regwin.S, sparc_leon/regwin_patch.c,
sparc_leon/regwin_slow.S, sparc_leon/regwinflush.S,
sparc_leon/rtc.c, sparc_leon/rtrap.S,
sparc_leon/rtrap_fast.S, sparc_leon/stop.S,
sparc_leon/timer.c, sparc_leon/times.c:
New file
* sparc_leon/configure: Regenerate
Diffstat (limited to 'libgloss/sparc_leon/asm-leon')
28 files changed, 3937 insertions, 0 deletions
diff --git a/libgloss/sparc_leon/asm-leon/amba.h b/libgloss/sparc_leon/asm-leon/amba.h new file mode 100644 index 000000000..0dd2d987f --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/amba.h @@ -0,0 +1,429 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef _LEON3_AMBA_H__ +#define _LEON3_AMBA_H__ + +#define LEON3_IO_AREA 0xfff00000 +#define LEON3_CONF_AREA 0xff000 +#define LEON3_AHB_SLAVE_CONF_AREA (1 << 11) + +#define LEON3_AHB_CONF_WORDS 8 +#define LEON3_APB_CONF_WORDS 2 +#define LEON3_AHB_MASTERS 8 +#define LEON3_AHB_SLAVES 8 +#define LEON3_APB_SLAVES 16 +#define LEON3_APBUARTS 8 + +/* Vendor codes */ +#define VENDOR_GAISLER 1 +#define VENDOR_PENDER 2 +#define VENDOR_ESA 4 +#define VENDOR_OPENCORES 8 + +/* 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_SPACEWIRE 0x01f + +#define GAISLER_ETHMAC 0x01d +#define GAISLER_EHCI 0x026 +#define GAISLER_UHCI 0x027 + +#define GAISLER_L2TIME 0xffd /* internal device: leon2 timer */ +#define GAISLER_L2C 0xffe /* internal device: leon2compat */ +#define GAISLER_PLUGPLAY 0xfff /* internal device: plug & play configarea */ + +#ifndef __ASSEMBLER__ + +extern inline char * +gaisler_device_str (int id) +{ + switch (id) + { + case GAISLER_LEON3: + return "GAISLER_LEON3"; + case GAISLER_LEON3DSU: + return "GAISLER_LEON3DSU"; + case GAISLER_ETHAHB: + return "GAISLER_ETHAHB"; + case GAISLER_APBMST: + return "GAISLER_APBMST"; + case GAISLER_AHBUART: + return "GAISLER_AHBUART"; + case GAISLER_SRCTRL: + return "GAISLER_SRCTRL"; + case GAISLER_SDCTRL: + return "GAISLER_SDCTRL"; + case GAISLER_APBUART: + return "GAISLER_APBUART"; + case GAISLER_IRQMP: + return "GAISLER_IRQMP"; + case GAISLER_AHBRAM: + return "GAISLER_AHBRAM"; + case GAISLER_GPTIMER: + return "GAISLER_GPTIMER"; + case GAISLER_PCITRG: + return "GAISLER_PCITRG"; + case GAISLER_PCISBRG: + return "GAISLER_PCISBRG"; + case GAISLER_PCIFBRG: + return "GAISLER_PCIFBRG"; + case GAISLER_PCITRACE: + return "GAISLER_PCITRACE"; + case GAISLER_AHBTRACE: + return "GAISLER_AHBTRACE"; + case GAISLER_ETHDSU: + return "GAISLER_ETHDSU"; + case GAISLER_PIOPORT: + return "GAISLER_PIOPORT"; + case GAISLER_SPACEWIRE: + return "GAISLER_SPACEWIRE"; + + + case GAISLER_L2TIME: + return "GAISLER_L2TIME"; + case GAISLER_L2C: + return "GAISLER_L2C"; + case GAISLER_PLUGPLAY: + return "GAISLER_PLUGPLAY"; + + default: + break; + } + return 0; +} + +#endif + +/* European Space Agency device id's */ +#define ESA_LEON2 0x002 +#define ESA_MCTRL 0x00f + +#ifndef __ASSEMBLER__ + +extern inline char * +esa_device_str (int id) +{ + switch (id) + { + case ESA_LEON2: + return "ESA_LEON2"; + case ESA_MCTRL: + return "ESA_MCTRL"; + default: + break; + } + return 0; +} + +#endif + +/* Opencores device id's */ +#define OPENCORES_PCIBR 0x4 +#define OPENCORES_ETHMAC 0x5 + +#ifndef __ASSEMBLER__ + +extern inline char * +opencores_device_str (int id) +{ + switch (id) + { + case OPENCORES_PCIBR: + return "OPENCORES_PCIBR"; + case OPENCORES_ETHMAC: + return "OPENCORES_ETHMAC"; + default: + break; + } + return 0; +} + +extern inline char * +device_id2str (int vendor, int id) +{ + switch (vendor) + { + case VENDOR_GAISLER: + return gaisler_device_str (id); + case VENDOR_ESA: + return esa_device_str (id); + case VENDOR_OPENCORES: + return opencores_device_str (id); + case VENDOR_PENDER: + default: + break; + } + return 0; +} + +extern inline char * +vendor_id2str (int vendor) +{ + switch (vendor) + { + case VENDOR_GAISLER: + return "VENDOR_GAISLER"; + case VENDOR_ESA: + return "VENDOR_ESA"; + case VENDOR_OPENCORES: + return "VENDOR_OPENCORES"; + case VENDOR_PENDER: + return "VENDOR_PENDER"; + default: + break; + } + return 0; +} + +#endif + +/* Vendor codes */ + +/* + * + * Macros for manipulating Configuration registers + * + */ + +#define LEON3_BYPASS_LOAD_PA(x) (*((unsigned long*)x)) +#define LEON3_BYPASS_STORE_PA(x,v) (*((unsigned long*)x) = (v)) + +#define amba_get_confword(tab, index, word) (*((tab).addr[(index)]+(word))) + +#define amba_vendor(x) (((x) >> 24) & 0xff) + +#define amba_device(x) (((x) >> 12) & 0xfff) + +#define amba_ahb_get_membar(tab, index, nr) (*((tab).addr[(index)]+4+(nr))) + +#define amba_apb_get_membar(tab, index) (*((tab).addr[(index)]+1)) + +#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_membar_type(mbar) ((mbar) & 0xf) + +#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__ + +/* + * 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 LEON3_GPTIMER_EN 1 +#define LEON3_GPTIMER_RL 2 +#define LEON3_GPTIMER_LD 4 +#define LEON3_GPTIMER_IRQEN 8 +#define LEON3_GPTIMER_IP 0x10 + +#define LEON3_GPTIMER_CONFIG_TIMERMASK 0x7 +#define LEON3_GPTIMER_CONFIG_SEPERATE (1<<8) + +typedef struct +{ + volatile unsigned int ilevel; + volatile unsigned int ipend; + volatile unsigned int iforce; + volatile unsigned int iclear; + volatile unsigned int notused00; + volatile unsigned int notused01; + volatile unsigned int notused02; + volatile unsigned int notused03; + volatile unsigned int notused10; + volatile unsigned int notused11; + volatile unsigned int notused12; + volatile unsigned int notused13; + volatile unsigned int notused20; + volatile unsigned int notused21; + volatile unsigned int notused22; + volatile unsigned int notused23; + volatile unsigned int mask[16]; +} LEON3_IrqCtrl_Regs_Map; +extern volatile LEON3_IrqCtrl_Regs_Map *LEON3_IrqCtrl_Regs; /* in amba.c */ + +typedef struct +{ + volatile unsigned int data; + volatile unsigned int status; + volatile unsigned int ctrl; + volatile unsigned int scaler; +} LEON23_APBUART_Regs_Map; +extern volatile LEON23_APBUART_Regs_Map *leon23_uarts[2]; /* in console.c */ +extern unsigned int leon23_irqs[2]; /* in console.c */ + +typedef struct +{ + volatile unsigned int val; + volatile unsigned int rld; + volatile unsigned int ctrl; + volatile unsigned int unused; +} LEON3_GpTimerElem_Regs_Map; + + +typedef struct +{ + volatile unsigned int scalar; + volatile unsigned int scalar_reload; + volatile unsigned int config; + volatile unsigned int unused; + volatile LEON3_GpTimerElem_Regs_Map e[8]; +} LEON3_GpTimer_Regs_Map; +#define LEON3_GPTIMER_CONFIG_NRTIMERS(c) ((c)->config & 0x7) +int Timer_getTimer1 (unsigned int **count, unsigned int **reload, unsigned int **ctrl); /* in timer.c */ +int Timer_getTimer2 (unsigned int **count, unsigned int **reload, unsigned int **ctrl); /* in timer.c */ +extern volatile LEON3_GpTimer_Regs_Map *LEON3_GpTimer_Regs; +extern unsigned long LEON3_GpTimer_Irq; + +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; +} LEON3_IOPORT_Regs_Map; + + +/* + * Types and structure used for AMBA Plug & Play bus scanning + */ +extern int amba_init_done; + +#define AMBA_MAXAPB_DEVS 64 +#define AMBA_MAXAPB_DEVS_PERBUS 16 + +typedef struct amba_device_table +{ + int devnr; /* numbrer of devices on AHB or APB bus */ + unsigned int *addr[16]; /* addresses to the devices configuration tables */ + unsigned int allocbits[1]; /* 0=unallocated, 1=allocated driver */ +} amba_device_table; + +typedef struct amba_apbslv_device_table +{ + int devnr; /* number of devices on AHB or APB bus */ + unsigned int *addr[AMBA_MAXAPB_DEVS]; /* addresses to the devices configuration tables */ + unsigned int apbmst[AMBA_MAXAPB_DEVS]; /* apb master if a entry is a apb slave */ + unsigned int apbmstidx[AMBA_MAXAPB_DEVS]; /* apb master idx if a entry is a apb slave */ + unsigned int allocbits[4]; /* 0=unallocated, 1=allocated driver */ +} amba_apbslv_device_table; + +typedef struct amba_confarea_type +{ + amba_device_table ahbmst; + amba_device_table ahbslv; + amba_apbslv_device_table apbslv; + /*unsigned int apbmst; */ +} amba_confarea_type; + + +extern unsigned long amba_find_apbslv_addr (unsigned long vendor, + unsigned long device, + unsigned long *irq); + +// collect apb slaves +typedef struct amba_apb_device +{ + unsigned int start, irq; +} amba_apb_device; +extern int amba_get_free_apbslv_devices (int vendor, int device, + amba_apb_device * dev, int nr); + +// collect ahb slaves +typedef struct amba_ahb_device +{ + unsigned int start[4], irq; +} amba_ahb_device; +extern int amba_get_free_ahbslv_devices (int vendor, int device, + amba_ahb_device * dev, int nr); + + +/*amba_scan.c*/ +unsigned int leon3_getapbbase (register unsigned int vendor, + register unsigned int driver, + amba_apb_device * apbdevs, int c); + +#endif //!__ASSEMBLER__ + + + + + +#endif diff --git a/libgloss/sparc_leon/asm-leon/asmmacro.h b/libgloss/sparc_leon/asm-leon/asmmacro.h new file mode 100644 index 000000000..c210d0e92 --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/asmmacro.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef _INCLUDE_LEON_ASMMACRO_h +#define _INCLUDE_LEON_ASMMACRO_h + +#include <asm-leon/leonstack.h> + +/* All trap entry points _must_ begin with this macro or else you + * lose. It makes sure the kernel has a proper window so that + * c-code can be called. + */ +#define SAVE_ALL_HEAD \ + sethi %hi(leonbare_trapsetup), %l4; \ + jmpl %l4 + %lo(leonbare_trapsetup), %l6; +#define SAVE_ALL \ + SAVE_ALL_HEAD \ + nop; + +#define SAVE_ALL_FAST(l) \ + set l-8, %l6; \ + sethi %hi(leonbare_trapsetup_fast), %l4; \ + jmpl %l4 + %lo(leonbare_trapsetup_fast), %g0; \ + nop; + +/* All traps low-level code here must end with this macro. */ +#define RESTORE_ALL b leonbare_trapreturn; clr %l6; +#define RESTORE_ALL_FAST b leonbare_trapreturn_fast; clr %l6; + +#define WRITE_PAUSE nop; nop; nop; + +#endif /* !_INCLUDE_LEON_STACK_h */ diff --git a/libgloss/sparc_leon/asm-leon/clock.h b/libgloss/sparc_leon/asm-leon/clock.h new file mode 100644 index 000000000..189e942e1 --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/clock.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef _ASMSPARC_CLOCK_PARAM_H +#define _ASMSPARC_CLOCK_PARAM_H + +#include <_ansi.h> +#include <asm-leon/param.h> + +#ifndef __ASSEMBLER__ +int _EXFUN (gettimeofday, (struct timeval * __p, void *__tz)); +int _EXFUN (settimeofday, (const struct timeval *, const struct timezone *)); +void do_gettimeofday (struct timeval *tv); +#endif + +#define USEC_PER_SEC (1000000L) +#define NSEC_PER_SEC (1000000000L) +#define NSEC_PER_USEC (1000L) + +extern unsigned long tick_nsec; +extern unsigned long tick_usec; + +#endif diff --git a/libgloss/sparc_leon/asm-leon/contextswitch.h b/libgloss/sparc_leon/asm-leon/contextswitch.h new file mode 100644 index 000000000..8150ac8b6 --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/contextswitch.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef H_LEONBARE_CONTEXTSWITCH_H +#define H_LEONBARE_CONTEXTSWITCH_H + + +/* + * for this version, the index of THREAD_JB_SP must be even !!! + * This way, we can speed up the context switch (using std). + */ +#define THREAD_JB_SP 0 /* aligned */ +#define THREAD_JB_PC 1 +#define THREAD_JB_SVMASK 3 +#define THREAD_JB_MASK 4 +#define THREAD_JB_FP 5 +#define THREAD_JB_I7 6 + +#define THREAD_JB_PSR 8 /* aligned */ +#define THREAD_JB_WIM 9 + +#define THREAD_JB_FPUCTX 10 + +#ifndef __ASSEMBLER__ + +extern unsigned long fpustate_current; + +typedef int threadctx_t[14 + 2] __attribute__ ((aligned (8))); + +int thread_setjmp (threadctx_t env, int val); +void thread_longjmp (threadctx_t env, int val); +void _switch_to (threadctx_t env, int val); + +#endif /* __ASSEMBLER__ */ + +#endif diff --git a/libgloss/sparc_leon/asm-leon/elfmacro.h b/libgloss/sparc_leon/asm-leon/elfmacro.h new file mode 100644 index 000000000..02dfdc985 --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/elfmacro.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef _INCLUDE_LEON_ELFMACRO_h +#define _INCLUDE_LEON_ELFMACRO_h + +#ifdef __ASSEMBLER__ +#define _TEXT_SEG_ALIGN 4 +#define _LIBLEONBARE_TEXT_SEG_START \ + .text ; .balign _TEXT_SEG_ALIGN +#define FUNC_BEGIN(func) func: +#define FUNC_END(func) .size func, . - func + +#define GTEXT(sym) sym ; .type sym,@function +#define GDATA(sym) sym ; .type sym,@object + +#define FUNC_EXPORT(func) .globl GTEXT(func) +#define DATA_EXPORT(var) .globl GDATA(var) + +#define FUNC_IMPORT(func) .extern FUNC(func) +#define DATA_IMPORT(var) .extern var +#endif + +#ifndef weak_alias +/* Define ALIASNAME as a weak alias for NAME. */ +# define weak_alias(name, aliasname) _weak_alias (name, aliasname) +# define _weak_alias(name, aliasname) \ + extern __typeof (name) aliasname __attribute__ ((weak, alias (#name))); +#endif + +#ifndef strong_alias +/* Define ALIASNAME as a strong alias for NAME. */ +# define strong_alias(name, aliasname) _strong_alias(name, aliasname) +# define _strong_alias(name, aliasname) \ + extern __typeof (name) aliasname __attribute__ ((alias (#name))); +#endif + +#ifndef __ASSEMBLER__ +typedef int (*initcall_t) (void); +extern initcall_t __leonbare_initcall_start; +extern initcall_t __leonbare_initcall_end; + +#endif + +#if __GNUC_MINOR__ >= 3 +# define __attribute_used__ __attribute__((__used__)) +#else +# define __attribute_used__ __attribute__((__unused__)) +#endif + +#define __define_initcall(level,fn) \ + static initcall_t __initcall_##fn __attribute_used__ \ + __attribute__((__section__(".initcall" level ".init"))) = fn + +#define libc_initcall(fn) __define_initcall("1",fn) + +#endif /* !_INCLUDE_LEON_STACK_h */ diff --git a/libgloss/sparc_leon/asm-leon/head.h b/libgloss/sparc_leon/asm-leon/head.h new file mode 100644 index 000000000..83aa4ae68 --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/head.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef __LEONBARE_HEAD_H +#define __LEONBARE_HEAD_H + +/* This is for hard interrupts from level 1-14, 15 is non-maskable (nmi) and + * gets handled with another macro. + */ +#define TRAP_ENTRY_INTERRUPT(int_level) \ + mov int_level, %l7; rd %psr, %l0; b leonbare_irq_entry; rd %wim, %l3; + +#define TRAP_ENTRY(H) \ + rd %psr, %l0; b H; rd %wim, %l3; nop; + + +#endif /* __SPARC_HEAD_H */ diff --git a/libgloss/sparc_leon/asm-leon/irq.h b/libgloss/sparc_leon/asm-leon/irq.h new file mode 100644 index 000000000..5f542d594 --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/irq.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef _LEON_CATCHIRQ_HANDLER_H_ +#define _LEON_CATCHIRQ_HANDLER_H_ + +#include <asm-leon/leon.h> +#include <asm-leon/queue.h> +/*#include <sys/fsu_pthread_queue.h>*/ +#include <asm-leon/leoncompat.h> +#include <asm-leon/leonstack.h> + +#ifndef __ASSEMBLER__ + +struct pt_regs; +typedef int (*irqhandler) (int, void *, struct leonbare_pt_regs *); + +struct irqaction +{ + irqhandler handler; + unsigned long flags; + void *dev_id; + struct irqaction *next; +}; +#define INIT_IRQACTION { 0,0,0,0 } + +struct irqmp_type +{ + int *addr; + int eirq; +}; + +extern void chained_catch_interrupt (int irq, struct irqaction *a); +extern int catch_interrupt (int func, int irq); + +typedef int (*schedulehandler) (struct leonbare_pt_regs *); +extern schedulehandler schedule_callback; +typedef int (*tickerhandler) (struct leonbare_pt_regs *); +extern tickerhandler ticker_callback; +extern int leonbare_hz; +extern int nestcount; +extern int no_inirq_check; +extern unsigned long force_noalarm; + +extern void (*handler_irq_pre) (void); +extern void (*handler_irq_post) (void); + +extern void leonbare_enable_traps (unsigned long old_flags); +extern unsigned long leonbare_disable_traps (); +extern void leonbare_flush_windows (); + +static inline void +leonbare_enable_irq (int irq) +{ + unsigned int old, irqmask = 1 << irq; + old = leonbare_disable_traps (); + //--------------------- + switch (LEONCOMPAT_VERSION) + { + case 3: + default: + LEON3_IrqCtrl_Regs->mask[0] = LEON3_IrqCtrl_Regs->mask[0] | irqmask; + break; + } + //--------------------- + leonbare_enable_traps (old); +} + +typedef int (*pendinghandler) (void *); +struct pendingaction +{ + TAILQ_ENTRY (pendingaction) next; + pendinghandler handler; + void *arg; +}; + +#endif + +#endif diff --git a/libgloss/sparc_leon/asm-leon/jiffies.h b/libgloss/sparc_leon/asm-leon/jiffies.h new file mode 100644 index 000000000..60b0e2701 --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/jiffies.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef _LINUX_JIFFIES_H +#define _LINUX_JIFFIES_H + +#include <asm-leon/types.h> +#include <asm-leon/clock.h> +#include <asm-leon/linkage.h> + +/* Suppose we want to devide two numbers NOM and DEN: NOM/DEN, the we can + * improve accuracy by shifting LSH bits, hence calculating: + * (NOM << LSH) / DEN + * This however means trouble for large NOM, because (NOM << LSH) may no + * longer fit in 32 bits. The following way of calculating this gives us + * some slack, under the following conditions: + * - (NOM / DEN) fits in (32 - LSH) bits. + * - (NOM % DEN) fits in (32 - LSH) bits. + */ +#define SH_DIV(NOM,DEN,LSH) ( ((NOM / DEN) << LSH) \ + + (((NOM % DEN) << LSH) + DEN / 2) / DEN) + +/* TICK_NSEC is the time between ticks in nsec assuming real ACTHZ */ +#define TICK_NSEC (SH_DIV (1000000UL * 1000, (HZ<<8), 8)) + +/* + * The 64-bit value is not volatile - you MUST NOT read it + * without sampling the sequence number in xtime_lock. + */ +extern u64 jiffies_64; +extern struct timespec xtime __attribute__ ((aligned (16))); +#define jiffies (*((unsigned long *)(((unsigned long)(&jiffies_64))+4))) + +/* + * These inlines deal with timer wrapping correctly. You are + * strongly encouraged to use them + * 1. Because people otherwise forget + * 2. Because if the timer wrap changes in future you won't have to + * alter your driver code. + * + * time_after(a,b) returns true if the time a is after time b. + * + * Do this with "<0" and ">=0" to only test the sign of the result. A + * good compiler would generate better code (and a really good compiler + * wouldn't care). Gcc is currently neither. + */ +#define time_after(a,b) \ + (typecheck(unsigned long, a) && \ + typecheck(unsigned long, b) && \ + ((long)(b) - (long)(a) < 0)) +#define time_before(a,b) time_after(b,a) + +#define time_after_eq(a,b) \ + (typecheck(unsigned long, a) && \ + typecheck(unsigned long, b) && \ + ((long)(a) - (long)(b) >= 0)) +#define time_before_eq(a,b) time_after_eq(b,a) + +/* + * Have the 32 bit jiffies value wrap 5 minutes after boot + * so jiffies wrap bugs show up earlier. + */ +#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ)) + +static inline void +set_normalized_timespec (struct timespec *ts, time_t sec, long nsec) +{ + while (nsec > NSEC_PER_SEC) + { + nsec -= NSEC_PER_SEC; + ++sec; + } + while (nsec < 0) + { + nsec += NSEC_PER_SEC; + --sec; + } + ts->tv_sec = sec; + ts->tv_nsec = nsec; +} + +#endif diff --git a/libgloss/sparc_leon/asm-leon/lambapp.h b/libgloss/sparc_leon/asm-leon/lambapp.h new file mode 100644 index 000000000..ed406f1ea --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/lambapp.h @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef _LAMBAPP_H +#define _LAMBAPP_H + + +/* Include VENDOR and DEVICE definitions */ +#include "lambapp_devs.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + struct ambapp_dev_hdr; + struct ambapp_apb_info; + struct ambapp_ahb_info; + + struct ambapp_dev_hdr + { + struct ambapp_dev_hdr *next; /* Next */ + struct ambapp_dev_hdr *prev; /* Previous Device. If (this == prev->child) prev is bus bridge */ + struct ambapp_dev_hdr *children; /* Points to first device on sub-bus */ + void *owner; /* Owner of this AMBA device */ + unsigned char dev_type; /* AHB MST, AHB SLV or APB SLV */ + unsigned char vendor; /* Vendor ID */ + unsigned short device; /* Device ID */ + void *devinfo; /* Device info (APB or AHB depending on type) */ + }; + +#define AMBAPP_FLAG_FFACT_DIR 0x100 /* Frequency factor direction, 0=down, 1=up */ +#define AMBAPP_FLAG_FFACT 0x0f0 /* Frequency factor against top bus */ +#define AMBAPP_FLAG_MBUS 0x00c +#define AMBAPP_FLAG_SBUS 0x003 + + struct ambapp_apb_info + { + /* COMMON */ + unsigned char irq; + unsigned char ver; + + /* APB SPECIFIC */ + unsigned int start; + unsigned int mask; + }; + + struct ambapp_ahb_info + { + /* COMMON */ + unsigned char irq; + unsigned char ver; + + /* AHB SPECIFIC */ + unsigned int start[4]; + unsigned int mask[4]; + char type[4]; /* type[N] Determine type of start[N]-mask[N], 2=AHB Memory Space, 3=AHB I/O Space */ + unsigned int custom[3]; + }; + +/* Describes a complete AMBA Core. Each device may consist of 3 interfaces */ + struct ambapp_dev_info + { + char irq; /* irq=-1 indicate no IRQ */ + unsigned char vendor; + unsigned short device; + int index; /* Core index if multiple "subcores" in one */ + struct ambapp_ahb_info *ahb_mst; + struct ambapp_ahb_info *ahb_slv; + struct ambapp_apb_info *apb_slv; + }; + + struct ambapp_mmap + { + unsigned int size; + unsigned int local_adr; + unsigned int remote_adr; + }; + +/* Complete AMBA PnP information */ + struct ambapp_bus + { + struct ambapp_mmap *mmaps; + struct ambapp_dev_hdr *root; + }; + +/* + * Return values + * 0 - continue + * 1 - stop scanning + */ + typedef int (*ambapp_func_t) (struct ambapp_dev_hdr * dev, int index, + int maxdepth, void *arg); + +#define DEV_IS_FREE(dev) (dev->owner == NULL) +#define DEV_IS_ALLOCATED(dev) (dev->owner != NULL) + +/* Options to ambapp_for_each */ +#define OPTIONS_AHB_MSTS 0x00000001 +#define OPTIONS_AHB_SLVS 0x00000002 +#define OPTIONS_APB_SLVS 0x00000004 +#define OPTIONS_ALL_DEVS (OPTIONS_AHB_MSTS|OPTIONS_AHB_SLVS|OPTIONS_APB_SLVS) + +#define OPTIONS_FREE 0x00000010 +#define OPTIONS_ALLOCATED 0x00000020 +#define OPTIONS_ALL (OPTIONS_FREE|OPTIONS_ALLOCATED) + +/* Depth first search, Defualt is breth first search. */ +#define OPTIONS_DEPTH_FIRST 0x00000100 + +#define DEV_AHB_NONE 0 +#define DEV_AHB_MST 1 +#define DEV_AHB_SLV 2 +#define DEV_APB_SLV 3 + +/* Structures used to access Plug&Play information directly */ + struct ambapp_pnp_ahb + { + const unsigned int id; /* VENDOR, DEVICE, VER, IRQ, */ + const unsigned int custom[3]; + const unsigned int mbar[4]; /* MASK, ADDRESS, TYPE, CACHABLE/PREFETCHABLE */ + }; + + struct ambapp_pnp_apb + { + const unsigned int id; /* VENDOR, DEVICE, VER, IRQ, */ + const unsigned int iobar; /* MASK, ADDRESS, TYPE, CACHABLE/PREFETCHABLE */ + }; + +#define ambapp_pnp_vendor(id) (((id) >> 24) & 0xff) +#define ambapp_pnp_device(id) (((id) >> 12) & 0xfff) +#define ambapp_pnp_ver(id) (((id)>>5) & 0x1f) +#define ambapp_pnp_irq(id) ((id) & 0x1f) + +#define ambapp_pnp_start(mbar) (((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16)) +#define ambapp_pnp_mbar_mask(mbar) (((mbar)>>4) & 0xfff) +#define ambapp_pnp_mbar_type(mbar) ((mbar) & 0xf) + +#define ambapp_pnp_apb_start(iobar, base) ((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4)) ) +#define ambapp_pnp_apb_mask(iobar) ((~(ambapp_pnp_mbar_mask(iobar)<<8) & 0x000fffff) + 1) + +#define AMBA_TYPE_AHBIO_ADDR(addr,base_ioarea) ((unsigned int)(base_ioarea) | ((addr) >> 12)) + +#define AMBA_TYPE_APBIO 0x1 +#define AMBA_TYPE_MEM 0x2 +#define AMBA_TYPE_AHBIO 0x3 + + extern int find_apbslv (int vendor, int device, + struct ambapp_apb_info *dev); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libgloss/sparc_leon/asm-leon/lambapp_devs.h b/libgloss/sparc_leon/asm-leon/lambapp_devs.h new file mode 100644 index 000000000..eda7d422e --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/lambapp_devs.h @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef __AMBAPP_DEVS_H__ +#define __AMBAPP_DEVS_H__ + +/* 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_MOVIDIA 20 +#define VENDOR_ORBITA 23 +#define VENDOR_SYNOPSYS 33 +#define VENDOR_NASA 34 +#define VENDOR_ACTEL 172 +#define VENDOR_CAL 202 +#define VENDOR_EMBEDDIT 234 +#define VENDOR_CETON 203 + +/* Gaisler Research device id's */ +#define GAISLER_LEON2DSU 0x002 +#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_SSRCTRL 0x00a +#define GAISLER_APBUART 0x00c +#define GAISLER_IRQMP 0x00d +#define GAISLER_AHBRAM 0x00e +#define GAISLER_AHBDPRAM 0x00f +#define GAISLER_GPTIMER 0x011 +#define GAISLER_PCITRG 0x012 +#define GAISLER_PCISBRG 0x013 +#define GAISLER_PCIFBRG 0x014 +#define GAISLER_PCITRACE 0x015 +#define GAISLER_DMACTRL 0x016 +#define GAISLER_AHBTRACE 0x017 +#define GAISLER_DSUCTRL 0x018 +#define GAISLER_CANAHB 0x019 +#define GAISLER_GPIO 0x01a +#define GAISLER_AHBROM 0x01b +#define GAISLER_AHBJTAG 0x01c +#define GAISLER_ETHMAC 0x01d +#define GAISLER_SWNODE 0x01e +#define GAISLER_SPW 0x01f +#define GAISLER_AHB2AHB 0x020 +#define GAISLER_USBDC 0x021 +#define GAISLER_USB_DCL 0x022 +#define GAISLER_DDRMP 0x023 +#define GAISLER_ATACTRL 0x024 +#define GAISLER_DDRSP 0x025 +#define GAISLER_EHCI 0x026 +#define GAISLER_UHCI 0x027 +#define GAISLER_I2CMST 0x028 +#define GAISLER_SPW2 0x029 +#define GAISLER_AHBDMA 0x02a +#define GAISLER_NUHOSP3 0x02b +#define GAISLER_CLKGATE 0x02c +#define GAISLER_SPICTRL 0x02d +#define GAISLER_DDR2SP 0x02e +#define GAISLER_SLINK 0x02f +#define GAISLER_GRTM 0x030 +#define GAISLER_GRTC 0x031 +#define GAISLER_GRPW 0x032 +#define GAISLER_GRCTM 0x033 +#define GAISLER_GRHCAN 0x034 +#define GAISLER_GRFIFO 0x035 +#define GAISLER_GRADCDAC 0x036 +#define GAISLER_GRPULSE 0x037 +#define GAISLER_GRTIMER 0x038 +#define GAISLER_AHB2PP 0x039 +#define GAISLER_GRVERSION 0x03a +#define GAISLER_APB2PW 0x03b +#define GAISLER_PW2APB 0x03c +#define GAISLER_GRCAN 0x03d +#define GAISLER_I2CSLV 0x03e +#define GAISLER_U16550 0x03f +#define GAISLER_AHBMST_EM 0x040 +#define GAISLER_AHBSLV_EM 0x041 +#define GAISLER_GRTESTMOD 0x042 +#define GAISLER_ASCS 0x043 +#define GAISLER_IPMVBCTRL 0x044 +#define GAISLER_SPIMCTRL 0x045 +#define GAISLER_LEON4 0x048 +#define GAISLER_LEON4DSU 0x049 +#define GAISLER_GRPWM 0x04A +#define GAISLER_FTAHBRAM 0x050 +#define GAISLER_FTSRCTRL 0x051 +#define GAISLER_AHBSTAT 0x052 +#define GAISLER_LEON3FT 0x053 +#define GAISLER_FTMCTRL 0x054 +#define GAISLER_FTSDCTRL 0x055 +#define GAISLER_FTSRCTRL8 0x056 +#define GAISLER_APBPS2 0x060 +#define GAISLER_VGACTRL 0x061 +#define GAISLER_LOGAN 0x062 +#define GAISLER_SVGACTRL 0x063 +#define GAISLER_T1AHB 0x064 +#define GAISLER_MP7WRAP 0x065 +#define GAISLER_GRSYSMON 0x066 +#define GAISLER_GRACECTRL 0x067 +#define GAISLER_B1553BC 0x070 +#define GAISLER_B1553RT 0x071 +#define GAISLER_B1553BRM 0x072 +#define GAISLER_SATCAN 0x080 +#define GAISLER_CANMUX 0x081 +#define GAISLER_GRTMRX 0x082 +#define GAISLER_GRTCTX 0x083 +#define GAISLER_GRTMDESC 0x084 +#define GAISLER_GRTMVC 0x085 +#define GAISLER_GEFFE 0x086 +#define GAISLER_AES 0x073 +#define GAISLER_ECC 0x074 +#define GAISLER_PCIF 0x075 +#define GAISLER_CLKMOD 0x076 +#define GAISLER_HAPSTRAK 0x077 +#define GAISLER_TEST_1X2 0x078 +#define GAISLER_WILD2AHB 0x079 +#define GAISLER_BIO1 0x07a + +#define GAISLER_PIPEWRAPPER 0xffa +#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 0x002 +#define ESA_LEON2APB 0x003 +#define ESA_IRQ 0x005 +#define ESA_TIMER 0x006 +#define ESA_UART 0x007 +#define ESA_CFG 0x008 +#define ESA_IO 0x009 +#define ESA_MCTRL 0x00f +#define ESA_PCIARB 0x010 +#define ESA_HURRICANE 0x011 +#define ESA_SPW_RMAP 0x012 +#define ESA_SPW2 0x012 +#define ESA_AHBUART 0x013 +#define ESA_SPWA 0x014 +#define ESA_BOSCHCAN 0x015 +#define ESA_IRQ2 0x016 +#define ESA_AHBSTAT 0x017 +#define ESA_WPROT 0x018 +#define ESA_WPROT2 0x019 +#define ESA_PDEC3AMBA 0x020 +#define ESA_PTME3AMBA 0x021 + +#define OPENCHIP_APBGPIO 0x001 +#define OPENCHIP_APBI2C 0x002 +#define OPENCHIP_APBSPI 0x003 +#define OPENCHIP_APBCHARLCD 0x004 +#define OPENCHIP_APBPWM 0x005 +#define OPENCHIP_APBPS2 0x006 +#define OPENCHIP_APBMMCSD 0x007 +#define OPENCHIP_APBNAND 0x008 +#define OPENCHIP_APBLPC 0x009 +#define OPENCHIP_APBCF 0x00a +#define OPENCHIP_APBSYSACE 0x00b +#define OPENCHIP_APB1WIRE 0x00c +#define OPENCHIP_APBJTAG 0x00d +#define OPENCHIP_APBSUI 0x00e + + +#define CONTRIB_CORE1 0x001 +#define CONTRIB_CORE2 0x002 + +#define GLEICHMANN_CUSTOM 0x001 +#define GLEICHMANN_GEOLCD01 0x002 +#define GLEICHMANN_DAC 0x003 +#define GLEICHMANN_HPI 0x004 +#define GLEICHMANN_SPI 0x005 +#define GLEICHMANN_HIFC 0x006 +#define GLEICHMANN_ADCDAC 0x007 +#define GLEICHMANN_SPIOC 0x008 +#define GLEICHMANN_AC97 0x009 + +#define SUN_T1 0x001 +#define SUN_S1 0x011 + +#define ORBITA_1553B 0x001 +#define ORBITA_429 0x002 +#define ORBITA_SPI 0x003 +#define ORBITA_I2C 0x004 +#define ORBITA_SMARTCARD 0x064 +#define ORBITA_SDCARD 0x065 +#define ORBITA_UART16550 0x066 +#define ORBITA_CRYPTO 0x067 +#define ORBITA_SYSIF 0x068 +#define ORBITA_PIO 0x069 +#define ORBITA_RTC 0x0c8 +#define ORBITA_COLORLCD 0x12c +#define ORBITA_PCI 0x190 +#define ORBITA_DSP 0x1f4 +#define ORBITA_USBHOST 0x258 +#define ORBITA_USBDEV 0x2bc + +#define NASA_EP32 0x001 + +#define CAL_DDRCTRL 0x188 + +#define ACTEL_COREMP7 0x001 + +/* Opencores device id's */ +#define OPENCORES_PCIBR 0x4 +#define OPENCORES_ETHMAC 0x5 + +#endif diff --git a/libgloss/sparc_leon/asm-leon/leon.h b/libgloss/sparc_leon/asm-leon/leon.h new file mode 100644 index 000000000..8c13a1bb8 --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/leon.h @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef _INCLUDE_LEON_h +#define _INCLUDE_LEON_h + +#include <asm-leon/leon3.h> +#include <asm-leon/amba.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* psr defines */ +#define SPARC_PSR_WIN_MASK 0x0000001f /* bit 0-4 */ +#define SPARC_PSR_ET_MASK 0x00000020 /* bit 5 */ +#define SPARC_PSR_PS_MASK 0x00000040 /* bit 6 */ +#define SPARC_PSR_S_MASK 0x00000080 /* bit 7 */ +#define SPARC_PSR_PIL_MASK 0x00000F00 /* bits 8 - 11 */ +#define SPARC_PSR_EF_MASK 0x00001000 /* bit 12 */ +#define SPARC_PSR_EC_MASK 0x00002000 /* bit 13 */ +#define SPARC_PSR_ICC_MASK 0x00F00000 /* bits 20 - 23 */ +#define SPARC_PSR_VER_MASK 0x0F000000 /* bits 24 - 27 */ +#define SPARC_PSR_IMPL_MASK 0xF0000000 /* bits 28 - 31 */ +#define SPARC_PSR_PIL_SHIFT 8 + +#define SPARC_NUM_REGWIN _nwindows + +#ifndef __ASSEMBLER__ + extern int _nwindows; + extern int _leon_version; +#endif + +#define LEON_VERSION _leon_version + +/* + * Interrupt Sources + * + * The interrupt source numbers directly map to the trap type and to + * the bits used in the Interrupt Clear, Interrupt Force, Interrupt Mask, + * and the Interrupt Pending Registers. + */ + +#define LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR 1 +#define LEON2_INTERRUPT_UART_2_RX_TX 2 +#define LEON2_INTERRUPT_UART_1_RX_TX 3 +#define LEON23_INTERRUPT_UART_2_RX_TX leon23_irqs[1] /*console.c */ +#define LEON23_INTERRUPT_UART_1_RX_TX leon23_irqs[0] /*console.c */ +#define LEON_INTERRUPT_EXTERNAL_0 4 +#define LEON_INTERRUPT_EXTERNAL_1 5 +#define LEON_INTERRUPT_EXTERNAL_2 6 +#define LEON_INTERRUPT_EXTERNAL_3 7 +#define LEON2_INTERRUPT_TIMER1 8 +#define LEON2_INTERRUPT_TIMER2 9 +#define LEON23_INTERRUPT_TIMER1 leon23_timerirqs[0] /* timer.c */ +#define LEON23_INTERRUPT_TIMER2 leon23_timerirqs[1] /* timer.c */ +#define LEON_INTERRUPT_EMPTY1 10 +#define LEON_INTERRUPT_EMPTY2 11 +#define LEON_INTERRUPT_EMPTY3 12 +#define LEON_INTERRUPT_EMPTY4 13 +#define LEON_INTERRUPT_EMPTY5 14 +#define LEON_INTERRUPT_EMPTY6 15 + +#ifndef __ASSEMBLER__ + +/* + * Trap Types for on-chip peripherals + * + * Source: Table 8 - Interrupt Trap Type and Default Priority Assignments + * + * NOTE: The priority level for each source corresponds to the least + * significant nibble of the trap type. + */ + +#define LEON_TRAP_TYPE( _source ) SPARC_ASYNCHRONOUS_TRAP((_source) + 0x10) + +#define LEON_TRAP_SOURCE( _trap ) ((_trap) - 0x10) + +#define LEON_INT_TRAP( _trap ) \ + ( (_trap) >= LEON_TRAP_TYPE( LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR ) && \ + (_trap) <= LEON_TRAP_TYPE( LEON_INTERRUPT_EMPTY6 ) ) + + +#endif + + +/* + * The following defines the bits in Memory Configuration Register 1. + */ + +#define LEON_MEMORY_CONFIGURATION_PROM_SIZE_MASK 0x0003C000 + +/* + * The following defines the bits in Memory Configuration Register 1. + */ + +#define LEON_MEMORY_CONFIGURATION_RAM_SIZE_MASK 0x00001E00 + + +/* + * The following defines the bits in the Timer Control Register. + */ + +#define LEON_REG_TIMER_CONTROL_EN 0x00000001 /* 1 = enable counting */ + /* 0 = hold scalar and counter */ +#define LEON_REG_TIMER_CONTROL_RL 0x00000002 /* 1 = reload at 0 */ + /* 0 = stop at 0 */ +#define LEON_REG_TIMER_CONTROL_LD 0x00000004 /* 1 = load counter */ + /* 0 = no function */ + +/* + * The following defines the bits in the UART Control Registers. + * + */ + +#define LEON_REG_UART_CONTROL_RTD 0x000000FF /* RX/TX data */ + +/* + * 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 Status 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 */ + +/* leon2 asis */ +#define ASI_LEON2_IFLUSH 0x05 +#define ASI_LEON2_DFLUSH 0x06 +#define ASI_LEON2_CACHEMISS 1 + +/* leon3 asis */ +#define ASI_LEON3_IFLUSH 0x10 +#define ASI_LEON3_DFLUSH 0x11 +#define ASI_LEON3_CACHEMISS 1 +#define ASI_LEON3_SYSCTRL 0x02 + +#define ASI_LEON23_ITAG 0x0c +#define ASI_LEON23_DTAG 0x0e + + +#ifndef __ASSEMBLER__ + + unsigned int leonbare_leon23_loadnocache (unsigned int addr); + unsigned int leonbare_leon23_loadnocache16 (unsigned int addr); + unsigned int leonbare_leon23_loadnocache8 (unsigned int addr); + unsigned int leonbare_leon23_storenocache (unsigned int addr, + unsigned int value); + unsigned int leonbare_leon23_storenocache16 (unsigned int addr, + unsigned int value); + unsigned int leonbare_leon23_storenocache8 (unsigned int addr, + unsigned int value); + + unsigned int leonbare_leon3_loadnocache (unsigned int addr); + unsigned int leonbare_leon3_loadnocache16 (unsigned int addr); + unsigned int leonbare_leon3_loadnocache8 (unsigned int addr); + + +/* + * This is used to manipulate the on-chip registers. + * + * The following symbol must be defined in the linkcmds file and point + * to the correct location. + */ + + extern unsigned long *LEON23_IRQ_mask_addr; /* in peripherals.h */ + extern unsigned long *LEON23_IRQ_force_addr; /* in peripherals.h */ + extern unsigned long *LEON23_IRQ_pending_addr; /* in peripherals.h */ + extern unsigned long *LEON23_IRQ_clear_addr; /* in peripherals.h */ + +/* + * Macros to manipulate the Interrupt Clear, Interrupt Force, Interrupt Mask, + * and the Interrupt Pending Registers. + * + * NOTE: For operations which are not atomic, this code disables interrupts + * to guarantee there are no intervening accesses to the same register. + * The operations which read the register, modify the value and then + * store the result back are vulnerable. + */ + +#define LEON_Clear_interrupt( _source ) \ + do { \ + (*LEON23_IRQ_clear_addr) = (1 << (_source)); \ + } while (0) + +#define LEON_Force_interrupt( _source ) \ + do { \ + (*LEON23_IRQ_force_addr) = (1 << (_source)); \ + } while (0) + +#define LEON_Is_interrupt_masked( _source ) \ + ((*LEON23_IRQ_mask_addr) & (1 << (_source))) + +#define LEON_Mask_interrupt( _source ) \ + do { \ + unsigned32 _level; \ + \ + _level = sparc_disable_interrupts(); \ + (*LEON23_IRQ_mask_addr) &= ~(1 << (_source)); \ + sparc_enable_interrupts( _level ); \ + } while (0) + +#define LEON_Unmask_interrupt( _source ) \ + do { \ + unsigned32 _level; \ + \ + _level = sparc_disable_interrupts(); \ + (*LEON23_IRQ_mask_addr) |= (1 << (_source)); \ + sparc_enable_interrupts( _level ); \ + } while (0) + +#define LEON_Disable_interrupt( _source, _previous ) \ + do { \ + unsigned32 _level; \ + unsigned32 _mask = 1 << (_source); \ + \ + _level = sparc_disable_interrupts(); \ + (_previous) = (*LEON23_IRQ_mask_addr); \ + (*LEON23_IRQ_mask_addr) = _previous & ~_mask; \ + sparc_enable_interrupts( _level ); \ + (_previous) &= _mask; \ + } while (0) + +#define LEON_Restore_interrupt( _source, _previous ) \ + do { \ + unsigned32 _level; \ + unsigned32 _mask = 1 << (_source); \ + \ + _level = sparc_disable_interrupts(); \ + (*LEON23_IRQ_mask_addr) = \ + ((*LEON23_IRQ_mask_addr) & ~_mask) | (_previous); \ + sparc_enable_interrupts( _level ); \ + } while (0) + +/* + * Each timer control register is organized as follows: + * + * D0 - Enable + * 1 = enable counting + * 0 = hold scaler and counter + * + * D1 - Counter Reload + * 1 = reload counter at zero and restart + * 0 = stop counter at zero + * + * D2 - Counter Load + * 1 = load counter with preset value + * 0 = no function + * + */ + +#define LEON_REG_TIMER_COUNTER_IRQEN 0x00000008 + +#define LEON_REG_TIMER_COUNTER_RELOAD_AT_ZERO 0x00000002 +#define LEON_REG_TIMER_COUNTER_STOP_AT_ZERO 0x00000000 + +#define LEON_REG_TIMER_COUNTER_LOAD_COUNTER 0x00000004 + +#define LEON_REG_TIMER_COUNTER_ENABLE_COUNTING 0x00000001 +#define LEON_REG_TIMER_COUNTER_DISABLE_COUNTING 0x00000000 + +#define LEON_REG_TIMER_COUNTER_RELOAD_MASK 0x00000002 +#define LEON_REG_TIMER_COUNTER_ENABLE_MASK 0x00000001 + +#define LEON_REG_TIMER_COUNTER_DEFINED_MASK 0x00000003 +#define LEON_REG_TIMER_COUNTER_CURRENT_MODE_MASK 0x00000003 + +/* console.c */ + int lo_sprintf (char *buf, const char *fmt, ...); + +/* do a virtual address read without cache */ + static __inline__ unsigned long leon23_getpsr () + { + unsigned long retval; + __asm__ __volatile__ ("mov %%psr, %0\n\t":"=r" (retval):); + return retval; + } + + extern __inline__ void sparc_leon2_dcache_flush (void) + { + __asm__ + __volatile__ ("sta %%g0, [%%g0] %0\n\t"::"i" + (ASI_LEON2_IFLUSH):"memory"); + __asm__ + __volatile__ ("sta %%g0, [%%g0] %0\n\t"::"i" + (ASI_LEON2_DFLUSH):"memory"); + }; + + + extern __inline__ void sparc_leon_dcache_flush (void) + { + switch (sparc_leon23_get_psr_version ()) + { + case 0: + case 2: + sparc_leon2_dcache_flush (); + break; + default: + sparc_leon3_dcache_flush (); + break; + } + } + + extern int lolevelirqinstall (int irqnr, void (*handler) ()); + extern unsigned long locore_readtbr (); + extern void _leonbase_Stop (); + + extern void uninstall_winoverflow_hook (); + extern int install_winoverflow_hook (void (*func) (void)); + + extern void sparc_leon23_icache_flush (); + extern void sparc_leon23_dcache_flush (); + +#endif /* ! __ASSEMBLER__ */ + +#ifdef __cplusplus +} +#endif + +#define TACODE_IRQCALL 2 +#define TACODE_IRQCALL_FLUSH 6 + +#define TACODE_FLUSH 3 +#define TACODE_IRQCALLDIS 5 + + + +#endif /* !_INCLUDE_LEON_h */ +/* end of include file */ diff --git a/libgloss/sparc_leon/asm-leon/leon3.h b/libgloss/sparc_leon/asm-leon/leon3.h new file mode 100644 index 000000000..e8b6cfee5 --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/leon3.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef _INCLUDE_LEON3_h +#define _INCLUDE_LEON3_h + +#ifndef __ASSEMBLER__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define ASI_LEON3_CACHEMISS 1 +#define ASI_LEON3_SYSCTRL 0x02 +#define ASI_LEON3_DFLUSH 0x11 + +#define ASI_LEON3_SYSCTRL_ICFG 0x08 +#define ASI_LEON3_SYSCTRL_DCFG 0x0c +#define ASI_LEON3_SYSCTRL_CFG_SNOOPING (1<<27) +#define ASI_LEON3_SYSCTRL_CFG_SSIZE(c) (1<<((c>>20)&0xf)) + + + extern __inline__ unsigned long sparc_leon23_get_psr (void) + { + unsigned int retval; + __asm__ __volatile__ ("rd %%psr, %0\n\t":"=r" (retval):); + return (retval); + } + + extern __inline__ unsigned long sparc_leon23_get_psr_version (void) + { + unsigned int psr = sparc_leon23_get_psr (); + return (psr >> 24) & 0xf; + } +#define LEON_ISLEON2 (sparc_leon23_get_psr_version() == 2 || sparc_leon23_get_psr_version() == 0) +#define LEON_ISLEON3 (sparc_leon23_get_psr_version() == 3) + + extern __inline__ unsigned long sparc_leon3_get_dcachecfg (void) + { + unsigned int retval; + __asm__ + __volatile__ ("lda [%1] %2, %0\n\t":"=r" (retval):"r" + (ASI_LEON3_SYSCTRL_DCFG), "i" (ASI_LEON3_SYSCTRL)); + return (retval); + } + + extern __inline__ void sparc_leon3_enable_snooping (void) + { + /*enable snooping */ + __asm__ volatile ("lda [%%g0] 2, %%l1\n\t" + "set 0x800000, %%l2\n\t" + "or %%l2, %%l1, %%l2\n\t" + "sta %%l2, [%%g0] 2\n\t":::"l1", "l2"); + }; + + extern __inline__ void sparc_leon3_disable_cache (void) + { + /*asi 2 */ + __asm__ volatile ("lda [%%g0] 2, %%l1\n\t" + "set 0x00000f, %%l2\n\t" + "andn %%l2, %%l1, %%l2\n\t" + "sta %%l2, [%%g0] 2\n\t":::"l1", "l2"); + }; + + + + extern __inline__ void sparc_leon3_dcache_flush (void) + { + __asm__ __volatile__ (" flush "); //iflush + __asm__ + __volatile__ ("sta %%g0, [%%g0] %0\n\t"::"i" + (ASI_LEON3_DFLUSH):"memory"); + }; + + +#ifdef __cplusplus +} +#endif + +#endif /* !ASM */ + + +#endif /* !_INCLUDE_LEON3_h */ +/* end of include file */ diff --git a/libgloss/sparc_leon/asm-leon/leonbare_debug.h b/libgloss/sparc_leon/asm-leon/leonbare_debug.h new file mode 100644 index 000000000..ca9362f0e --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/leonbare_debug.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef __LEONBARE_KERNEL_DEBUG_H__ +#define __LEONBARE_KERNEL_DEBUG_H__ + +#include <asm-leon/leondbg.h> + +/* + #define LBDEBUG_DO_DEBUG + #define LBDEBUG_DO_ASSERT +*/ + +#define LBDEBUG_ALWAYS_NR (1<<0) +#define LBDEBUG_ASSERT_NR (1<<1) +#define LBDEBUG_FNCALL_NR (1<<2) +#define LBDEBUG_FNEXIT_NR (1<<3) +#define LBDEBUG_SCHED_NR (1<<4) +#define LBDEBUG_QUEUE_NR (1<<5) +#define LBDEBUG_THREAD_NR (1<<6) + +#define LBDEBUG_PRINTF dbgleon_printf /*leonbare_debug_printf */ + +#ifdef LBDEBUG_DO_DEBUG +#ifndef __ASSEMBLER__ +extern int leonbare_debug; +#endif +# define PDEBUG_FLAGS_CHECK(c) ((c)&leonbare_debug) +# define PDEBUG_FLAGS_SET(c) leonbare_debug |= c +#else +# define PDEBUG_FLAGS_CHECK(c) 0 +# define PDEBUG_FLAGS_SET(c) +#endif + +#ifdef LBDEBUG_DO_DEBUG +# define LBDEBUG(x, fmt, args...) do { if (PDEBUG_FLAGS_CHECK(x)) { LBDEBUG_PRINTF(fmt,args); } } while(0) +#else +# define LBDEBUG(x, fmt, args...) +#endif + +#ifdef LBDEBUG_DO_ASSERT +# define LBPASSERT(x, fmt, args...) if (!(x)) { LBDEBUG_PRINTF(fmt,args); while(1); } +#else +# define LBPASSERT(x, fmt, args...) +#endif + +#ifndef LBDEBUG___FUNCTION__ +#define LBDEBUG___FUNCTION__ __FUNCTION__ +#endif + +#ifndef LBDEBUG___FUNCTION_WIDTH__ +#define LBDEBUG___FUNCTION_WIDTH__ "28" +#endif + +#ifdef LBDEBUG_DO_FILE +#ifndef LBDEBUG___FILE__ +#define LBDEBUG___FILE__ __FILE__ +#endif +#ifndef LBDEBUG___FILE_WIDTH__ +#define LBDEBUG___FILE_WIDTH__ "28" +#endif +#define LBDEBUG___FILE_APPEND ,__FILE__ +#define LBDEBUG___FILE_FMT_APPEND ":%" LBDEBUG___FILE_WIDTH__ "s" +#else +#define LBDEBUG___FILE_APPEND +#define LBDEBUG___FILE_FMT_APPEND +#endif + +#ifdef LBDEBUG_DO_DEBUG +# define LBDEBUG_HEADER(code) \ + if (PDEBUG_FLAGS_CHECK(code)) { \ + register unsigned int _GETSP asm("sp"); \ + LBDEBUG_PRINTF("[sp:%08x self(%08x):", _GETSP, LEONBARE_KR_CURRENT); \ + LBDEBUG_PRINTF("%10s",LEONBARE_TH_NAME_DBG(LEONBARE_KR_CURRENT)); \ + LBDEBUG_PRINTF(" %03d @ %" LBDEBUG___FUNCTION_WIDTH__ "s()" LBDEBUG___FILE_FMT_APPEND "]:" , __LINE__,LBDEBUG___FUNCTION__ LBDEBUG___FILE_APPEND); \ + } + +# define LBDEBUG_HEADER_PRINTF(code,fmt,args...) \ + if (PDEBUG_FLAGS_CHECK(code)) { \ + LBDEBUG_HEADER(code); \ + LBDEBUG_PRINTF(fmt,args); \ + } + +# define LBDEBUG_CODE_PRINTF(code,fmt,args...) \ + if (PDEBUG_FLAGS_CHECK(code)) { \ + LBDEBUG_PRINTF(fmt,args); \ + } +#else +# define LBDEBUG_HEADER(code) +# define LBDEBUG_HEADER_PRINTF(code,fmt,args...) +# define LBDEBUG_CODE_PRINTF(code,fmt,args...) +#endif + +#define LBDEBUG_FNCALL LBDEBUG_HEADER_PRINTF(LBDEBUG_FNCALL_NR,"enter\n",0) +#define LBDEBUG_FNEXIT LBDEBUG_HEADER_PRINTF(LBDEBUG_FNEXIT_NR,"exit\n",0) + +#ifndef __ASSEMBLER__ + +int leonbare_debug_printf (const char *fmt, ...); + +#endif + +#endif diff --git a/libgloss/sparc_leon/asm-leon/leonbare_kernel.h b/libgloss/sparc_leon/asm-leon/leonbare_kernel.h new file mode 100644 index 000000000..0924d4723 --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/leonbare_kernel.h @@ -0,0 +1,438 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef __LEONBARE_KERNEL_H__ +#define __LEONBARE_KERNEL_H__ + +#include <asm-leon/contextswitch.h> +#include <asm-leon/leonbare_debug.h> +#include <asm-leon/leon.h> +#ifndef __ASSEMBLER__ +#include <asm-leon/leonbare_kernel_queue.h> +#include <reent.h> +#endif +#include "irq.h" + +#define LEONBARE_RUNQ_READY_NR (2) /* queue 0-1 for ready */ +#define LEONBARE_RUNQ_SUSPENDED_IDX (2) /* queue 2 for suspended */ +#define LEONBARE_RUNQ_PREPARE_IDX (3) /* LEONBARE_RUNQ_READY_NR times queues */ +#define LEONBARE_RUNQ_KILLED_IDX (LEONBARE_RUNQ_PREPARE_IDX+LEONBARE_RUNQ_READY_NR) /* queue 2 for killed threads */ +#define LEONBARE_RUNQ_NR (LEONBARE_RUNQ_KILLED_IDX+1) + +#define LEONBARE_RUNQ_ISREADY(idx) ((idx) >= 0 && (idx) < LEONBARE_RUNQ_READY_NR) +#define LEONBARE_RUNQ_ISPREPARE(idx) ((idx) >= LEONBARE_RUNQ_PREPARE_IDX && (idx) < LEONBARE_RUNQ_PREPARE_IDX+LEONBARE_RUNQ_READY_NR) +#define LEONBARE_RUNQ_ISSUSPEND(idx) ((idx) == LEONBARE_RUNQ_SUSPENDED_IDX) +#define LEONBARE_RUNQ_ISKILLED(idx) ((idx) == LEONBARE_RUNQ_KILLED_IDX) + +#ifndef __ASSEMBLER__ + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#define MACRO_BEGIN do { +#define MACRO_END } while (0) + +#define optbarrier() __asm__ __volatile__("": : :"memory") + +typedef struct leonbare_thread_ctx +{ + unsigned long sf_locals[8]; + unsigned long sf_ins[8]; + unsigned long outs[8]; + unsigned long globals[8]; + unsigned long psr; + unsigned long wim; + unsigned long magic; + unsigned long fpu; + /* size aligned to 8 */ +} leonbare_thread_ctx_t; +#define LEONBARE_THREAD_CTX_SZ sizeof(struct leonbare_thread_ctx) + +typedef +LBTAILQ_HEAD (leonbare_mutex_queue, leonbare_mutex) * + leonbare_mutex_queue_t; + +#endif +#define LEONBARE_THREAD_OFFSET_CTX 0 +#ifndef __ASSEMBLER__ + + struct leonbare_thread_protect + { + unsigned int runq; + unsigned int krp_runq_depth; + unsigned int krp_k_depth; + struct leonbare_mutex *krp_m; + unsigned int krp_m_depth; + unsigned int krp_flags;; + unsigned int krp_flags_depth; + }; + +#define LEONBARE_INT_DISABLE_DECL unsigned long _irq_flags = leonbare_disable_traps(); +#define LEONBARE_INT_ENABLE_DECL leonbare_enable_traps(_irq_flags); + +#define leonbare_setu32p(a,v) leonbare_leon23_storenocache(a,v) +#define leonbare_setu32(a,v) leonbare_leon23_storenocache(a,v) +#define leonbare_getu32(a) leonbare_leon23_loadnocache(a) + +#define LEONBARE_KERNEL_UNCACHED +#ifndef LEONBARE_KERNEL_UNCACHED +#define LEONBARE_KERNEL_SETU32P(a,v) (a=v) +#define LEONBARE_KERNEL_SETU32(a,v) (a=v) /* uncached version should return v */ +#define LEONBARE_KERNEL_GETU32(a) (a) +#define LEONBARE_KERNEL_GETU32P(a) (a) +#define LEONBARE_KERNEL_GETI32(a) (a) +#define LEONBARE_KERNEL_GETU32P_CAST(a,typ) ((typ)(a)) +#define LEONBARE_KERNEL_GETU32P_BARE(a) (*(a)) /* uncached: no & */ +#define LEONBARE_KERNEL_SETU32P_BARE(a,v) (*(a) = v) /* uncached: no & */ +#else +#define LEONBARE_KERNEL_SETU32P(a,v) (leonbare_setu32p(&a,v)) +#define LEONBARE_KERNEL_SETU32(a,v) (leonbare_setu32p(&a,v)) /* uncached version should return v */ +#define LEONBARE_KERNEL_GETU32(a) (leonbare_getu32(&a)) +#define LEONBARE_KERNEL_GETU32P(a) ((void *)leonbare_getu32(&a)) +#define LEONBARE_KERNEL_GETI32(a) (leonbare_getu32(&a)) +#define LEONBARE_KERNEL_GETU32P_CAST(a,typ) ((typ)(LEONBARE_KERNEL_GETU32P(a))) +#define LEONBARE_KERNEL_GETU32P_BARE(a) ((void *)leonbare_getu32(a)) /* uncached: no & */ +#define LEONBARE_KERNEL_SETU32P_BARE(a,v) (leonbare_setu32p(a,v)) /* uncached: no & */ +#endif + + +#define LEONBARE_SMP_SPINLOCK_AQUIRE(l) +#define LEONBARE_SMP_SPINLOCK_RELEASE(l) + +#define LEONBARE_ISQ_ISDISABLED ((leon23_getpsr() & SPARC_PSR_PIL_MASK) == SPARC_PSR_PIL_MASK) + +#define _LEONBARE_PROTECT_IRQ_START \ + if (LEONBARE_KR_CURRENT->th_prot.krp_flags_depth++) { \ + LBPASSERT((LEONBARE_ISQ_ISDISABLED),"Internal error: Recursiv IRQ protection with irq's enabled",0); \ + } else { \ + LEONBARE_KR_CURRENT->th_prot.krp_flags = leonbare_disable_traps(); \ + } + +#define _LEONBARE_PROTECT_IRQ_END \ + if (--LEONBARE_KR_CURRENT->th_prot.krp_flags_depth) { \ + LBPASSERT((LEONBARE_ISQ_ISDISABLED),"Internal error: Recursiv IRQ protection with irq's enabled",0); \ + } else { \ + leonbare_enable_traps(LEONBARE_KR_CURRENT->th_prot.krp_flags); \ + } + +#define _LEONBARE_PROTECT_MUTEXSTRUCT_START(m) \ + if (LEONBARE_KR_CURRENT->th_prot.krp_m_depth++) { \ + LBPASSERT((LEONBARE_KR_CURRENT->th_prot.krp_m == m),"Mutex protection only allowed for one mutex at a time",0); \ + } else { \ + LEONBARE_SMP_SPINLOCK_AQUIRE(m->smp_lock); \ + LEONBARE_KR_CURRENT->th_prot.krp_m = m; \ + } + +#define _LEONBARE_PROTECT_MUTEXSTRUCT_END(m) \ + LBPASSERT((LEONBARE_KR_CURRENT->th_prot.krp_m == m),"Mutex protection only allowed for one mutex at a time",0); \ + if ((--LEONBARE_KR_CURRENT->th_prot.krp_m_depth) == 0) { \ + LEONBARE_SMP_SPINLOCK_RELEASE(m->smp_lock); \ + } + +#define _LEONBARE_PROTECT_KERNEL_START \ + if (LEONBARE_KR_CURRENT->th_prot.krp_k_depth++ == 0) { \ + LEONBARE_SMP_SPINLOCK_AQUIRE(LEONBARE_KR_LOCK); \ + } + +#define _LEONBARE_PROTECT_KERNEL_END \ + if ((--LEONBARE_KR_CURRENT->th_prot.krp_k_depth) == 0) { \ + LEONBARE_SMP_SPINLOCK_RELEASE(LEONBARE_KR_LOCK); \ + } + + +#define LEONBARE_PROTECT_MUTEXSTRUCT_START(m) \ + _LEONBARE_PROTECT_IRQ_START; \ + _LEONBARE_PROTECT_MUTEXSTRUCT_START(m) + +#define LEONBARE_PROTECT_MUTEXSTRUCT_END(m) \ + _LEONBARE_PROTECT_MUTEXSTRUCT_END(m) \ + _LEONBARE_PROTECT_IRQ_END; + + +#define LEONBARE_PROTECT_KERNEL_START() \ + _LEONBARE_PROTECT_IRQ_START; \ + _LEONBARE_PROTECT_KERNEL_START; + +#define LEONBARE_PROTECT_KERNEL_END() \ + _LEONBARE_PROTECT_KERNEL_END; \ + _LEONBARE_PROTECT_IRQ_END; + + typedef struct leonbare_thread + { + struct leonbare_thread_ctx th_ctx; + unsigned int th_flags; + + int th_account; /* how many ticks the thread stays in the readyqueue for one round */ + int th_caccount; /* current value of th_account, updated on reinsertion */ + unsigned int th_pri_idx; /* ready queue index */ + unsigned int th_runq_idx; /* ready queue index index */ + unsigned int th_runq_which; /* 0: ready queue, 1: ready prepare queue */ + + char *th_name; + int th_result; + int (*th_func) (void *); + void *th_arg; + char *th_stack_base; + unsigned int th_stack_size; + struct _reent th_reent; /* reentrant structure for newlib */ + struct _reent *th_reentp; /* pointer to eather pt_reent or global reent */ + + struct leonbare_thread_protect th_prot; + + LBTAILQ_ENTRY (leonbare_thread) th_runq; + LBTAILQ_ENTRY (leonbare_thread) th_allq; + LBTAILQ_ENTRY (leonbare_thread) th_mutex; + struct leonbare_mutex_queue th_mutex_locked; + + } *leonbare_thread_t __attribute__ ((aligned (8))); + +#define LEONBARE_TH_FLAGS_get(c) LEONBARE_KERNEL_GETU32((c)->th_flags) +#define LEONBARE_TH_ACCOUNT_get(c) LEONBARE_KERNEL_GETI32((c)->th_account) +#define LEONBARE_TH_CACCOUNT_get(c) LEONBARE_KERNEL_GETI32((c)->th_caccount) + +#define LEONBARE_TH_PRI_IDX_get(c) LEONBARE_KERNEL_GETU32((c)->th_pri_idx) +#define LEONBARE_TH_RUNQ_IDX_get(c) LEONBARE_KERNEL_GETU32((c)->th_runq_idx) +#define LEONBARE_TH_RUNQ_WHICH_get(c) LEONBARE_KERNEL_GETU32((c)->th_runq_which) + +#define LEONBARE_TH_NAME_get(c) LEONBARE_KERNEL_GETU32P((c)->th_name) +#define LEONBARE_TH_RESULT_get(c) LEONBARE_KERNEL_GETI32((c)->th_result) +#define LEONBARE_TH_FUNC_get(c) LEONBARE_KERNEL_GETU32((c)->th_func) +#define LEONBARE_TH_ARG_get(c) LEONBARE_KERNEL_GETU32((c)->th_arg) +#define LEONBARE_TH_STACK_BASE_get(c) LEONBARE_KERNEL_GETU32P((c)->th_stack_base) +#define LEONBARE_TH_STACK_SIZE_get(c) LEONBARE_KERNEL_GETU32((c)->th_stack_size) +#define LEONBARE_TH_REENTP_get(c) LEONBARE_KERNEL_GETU32P((c)->th_reentp) + + + + +#define LEONBARE_TH_NAME(c) (c->th_name) +#define LEONBARE_TH_NAME_DBG(c) (LEONBARE_TH_NAME(c) ? LEONBARE_TH_NAME(c) : "<unknown>") + +#define LEONBARE_REENT_SET(p) ((_impure_ptr=(p)->th_reentp)==_impure_ptr) + +#define LEONBARE_TH_READY (1<<0) +#define LEONBARE_TH_SUSPENDED (1<<1) +#define LEONBARE_TH_TERMINATED (1<<2) +#define LEONBARE_TH_FINISHED (1<<3) + +#define LEONBARE_TH_SATEMASK (LEONBARE_TH_READY | \ + LEONBARE_TH_SUSPENDED | \ + LEONBARE_TH_TERMINATED | \ + LEONBARE_TH_FINISHED) + +#define LEONBARE_TH_SETSTATE(c,f) c->th_flags = ((c->th_flags & ~LEONBARE_TH_SATEMASK) | (f & LEONBARE_TH_SATEMASK)) +#define LEONBARE_TH_ORSTATE(c,f) c->th_flags |= (f & LEONBARE_TH_SATEMASK) + + typedef LBTAILQ_HEAD (leonbare_thread_queue, + leonbare_thread) * leonbare_thread_queue_t; + + extern struct leonbare_kernel leonbare_kernel; +#define KERNEL_GLOBAL leonbare_kernel + typedef struct leonbare_kernel + { + leonbare_thread_t kr_cur, kr_next; + struct leonbare_thread_queue kr_runq[LEONBARE_RUNQ_NR]; + struct leonbare_thread_queue kr_allq; + struct leonbare_mutex_queue kr_allm; + int kr_is_inkernel, kr_need_schedule, kr_is_preemption, kr_runq_which; + int kr_protect_flags; + } leonbare_kernel_t __attribute__ ((aligned (8))); +#define LEONBARE_KR_CURRENT (KERNEL_GLOBAL.kr_cur) +#define LEONBARE_KR_NEXT (KERNEL_GLOBAL.kr_next) +#define LEONBARE_KR_RUNQ(i) (&(KERNEL_GLOBAL.kr_runq[i])) +#define LEONBARE_KR_RUNQ_WHICH (KERNEL_GLOBAL.kr_runq_which) +#define LEONBARE_KR_ALLQ (&(KERNEL_GLOBAL.kr_allq)) +#define LEONBARE_KR_ALLM (&(KERNEL_GLOBAL.kr_allm)) +#define LEONBARE_KR_IS_IN_KERNEL (KERNEL_GLOBAL.kr_is_inkernel) +#define LEONBARE_KR_IS_PREEMPTION (KERNEL_GLOBAL.kr_is_preemption) + +#define LEONBARE_KR_NEED_SCHEDULE (LEONBARE_KR_CURRENT != LEONBARE_KR_NEXT) + +#define LEONBARE_STACKALIGN(sp) ((((unsigned int)sp) + 7) & ~7) + +/* context switching macros, implemented via setjmp/longjmp plus saving errno */ +#define SAVE_CONTEXT(t) ( _leonbare_kernel_savecontext((t), 0) ) +#define RESTORE_CONTEXT(t) _leonbare_kernel_switchto((t), 1) + +#define KERNEL_SCHEDULE(f,retval) \ + MACRO_BEGIN \ + LEONBARE_KR_IS_IN_KERNEL--; \ + if (LEONBARE_KR_IS_IN_KERNEL == 0 && LEONBARE_KR_NEED_SCHEDULE) { \ + LEONBARE_KR_IS_IN_KERNEL++; \ + if ((f) && (SAVE_CONTEXT(LEONBARE_KR_CURRENT) == 0)) { \ + leonbare_sched(); \ + } \ + optbarrier(); \ + LEONBARE_KR_IS_IN_KERNEL--; \ + } \ + MACRO_END + +#define KERNEL_ENTER LEONBARE_KR_IS_IN_KERNEL++; +#define KERNEL_EXIT(f,ret) KERNEL_SCHEDULE(f,ret) + + int leonbare_thread_init (); + int leonbare_thread_create (struct leonbare_thread *thread, char *stack, + int stacksize); + int leonbare_sched_update (); + leonbare_thread_t leonbare_sched_paytime (); + void leonbare_sched_insert (struct leonbare_thread *thread, int head, + int prepare); + unsigned int leonbare_sched (); + unsigned int reschedule (); + unsigned int _leonbare_kernel_switchto (struct leonbare_thread *old, + struct leonbare_thread *new); + +#define LEONBARE_STACK_DEFINE(n,size) unsigned char n[size] __attribute__((aligned(8))); +#define LEONBARE_STACK_SIZE_DEFAULT 1024*20 + + typedef struct leonbare_mutex + { + unsigned int mx_owner_cnt; + leonbare_thread_t mx_owner; + struct leonbare_thread_queue mx_threads; + LBTAILQ_ENTRY (leonbare_mutex) mx_allm; + LBTAILQ_ENTRY (leonbare_mutex) mx_locked; + + } *leonbare_mutex_t; + +#define LEONBARE_MUTEX_OWNER_GET(m) LEONBARE_KERNEL_GETU32(m->mx_owner) +#define LEONBARE_MUTEX_OWNER_SET(m,o) LEONBARE_KERNEL_SETU32(m->mx_owner,o) +#define LEONBARE_MUTEX_OWNER_CNT_GET(m) LEONBARE_KERNEL_GETU32(m->mx_owner_cnt) +#define LEONBARE_MUTEX_OWNER_CNT_SET(m,o) LEONBARE_KERNEL_SETU32(m->mx_owner_cnt,o) + +#define LEONBARE_MUTEX_LOCK_TIMEOUT -1 +#define LEONBARE_MUTEX_LOCK_OK 0 +#define LEONBARE_MUTEX_LOCK_ERROR 1 + +#define LEONBARE_MUTEX_UNLOCK_OK 0 +#define LEONBARE_MUTEX_UNLOCK_ERROR 1 + + +#define LEONBARE_PROTECT_DECL(flags) unsigned long flags; +#define LEONBARE_PROTECT_KERNEL(flags) flags = leonbare_disable_traps(); +#define LEONBARE_UNPROTECT_KERNEL(flags) leonbare_enable_traps(flags); + +#define LEONBARE_PROTECT_MUTEX(flags,m) flags = leonbare_disable_traps(); +#define LEONBARE_UNPROTECT_MUTEX(flags,m) leonbare_enable_traps(flags); + +#else + +#define LEONBARE_THREAD_CTX_STORE_LOCALS(base_reg) \ + std %l0, [%base_reg + LEONBARE_THREAD_CTX_STACK_L0]; \ + std %l2, [%base_reg + LEONBARE_THREAD_CTX_STACK_L2]; \ + std %l4, [%base_reg + LEONBARE_THREAD_CTX_STACK_L4]; \ + std %l6, [%base_reg + LEONBARE_THREAD_CTX_STACK_L6]; + +#define LEONBARE_THREAD_CTX_STORE_INS(base_reg) \ + std %i0, [%base_reg + LEONBARE_THREAD_CTX_STACK_I0]; \ + std %i2, [%base_reg + LEONBARE_THREAD_CTX_STACK_I2]; \ + std %i4, [%base_reg + LEONBARE_THREAD_CTX_STACK_I4]; \ + std %i6, [%base_reg + LEONBARE_THREAD_CTX_STACK_I6]; + +#define LEONBARE_THREAD_CTX_STORE_OUTS(base_reg) \ + std %o0, [%base_reg + LEONBARE_THREAD_CTX_STACK_O0]; \ + std %o2, [%base_reg + LEONBARE_THREAD_CTX_STACK_O2]; \ + std %o4, [%base_reg + LEONBARE_THREAD_CTX_STACK_O4]; \ + std %o6, [%base_reg + LEONBARE_THREAD_CTX_STACK_O6]; + +#define LEONBARE_THREAD_CTX_STORE_GLOBALS(base_reg) \ + st %g1, [%base_reg + LEONBARE_THREAD_CTX_STACK_G1]; \ + std %g2, [%base_reg + LEONBARE_THREAD_CTX_STACK_G2]; \ + std %g4, [%base_reg + LEONBARE_THREAD_CTX_STACK_G4]; \ + std %g6, [%base_reg + LEONBARE_THREAD_CTX_STACK_G6]; + + +#define LEONBARE_THREAD_CTX_LOAD_LOCALS(base_reg) \ + ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_L0], %l0; \ + ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_L2], %l2; \ + ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_L4], %l4; \ + ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_L6], %l6; + +#define LEONBARE_THREAD_CTX_LOAD_INS(base_reg) \ + ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_I0], %i0; \ + ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_I2], %i2; \ + ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_I4], %i4; \ + ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_I6], %i6; + +#define LEONBARE_THREAD_CTX_LOAD_OUTS(base_reg) \ + ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_O0], %o0; \ + ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_O2], %o2; \ + ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_O4], %o4; \ + ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_O6], %o6; + +#define LEONBARE_THREAD_CTX_LOAD_GLOBALS(base_reg) \ + ld [%base_reg + LEONBARE_THREAD_CTX_STACK_G1], %g1; \ + ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_G2], %g2; \ + ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_G4], %g4; \ + ldd [%base_reg + LEONBARE_THREAD_CTX_STACK_G6], %g6; + + +#define LEONBARE_THREAD_CTX_STACK_L0 (0*8*4) +#define LEONBARE_THREAD_CTX_STACK_L2 (LEONBARE_THREAD_CTX_STACK_L0+(2*4)) +#define LEONBARE_THREAD_CTX_STACK_L4 (LEONBARE_THREAD_CTX_STACK_L0+(4*4)) +#define LEONBARE_THREAD_CTX_STACK_L6 (LEONBARE_THREAD_CTX_STACK_L0+(6*4)) + +#define LEONBARE_THREAD_CTX_STACK_I0 (1*8*4) +#define LEONBARE_THREAD_CTX_STACK_I2 (LEONBARE_THREAD_CTX_STACK_I0+(2*4)) +#define LEONBARE_THREAD_CTX_STACK_I4 (LEONBARE_THREAD_CTX_STACK_I0+(4*4)) +#define LEONBARE_THREAD_CTX_STACK_I6 (LEONBARE_THREAD_CTX_STACK_I0+(6*4)) + +#define LEONBARE_THREAD_CTX_STACK_O0 (2*8*4) +#define LEONBARE_THREAD_CTX_STACK_O2 (LEONBARE_THREAD_CTX_STACK_O0+(2*4)) +#define LEONBARE_THREAD_CTX_STACK_O4 (LEONBARE_THREAD_CTX_STACK_O0+(4*4)) +#define LEONBARE_THREAD_CTX_STACK_O6 (LEONBARE_THREAD_CTX_STACK_O0+(6*4)) + +#define LEONBARE_THREAD_CTX_STACK_G0 (3*8*4) +#define LEONBARE_THREAD_CTX_STACK_G1 (LEONBARE_THREAD_CTX_STACK_G0+(1*4)) +#define LEONBARE_THREAD_CTX_STACK_G2 (LEONBARE_THREAD_CTX_STACK_G0+(2*4)) +#define LEONBARE_THREAD_CTX_STACK_G4 (LEONBARE_THREAD_CTX_STACK_G0+(4*4)) +#define LEONBARE_THREAD_CTX_STACK_G6 (LEONBARE_THREAD_CTX_STACK_G0+(6*4)) + +#define LEONBARE_THREAD_CTX_STACK_PSR (4*8*4) +#define LEONBARE_THREAD_CTX_STACK_WIM (LEONBARE_THREAD_CTX_STACK_PSR+4) +#define LEONBARE_THREAD_CTX_STACK_MAGIC (LEONBARE_THREAD_CTX_STACK_PSR+8) +#define LEONBARE_THREAD_CTX_STACK_FPU (LEONBARE_THREAD_CTX_STACK_PSR+12) + +#define LEONBARE_THREAD_CTX_SZ (LEONBARE_THREAD_CTX_STACK_PSR+16) + +#endif /* __ASSEMBLER__ */ + +# define LEONBARE_STOPALL \ + LBDEBUG_HEADER_PRINTF(LBDEBUG_ALWAYS_NR,"Stopped at %s(%d), possibly not implemented yet\n",__FUNCTION__,__LINE__); \ + _leonbare_Stop(); + +#define LEONBARE_THREAD_CTX_MAGIC 0x1234 + +#ifdef LBDEBUG_DO_ASSERT +#define LEONBARE_VERIFYIRQDISABLED() LBPASSERT(((leon23_getpsr() & SPARC_PSR_PIL_MASK) == SPARC_PSR_PIL_MASK),"Irq must be disabled (pil==0xf)\n",0) +#define LEONBARE_VERIFYSCHED() leonbare_sched_verify() +#else +#define LEONBARE_VERIFYIRQDISABLED() +#define LEONBARE_VERIFYSCHED() +#endif +#define LEONBARE_PRINTQUEUES() if (PDEBUG_FLAGS_CHECK(LBDEBUG_QUEUE_NR)) { leonbare_sched_printqueue(); } + +#endif diff --git a/libgloss/sparc_leon/asm-leon/leonbare_kernel_queue.h b/libgloss/sparc_leon/asm-leon/leonbare_kernel_queue.h new file mode 100644 index 000000000..a51df105b --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/leonbare_kernel_queue.h @@ -0,0 +1,148 @@ +//####BSDCOPYRIGHTBEGIN#### +// +// ------------------------------------------- +// +// Portions of this software may have been derived from OpenBSD, +// FreeBSD or other sources, and are covered by the appropriate +// copyright disclaimers included herein. +// +// Portions created by Red Hat are +// Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. +// +// ------------------------------------------- +// +//####BSDCOPYRIGHTEND#### +//========================================================================== + +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + * $FreeBSD: src/sys/sys/queue.h,v 1.32.2.4 2001/03/31 03:33:39 hsu Exp $ + */ + +#ifndef _SYS_LEONBARE_QUEUE_H_ +#define _SYS_LEONBARE_QUEUE_H_ + + +/* + * Tail queue definitions. + */ +#define LBTAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ + char *tqh_name; \ +} + +#define LBTAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first, 0 } + +#define LBTAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} + +/* + * Tail queue functions. + */ +#define LBTAILQ_EMPTY(head) (LEONBARE_KERNEL_GETU32P((head)->tqh_first) == NULL) + +#define LBTAILQ_HASTWO(head, field) ((!LBTAILQ_EMPTY(head)) && LBTAILQ_NEXT(LBTAILQ_FIRST(head),field)) + +#define LBTAILQ_FOREACH(var, head, field) \ + for (var = LBTAILQ_FIRST(head); var; var = LBTAILQ_NEXT(var, field)) + +#define LBTAILQ_FIRST(head) LEONBARE_KERNEL_GETU32P_CAST((head)->tqh_first,__typeof((head)->tqh_first)) + +#define LBTAILQ_LAST(head, headname) \ + LEONBARE_KERNEL_GETU32P_BARE(LEONBARE_KERNEL_GETU32P(((struct headname *)(LEONBARE_KERNEL_GETU32P((head)->tqh_last)))->tqh_last)) + +#define LBTAILQ_NEXT(elm, field) LEONBARE_KERNEL_GETU32P_CAST((elm)->field.tqe_next,__typeof((elm)->field.tqe_next)) + +#define LBTAILQ_PREV(elm, headname, field) \ + LEONBARE_KERNEL_GETU32P_BARE(LEONBARE_KERNEL_GETU32P(((struct headname *)(LEONBARE_KERNEL_GETU32P((elm)->field.tqe_prev)))->tqh_last)) + +/* #define LBTAILQ_INIT(head) do { \ */ +/* (head)->tqh_first = NULL; \ */ +/* (head)->tqh_last = &(head)->tqh_first; \ */ +/* (head)->tqh_name = 0; \ */ +/* } while (0) */ + +#define LBTAILQ_INIT(head) do { \ + LEONBARE_KERNEL_SETU32P((head)->tqh_first,NULL); \ + LEONBARE_KERNEL_SETU32P((head)->tqh_last,&(head)->tqh_first); \ + LEONBARE_KERNEL_SETU32P((head)->tqh_name,0); \ +} while (0) + +/* #define LBTAILQ_INSERT_HEAD(head, elm, field) do { \ */ +/* if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ */ +/* (head)->tqh_first->field.tqe_prev = \ */ +/* &(elm)->field.tqe_next; \ */ +/* else \ */ +/* (head)->tqh_last = &(elm)->field.tqe_next; \ */ +/* (head)->tqh_first = (elm); \ */ +/* (elm)->field.tqe_prev = &(head)->tqh_first; \ */ +/* } while (0) */ + +#define LBTAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((LEONBARE_KERNEL_SETU32P((elm)->field.tqe_next,LEONBARE_KERNEL_GETU32P((head)->tqh_first))) != NULL) \ + LEONBARE_KERNEL_SETU32P(LEONBARE_KERNEL_GETU32P_CAST((head)->tqh_first,__typeof ((head)->tqh_first))->field.tqe_prev,&(elm)->field.tqe_next); \ + else \ + LEONBARE_KERNEL_SETU32P((head)->tqh_last,&(elm)->field.tqe_next); \ + LEONBARE_KERNEL_SETU32P((head)->tqh_first,(elm)); \ + LEONBARE_KERNEL_SETU32P((elm)->field.tqe_prev,&(head)->tqh_first); \ +} while (0) + +#define LBTAILQ_INSERT_TAIL(head, elm, field) do { \ + LEONBARE_KERNEL_SETU32P((elm)->field.tqe_next,NULL); \ + LEONBARE_KERNEL_SETU32P((elm)->field.tqe_prev,LEONBARE_KERNEL_GETU32P((head)->tqh_last)); \ + LEONBARE_KERNEL_SETU32P_BARE(LEONBARE_KERNEL_GETU32P((head)->tqh_last),(elm)); \ + LEONBARE_KERNEL_SETU32P((head)->tqh_last,&(elm)->field.tqe_next); \ +} while (0) + +#define LBTAILQ_REMOVE(head, elm, field) do { \ + if (LEONBARE_KERNEL_GETU32P((elm)->field.tqe_next) != NULL) \ + LEONBARE_KERNEL_SETU32P(LEONBARE_KERNEL_GETU32P_CAST((elm)->field.tqe_next, __typeof((elm)->field.tqe_next))->field.tqe_prev, LEONBARE_KERNEL_GETU32P((elm)->field.tqe_prev)); \ + else \ + LEONBARE_KERNEL_SETU32P((head)->tqh_last, LEONBARE_KERNEL_GETU32P((elm)->field.tqe_prev)); \ + LEONBARE_KERNEL_SETU32P_BARE(LEONBARE_KERNEL_GETU32P((elm)->field.tqe_prev),LEONBARE_KERNEL_GETU32P((elm)->field.tqe_next)); \ + LEONBARE_KERNEL_SETU32P((elm)->field.tqe_next, 0); \ + LEONBARE_KERNEL_SETU32P((elm)->field.tqe_prev, 0); /* mark removed */ \ +} while (0) + +#define LBTAILQ_REMOVED(elm, field) (LEONBARE_KERNEL_GETU32P((elm)->field.tqe_next) == NULL && LEONBARE_KERNEL_GETU32P((elm)->field.tqe_prev) == NULL) + + + +#endif /* !_SYS_QUEUE_H_ */ diff --git a/libgloss/sparc_leon/asm-leon/leoncompat.h b/libgloss/sparc_leon/asm-leon/leoncompat.h new file mode 100644 index 000000000..715829609 --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/leoncompat.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef _INCLUDE_LEONCOMPAT_h +#define _INCLUDE_LEONCOMPAT_h + +#include <asm-leon/leon.h> + +#ifndef __ASSEMBLER__ + +#define LEONCOMPAT_VERSION _leon_version +#define LEONCOMPAT_VERSION_ISLEON3 (LEONCOMPAT_VERSION == 3) +extern int _leon_version; + +#endif /* __ASSEMBLER__ */ + +#endif /* !_INCLUDE_LEONCOMPAT_h */ diff --git a/libgloss/sparc_leon/asm-leon/leondbg.h b/libgloss/sparc_leon/asm-leon/leondbg.h new file mode 100644 index 000000000..7b5b1cd9d --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/leondbg.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef _ASMSPARC_LEONDBG_H +#define _ASMSPARC_LEONDBG_H + +#ifndef __ASSEMBLER__ +extern int dbgleon_printf (const char *fmt, ...); +#endif + +#endif diff --git a/libgloss/sparc_leon/asm-leon/leonstack.h b/libgloss/sparc_leon/asm-leon/leonstack.h new file mode 100644 index 000000000..94cb6eade --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/leonstack.h @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef _INCLUDE_LEON_STACK_h +#define _INCLUDE_LEON_STACK_h + +#ifndef __ASSEMBLER__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* process trap regs */ + struct leonbare_pt_regs + { + unsigned long psr; + unsigned long pc; + unsigned long npc; + unsigned long y; + unsigned long u_regs[16]; /* globals and ins */ + }; +#define PT_REGS_SZ sizeof(struct leonbare_pt_regs) + +/* A Sparc stack frame */ + struct sparc_stackframe_regs + { + unsigned long sf_locals[8]; + unsigned long sf_ins[6]; + struct sparc_stackframe_regs *sf_fp; + unsigned long sf_callers_pc; + char *sf_structptr; + unsigned long sf_xargs[6]; + unsigned long sf_xxargs[1]; + }; +#define SF_REGS_SZ sizeof(struct sparc_stackframe_regs) + +/* A register window */ + struct sparc_regwindow_regs + { + unsigned long locals[8]; + unsigned long ins[8]; + }; +#define RW_REGS_SZ sizeof(struct sparc_regwindow_regs) + +/* A fpu window */ + struct sparc_fpuwindow_regs + { + unsigned long locals[32]; + unsigned long fsr; + unsigned long dummy; + unsigned long irqpsr; + unsigned long lastctx; + }; +#define FW_REGS_SZ sizeof(struct sparc_fpuwindow_regs) + +#ifdef __cplusplus +} +#endif + +#else +#define PT_REGS_SZ 0x50 /* 20*4 */ +#define SF_REGS_SZ 0x60 /* 24*4 */ +#define RW_REGS_SZ 0x20 /* 16*4 */ +#define FW_REGS_SZ 0x90 /* 36*4 */ +#endif /* !ASM */ + +/* These are for pt_regs. */ +#define PT_PSR 0x0 +#define PT_PC 0x4 +#define PT_NPC 0x8 +#define PT_Y 0xc +#define PT_G0 0x10 +#define PT_WIM PT_G0 +#define PT_G1 0x14 +#define PT_G2 0x18 +#define PT_G3 0x1c +#define PT_G4 0x20 +#define PT_G5 0x24 +#define PT_G6 0x28 +#define PT_G7 0x2c +#define PT_I0 0x30 +#define PT_I1 0x34 +#define PT_I2 0x38 +#define PT_I3 0x3c +#define PT_I4 0x40 +#define PT_I5 0x44 +#define PT_I6 0x48 +#define PT_FP PT_I6 +#define PT_I7 0x4c + +/* Stack_frame offsets */ +#define SF_L0 0x00 +#define SF_L1 0x04 +#define SF_L2 0x08 +#define SF_L3 0x0c +#define SF_L4 0x10 +#define SF_L5 0x14 +#define SF_L6 0x18 +#define SF_L7 0x1c +#define SF_I0 0x20 +#define SF_I1 0x24 +#define SF_I2 0x28 +#define SF_I3 0x2c +#define SF_I4 0x30 +#define SF_I5 0x34 +#define SF_FP 0x38 +#define SF_PC 0x3c +#define SF_RETP 0x40 +#define SF_XARG0 0x44 +#define SF_XARG1 0x48 +#define SF_XARG2 0x4c +#define SF_XARG3 0x50 +#define SF_XARG4 0x54 +#define SF_XARG5 0x58 +#define SF_XXARG 0x5c + +/* Reg_window offsets */ +#define RW_L0 0x00 +#define RW_L1 0x04 +#define RW_L2 0x08 +#define RW_L3 0x0c +#define RW_L4 0x10 +#define RW_L5 0x14 +#define RW_L6 0x18 +#define RW_L7 0x1c +#define RW_I0 0x20 +#define RW_I1 0x24 +#define RW_I2 0x28 +#define RW_I3 0x2c +#define RW_I4 0x30 +#define RW_I5 0x34 +#define RW_I6 0x38 +#define RW_I7 0x3c + +/* Fpu_window offsets */ +#define FW_F0 0x00 +#define FW_F2 0x08 +#define FW_F4 0x10 +#define FW_F6 0x18 +#define FW_F8 0x20 +#define FW_F10 0x28 +#define FW_F12 0x30 +#define FW_F14 0x38 +#define FW_F16 0x40 +#define FW_F18 0x48 +#define FW_F20 0x50 +#define FW_F22 0x58 +#define FW_F24 0x60 +#define FW_F26 0x68 +#define FW_F28 0x70 +#define FW_F30 0x78 +#define FW_FSR 0x80 + +#endif /* !_INCLUDE_LEON_STACK_h */ diff --git a/libgloss/sparc_leon/asm-leon/liblocks.h b/libgloss/sparc_leon/asm-leon/liblocks.h new file mode 100644 index 000000000..66f605f59 --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/liblocks.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef __LEONBARE_LIBLOCKS_H +#define __LEONBARE_LIBLOCKS_H + +extern int (*__lbst_pthread_mutex_init) (pthread_mutex_t * __mutex, + pthread_mutexattr_t * __mutex_attr); +extern int (*__lbst_pthread_mutex_destroy) (pthread_mutex_t * __mutex); +extern int (*__lbst_pthread_mutex_trylock) (pthread_mutex_t * __mutex); +extern int (*__lbst_pthread_mutex_lock) (pthread_mutex_t * __mutex); +extern int (*__lbst_pthread_mutex_unlock) (pthread_mutex_t * __mutex); +extern int (*__lbst_pthread_mutexattr_init) (pthread_mutexattr_t * __attr); +extern int (*__lbst_pthread_mutexattr_destroy) (pthread_mutexattr_t * __attr); +extern int (*__lbst_pthread_mutexattr_settype) (pthread_mutexattr_t * __attr, + int __kind); + +#endif /* __LEONBARE_LIBLOCKS_H */ diff --git a/libgloss/sparc_leon/asm-leon/linkage.h b/libgloss/sparc_leon/asm-leon/linkage.h new file mode 100644 index 000000000..d82eb90b1 --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/linkage.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef H_LEONBARE_LINKAGE_H +#define H_LEONBARE_LINKAGE_H + +#ifndef _ASM +# define __inline__ __inline__ __attribute__((always_inline)) + +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) +#define barrier() __memory_barrier() + +#define gccalign8 __attribute__((aligned(8))) + +#else /* !_ASM */ + +#define MCOUNT_SIZE 0 /* no instructions inserted */ +#define MCOUNT(x) + +/* + * ENTRY provides the standard procedure entry code and an easy way to + * insert the calls to mcount for profiling. ENTRY_NP is identical, but + * never calls mcount. + */ +#define ENTRY(x) \ + .section ".text"; \ + .align 4; \ + .global x; \ + .type x, #function; \ +x: MCOUNT(x) + +#define ENTRY_SIZE MCOUNT_SIZE + +#endif /* _ASM */ + +#endif diff --git a/libgloss/sparc_leon/asm-leon/param.h b/libgloss/sparc_leon/asm-leon/param.h new file mode 100644 index 000000000..4b24092c0 --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/param.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef _LEON_ASMSPARC_PARAM_H +#define _LEON_ASMSPARC_PARAM_H + +/* note: this is also defined in machine/param.h */ +#define HZ 100UL /* Internal kernel timer frequency */ +#define CLOCK_TICK_RATE 1000000UL /* Underlying HZ */ + +#endif diff --git a/libgloss/sparc_leon/asm-leon/queue.h b/libgloss/sparc_leon/asm-leon/queue.h new file mode 100644 index 000000000..621bc3016 --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/queue.h @@ -0,0 +1,570 @@ +//####BSDCOPYRIGHTBEGIN#### +// +// ------------------------------------------- +// +// Portions of this software may have been derived from OpenBSD, +// FreeBSD or other sources, and are covered by the appropriate +// copyright disclaimers included herein. +// +// Portions created by Red Hat are +// Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. +// +// ------------------------------------------- +// +//####BSDCOPYRIGHTEND#### +//========================================================================== + +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + * $FreeBSD: src/sys/sys/queue.h,v 1.32.2.4 2001/03/31 03:33:39 hsu Exp $ + */ + +#ifndef _SYS_QUEUE_H_ +#define _SYS_QUEUE_H_ + +#ifndef __ASSEMBLER__ + +/* + * This file defines five types of data structures: singly-linked lists, + * singly-linked tail queues, lists, tail queues, and circular queues. + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A singly-linked tail queue is headed by a pair of pointers, one to the + * head of the list and the other to the tail of the list. The elements are + * singly linked for minimum space and pointer manipulation overhead at the + * expense of O(n) removal for arbitrary elements. New elements can be added + * to the list after an existing element, at the head of the list, or at the + * end of the list. Elements being removed from the head of the tail queue + * should use the explicit macro for this purpose for optimum efficiency. + * A singly-linked tail queue may only be traversed in the forward direction. + * Singly-linked tail queues are ideal for applications with large datasets + * and few or no removals or for implementing a FIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * A circle queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the list. + * A circle queue may be traversed in either direction, but has a more + * complex end of list detection. + * + * For details on the use of these macros, see the queue(3) manual page. + * + * + * SLIST LIST STAILQ TAILQ CIRCLEQ + * _HEAD + + + + + + * _ENTRY + + + + + + * _INIT + + + + + + * _EMPTY + + + + + + * _FIRST + + + + + + * _NEXT + + + + + + * _PREV - - - + + + * _LAST - - + + + + * _FOREACH + + + + + + * _FOREACH_REVERSE - - - + + + * _INSERT_HEAD + + + + + + * _INSERT_BEFORE - + - + + + * _INSERT_AFTER + + + + + + * _INSERT_TAIL - - + + + + * _REMOVE_HEAD + - + - - + * _REMOVE + + + + + + * + */ + +/* + * Singly-linked List definitions. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List functions. + */ +#define SLIST_EMPTY(head) ((head)->slh_first == NULL) + +#define SLIST_FIRST(head) ((head)->slh_first) + +#define SLIST_FOREACH(var, head, field) \ + for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next) + +#define SLIST_INIT(head) { \ + (head)->slh_first = NULL; \ +} + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + (elm)->field.sle_next = (slistelm)->field.sle_next; \ + (slistelm)->field.sle_next = (elm); \ +} while (0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.sle_next = (head)->slh_first; \ + (head)->slh_first = (elm); \ +} while (0) + +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + (head)->slh_first = (head)->slh_first->field.sle_next; \ +} while (0) + +#define SLIST_REMOVE(head, elm, type, field) do { \ + if ((head)->slh_first == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = (head)->slh_first; \ + while( curelm->field.sle_next != (elm) ) \ + curelm = curelm->field.sle_next; \ + curelm->field.sle_next = \ + curelm->field.sle_next->field.sle_next; \ + } \ +} while (0) + +/* + * Singly-linked Tail queue definitions. + */ +#define STAILQ_HEAD(name, type) \ +struct name { \ + struct type *stqh_first;/* first element */ \ + struct type **stqh_last;/* addr of last next element */ \ +} + +#define STAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).stqh_first } + +#define STAILQ_ENTRY(type) \ +struct { \ + struct type *stqe_next; /* next element */ \ +} + +/* + * Singly-linked Tail queue functions. + */ +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) + +#define STAILQ_INIT(head) do { \ + (head)->stqh_first = NULL; \ + (head)->stqh_last = &(head)->stqh_first; \ +} while (0) + +#define STAILQ_FIRST(head) ((head)->stqh_first) + +#define STAILQ_LAST(head, type, field) \ + (STAILQ_EMPTY(head) ? \ + NULL : \ + ((struct type *) \ + ((char *)((head)->stqh_last) - __offsetof(struct type, field)))) + +#define STAILQ_FOREACH(var, head, field) \ + for((var) = (head)->stqh_first; (var); (var) = (var)->field.stqe_next) + +#define STAILQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \ + (head)->stqh_last = &(elm)->field.stqe_next; \ + (head)->stqh_first = (elm); \ +} while (0) + +#define STAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.stqe_next = NULL; \ + *(head)->stqh_last = (elm); \ + (head)->stqh_last = &(elm)->field.stqe_next; \ +} while (0) + +#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ + if (((elm)->field.stqe_next = (tqelm)->field.stqe_next) == NULL)\ + (head)->stqh_last = &(elm)->field.stqe_next; \ + (tqelm)->field.stqe_next = (elm); \ +} while (0) + +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) + +#define STAILQ_REMOVE_HEAD(head, field) do { \ + if (((head)->stqh_first = \ + (head)->stqh_first->field.stqe_next) == NULL) \ + (head)->stqh_last = &(head)->stqh_first; \ +} while (0) + +#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ + if (((head)->stqh_first = (elm)->field.stqe_next) == NULL) \ + (head)->stqh_last = &(head)->stqh_first; \ +} while (0) + +#define STAILQ_REMOVE(head, elm, type, field) do { \ + if ((head)->stqh_first == (elm)) { \ + STAILQ_REMOVE_HEAD(head, field); \ + } \ + else { \ + struct type *curelm = (head)->stqh_first; \ + while( curelm->field.stqe_next != (elm) ) \ + curelm = curelm->field.stqe_next; \ + if((curelm->field.stqe_next = \ + curelm->field.stqe_next->field.stqe_next) == NULL) \ + (head)->stqh_last = &(curelm)->field.stqe_next; \ + } \ +} while (0) + +/* + * List definitions. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List functions. + */ + +#define LIST_EMPTY(head) ((head)->lh_first == NULL) + +#define LIST_FIRST(head) ((head)->lh_first) + +#define LIST_FOREACH(var, head, field) \ + for((var) = (head)->lh_first; (var); (var) = (var)->field.le_next) + +#define LIST_INIT(head) do { \ + (head)->lh_first = NULL; \ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ + (listelm)->field.le_next->field.le_prev = \ + &(elm)->field.le_next; \ + (listelm)->field.le_next = (elm); \ + (elm)->field.le_prev = &(listelm)->field.le_next; \ +} while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + (elm)->field.le_next = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &(elm)->field.le_next; \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.le_next = (head)->lh_first) != NULL) \ + (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ + (head)->lh_first = (elm); \ + (elm)->field.le_prev = &(head)->lh_first; \ +} while (0) + +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_REMOVE(elm, field) do { \ + if ((elm)->field.le_next != NULL) \ + (elm)->field.le_next->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = (elm)->field.le_next; \ +} while (0) + +/* + * Tail queue definitions. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ + char *tqh_name; \ +} + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first, 0 } + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} + +/* + * Tail queue functions. + */ +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) + +#define TAILQ_HASTWO(head, field) ((!TAILQ_EMPTY(head)) && TAILQ_NEXT(TAILQ_FIRST(head),field)) + +#define TAILQ_FOREACH(var, head, field) \ + for (var = TAILQ_FIRST(head); var; var = TAILQ_NEXT(var, field)) + +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var); \ + (var) = TAILQ_PREV((var), headname, field)) + +#define TAILQ_FIRST(head) ((head)->tqh_first) + +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) + +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) + +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) + +#define TAILQ_INIT(head) do { \ + (head)->tqh_first = NULL; \ + (head)->tqh_last = &(head)->tqh_first; \ + (head)->tqh_name = 0; \ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ + (head)->tqh_first->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (head)->tqh_first = (elm); \ + (elm)->field.tqe_prev = &(head)->tqh_first; \ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.tqe_next = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &(elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ + (elm)->field.tqe_next->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (listelm)->field.tqe_next = (elm); \ + (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ +} while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + (elm)->field.tqe_next = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_REMOVE(head, elm, field) do { \ + if (((elm)->field.tqe_next) != NULL) \ + (elm)->field.tqe_next->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ + (elm)->field.tqe_next = 0; \ + (elm)->field.tqe_prev = 0; /* mark removed */ \ +} while (0) + +#define TAILQ_REMOVED(elm, field) ((elm)->field.tqe_next == NULL && (elm)->field.tqe_prev == NULL) + +/* + * Circular queue definitions. + */ +#define CIRCLEQ_HEAD(name, type) \ +struct name { \ + struct type *cqh_first; /* first element */ \ + struct type *cqh_last; /* last element */ \ +} + +#define CIRCLEQ_ENTRY(type) \ +struct { \ + struct type *cqe_next; /* next element */ \ + struct type *cqe_prev; /* previous element */ \ +} + +/* + * Circular queue functions. + */ +#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) + +#define CIRCLEQ_FIRST(head) ((head)->cqh_first) + +#define CIRCLEQ_FOREACH(var, head, field) \ + for((var) = (head)->cqh_first; \ + (var) != (void *)(head); \ + (var) = (var)->field.cqe_next) + +#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ + for((var) = (head)->cqh_last; \ + (var) != (void *)(head); \ + (var) = (var)->field.cqe_prev) + +#define CIRCLEQ_INIT(head) do { \ + (head)->cqh_first = (void *)(head); \ + (head)->cqh_last = (void *)(head); \ +} while (0) + +#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm)->field.cqe_next; \ + (elm)->field.cqe_prev = (listelm); \ + if ((listelm)->field.cqe_next == (void *)(head)) \ + (head)->cqh_last = (elm); \ + else \ + (listelm)->field.cqe_next->field.cqe_prev = (elm); \ + (listelm)->field.cqe_next = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm); \ + (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ + if ((listelm)->field.cqe_prev == (void *)(head)) \ + (head)->cqh_first = (elm); \ + else \ + (listelm)->field.cqe_prev->field.cqe_next = (elm); \ + (listelm)->field.cqe_prev = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.cqe_next = (head)->cqh_first; \ + (elm)->field.cqe_prev = (void *)(head); \ + if ((head)->cqh_last == (void *)(head)) \ + (head)->cqh_last = (elm); \ + else \ + (head)->cqh_first->field.cqe_prev = (elm); \ + (head)->cqh_first = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.cqe_next = (void *)(head); \ + (elm)->field.cqe_prev = (head)->cqh_last; \ + if ((head)->cqh_first == (void *)(head)) \ + (head)->cqh_first = (elm); \ + else \ + (head)->cqh_last->field.cqe_next = (elm); \ + (head)->cqh_last = (elm); \ +} while (0) + +#define CIRCLEQ_LAST(head) ((head)->cqh_last) + +#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next) + +#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev) + +#define CIRCLEQ_REMOVE(head, elm, field) do { \ + if ((elm)->field.cqe_next == (void *)(head)) \ + (head)->cqh_last = (elm)->field.cqe_prev; \ + else \ + (elm)->field.cqe_next->field.cqe_prev = \ + (elm)->field.cqe_prev; \ + if ((elm)->field.cqe_prev == (void *)(head)) \ + (head)->cqh_first = (elm)->field.cqe_next; \ + else \ + (elm)->field.cqe_prev->field.cqe_next = \ + (elm)->field.cqe_next; \ +} while (0) + +/* + * XXX insque() and remque() are an old way of handling certain queues. + * They bogusly assumes that all queue heads look alike. + */ + +struct quehead +{ + struct quehead *qh_link; + struct quehead *qh_rlink; +}; + +#ifdef __GNUC__ + +static __inline void +insque (void *a, void *b) +{ + struct quehead *element = a, *head = b; + + element->qh_link = head->qh_link; + element->qh_rlink = head; + head->qh_link = element; + element->qh_link->qh_rlink = element; +} + +static __inline void +remque (void *a) +{ + struct quehead *element = a; + + element->qh_link->qh_rlink = element->qh_rlink; + element->qh_rlink->qh_link = element->qh_link; + element->qh_rlink = 0; +} + +#else /* !__GNUC__ */ + +void insque __P ((void *a, void *b)); +void remque __P ((void *a)); + +#endif /* __GNUC__ */ + +#endif /* __ASSEMBLER__ */ + + +#endif /* !_SYS_QUEUE_H_ */ diff --git a/libgloss/sparc_leon/asm-leon/spinlock.h b/libgloss/sparc_leon/asm-leon/spinlock.h new file mode 100644 index 000000000..c3c0a7c4e --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/spinlock.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef _INCLUDE_LEONSPINLOCK_h +#define _INCLUDE_LEONSPINLOCK_h + +typedef struct +{ + unsigned char lock; +} raw_spinlock_t; + +#define __RAW_SPIN_LOCK_UNLOCKED { 0 } + +typedef struct +{ + volatile unsigned int lock; +} raw_rwlock_t; + +#define __RAW_RW_LOCK_UNLOCKED { 0 } + +static inline void +__raw_spin_lock (raw_spinlock_t * lock) +{ + __asm__ __volatile__ ("\n1:\n\t" "ldstuba [%0]1, %%g2\n\t" /* ASI_LEON23_DCACHE_MISS */ + "orcc %%g2, 0x0, %%g0\n\t" "bne,a 2f\n\t" " ldub [%0], %%g2\n\t" ".subsection 2\n" "2:\n\t" "orcc %%g2, 0x0, %%g0\n\t" "bne,a 2b\n\t" " ldub [%0], %%g2\n\t" "b,a 1b\n\t" ".previous\n": /* no outputs */ + :"r" (lock):"g2", "memory", "cc"); +} + +static inline int +__raw_spin_trylock (raw_spinlock_t * lock) +{ + unsigned int result; + __asm__ __volatile__ ("ldstuba [%1]1, %0" /* ASI_LEON23_DCACHE_MISS */ + :"=r" (result):"r" (lock):"memory"); + return (result == 0); +} + +static inline void +__raw_spin_unlock (raw_spinlock_t * lock) +{ + __asm__ __volatile__ ("stb %%g0, [%0]"::"r" (lock):"memory"); +} + + + +#endif /* _INCLUDE_LEONSPINLOCK_h */ +/* end of include file */ diff --git a/libgloss/sparc_leon/asm-leon/stack.h b/libgloss/sparc_leon/asm-leon/stack.h new file mode 100644 index 000000000..5ba773bc3 --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/stack.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef _SYS_STACK_H_ +#define _SYS_STACK_H_ + +#if !defined(_ASM) +#include <sys/types.h> +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* + * A stack frame looks like: + * + * %fp->| | + * |-------------------------------| + * | Locals, temps, saved floats | + * |-------------------------------| + * | outgoing parameters past 6 | + * |-------------------------------|-\ + * | 6 words for callee to dump | | + * | register arguments | | + * |-------------------------------| > minimum stack frame + * | One word struct-ret address | | + * |-------------------------------| | + * | 16 words to save IN and | | + * %sp->| LOCAL register on overflow | | + * |-------------------------------|-/ + */ + +/* + * Constants defining a 32-bit stack frame. + */ +#define WINDOWSIZE (16*4) /* size of window save area */ +#define ARGPUSHSIZE (6*4) /* size of arg dump area */ +#define ARGPUSH (WINDOWSIZE + 4) /* arg dump area offset */ +#define MINFRAME (WINDOWSIZE + ARGPUSHSIZE + 4) /* min frame */ + +#define STACK_GROWTH_DOWN /* stacks grow from high to low addresses */ + +/* + * Stack alignment macros. + */ +#define STACK_ALIGN 8 +#define SA(X) (((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1)) + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_STACK_H */ diff --git a/libgloss/sparc_leon/asm-leon/time.h b/libgloss/sparc_leon/asm-leon/time.h new file mode 100644 index 000000000..487190e21 --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/time.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef _ASMSPARC_TIME_H +#define _ASMSPARC_TIME_H + +extern struct timespec xtime; +extern unsigned long tick_nsec; /* nsec per tick (resolution) */ +extern unsigned long nodotimer; + +#endif diff --git a/libgloss/sparc_leon/asm-leon/timer.h b/libgloss/sparc_leon/asm-leon/timer.h new file mode 100644 index 000000000..f650d2e27 --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/timer.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef _ASMSPARC_TIMER_H +#define _ASMSPARC_TIMER_H + +#include <asm-leon/queue.h> +/*#include <sys/fsu_pthread_queue.h>*/ +#include <sys/time.h> +#include <asm-leon/clock.h> + +#ifndef __ASSEMBLER__ +typedef int (*timerevent_handler) (void *); +struct timerevent +{ + TAILQ_ENTRY (timerevent) n; + struct timespec expire; + timerevent_handler handler; + void *arg; + +}; +#endif + +#define GT_TIMESPEC(t1, t2) \ + (t1.tv_sec > t2.tv_sec || \ + (t1.tv_sec == t2.tv_sec && \ + t1.tv_nsec > t2.tv_nsec)) + +#define GT_TIMEVAL(t1, t2) \ + (t1.tv_sec > t2.tv_sec || \ + (t1.tv_sec == t2.tv_sec && \ + t1.tv_usec > t2.tv_usec)) + +/* + * MINUS_TIME only works if src1 > src2 + */ +#define MINUS_TIMEVAL(dst, src1, src2) \ + if ((src2).tv_usec > (src1).tv_usec) { \ + (dst).tv_sec = (src1).tv_sec - (src2).tv_sec - 1; \ + (dst).tv_usec = ((src1).tv_usec - (src2).tv_usec) + USEC_PER_SEC; \ + } \ + else { \ + (dst).tv_sec = (src1).tv_sec - (src2).tv_sec; \ + (dst).tv_usec = (src1).tv_usec - (src2).tv_usec; \ + } + +/* Protypes */ +#ifndef __ASSEMBLER__ +void leonbare_init_ticks (); +int addtimer (struct timerevent *e); +#endif + +#endif diff --git a/libgloss/sparc_leon/asm-leon/types.h b/libgloss/sparc_leon/asm-leon/types.h new file mode 100644 index 000000000..fa9e721fc --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/types.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#ifndef H_LEONBARE_TYPES_H +#define H_LEONBARE_TYPES_H + +typedef unsigned long long u64; + +#endif diff --git a/libgloss/sparc_leon/asm-leon/winmacros.h b/libgloss/sparc_leon/asm-leon/winmacros.h new file mode 100644 index 000000000..37ca6760e --- /dev/null +++ b/libgloss/sparc_leon/asm-leon/winmacros.h @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2011 Aeroflex Gaisler + * + * BSD license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#include <asm-leon/leon.h> +#include <asm-leon/leonstack.h> +#include <asm-leon/asmmacro.h> + +/* Store the register window onto the 8-byte aligned area starting + * at %reg. It might be %sp, it might not, we don't care. + */ +#define RW_STORE(reg) \ + std %l0, [%reg + RW_L0]; \ + std %l2, [%reg + RW_L2]; \ + std %l4, [%reg + RW_L4]; \ + std %l6, [%reg + RW_L6]; \ + std %i0, [%reg + RW_I0]; \ + std %i2, [%reg + RW_I2]; \ + std %i4, [%reg + RW_I4]; \ + std %i6, [%reg + RW_I6]; + +/* Load a register window from the area beginning at %reg. */ +#define RW_LOAD(reg) \ + ldd [%reg + RW_L0], %l0; \ + ldd [%reg + RW_L2], %l2; \ + ldd [%reg + RW_L4], %l4; \ + ldd [%reg + RW_L6], %l6; \ + ldd [%reg + RW_I0], %i0; \ + ldd [%reg + RW_I2], %i2; \ + ldd [%reg + RW_I4], %i4; \ + ldd [%reg + RW_I6], %i6; + +/* Loading and storing struct pt_reg trap frames. */ +#define PT_LOAD_INS(base_reg) \ + ldd [%base_reg + SF_REGS_SZ + PT_I0], %i0; \ + ldd [%base_reg + SF_REGS_SZ + PT_I2], %i2; \ + ldd [%base_reg + SF_REGS_SZ + PT_I4], %i4; \ + ldd [%base_reg + SF_REGS_SZ + PT_I6], %i6; + +#define PT_LOAD_GLOBALS(base_reg) \ + ld [%base_reg + SF_REGS_SZ + PT_G1], %g1; \ + ldd [%base_reg + SF_REGS_SZ + PT_G2], %g2; \ + ldd [%base_reg + SF_REGS_SZ + PT_G4], %g4; \ + ldd [%base_reg + SF_REGS_SZ + PT_G6], %g6; + +#define PT_LOAD_GLOBALS_23(base_reg) \ + ldd [%base_reg + SF_REGS_SZ + PT_G2], %g2; + +#define PT_LOAD_YREG(base_reg, scratch) \ + ld [%base_reg + SF_REGS_SZ + PT_Y], %scratch; \ + wr %scratch, 0x0, %y; + +#define PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \ + ld [%base_reg + SF_REGS_SZ + PT_PSR], %pt_psr; \ + ld [%base_reg + SF_REGS_SZ + PT_PC], %pt_pc; \ + ld [%base_reg + SF_REGS_SZ + PT_NPC], %pt_npc; + +#define PT_LOAD_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \ + PT_LOAD_YREG(base_reg, scratch) \ + PT_LOAD_INS(base_reg) \ + PT_LOAD_GLOBALS(base_reg) \ + PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) + +#define PT_LOAD_ALL_FAST(base_reg, pt_psr, pt_pc, pt_npc, scratch) \ + PT_LOAD_YREG(base_reg, scratch) \ + PT_LOAD_GLOBALS(base_reg) + +#define PT_STORE_INS(base_reg) \ + std %i0, [%base_reg + SF_REGS_SZ + PT_I0]; \ + std %i2, [%base_reg + SF_REGS_SZ + PT_I2]; \ + std %i4, [%base_reg + SF_REGS_SZ + PT_I4]; \ + std %i6, [%base_reg + SF_REGS_SZ + PT_I6]; + +#define PT_STORE_GLOBALS(base_reg) \ + st %g1, [%base_reg + SF_REGS_SZ + PT_G1]; \ + std %g2, [%base_reg + SF_REGS_SZ + PT_G2]; \ + std %g4, [%base_reg + SF_REGS_SZ + PT_G4]; \ + std %g6, [%base_reg + SF_REGS_SZ + PT_G6]; + +#define PT_STORE_GLOBALS_23(base_reg) \ + std %g2, [%base_reg + SF_REGS_SZ + PT_G2]; + +#define PT_STORE_YREG(base_reg, scratch) \ + rd %y, %scratch; \ + st %scratch, [%base_reg + SF_REGS_SZ + PT_Y]; + +#define PT_STORE_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \ + st %pt_psr, [%base_reg + SF_REGS_SZ + PT_PSR]; \ + st %pt_pc, [%base_reg + SF_REGS_SZ + PT_PC]; \ + st %pt_npc, [%base_reg + SF_REGS_SZ + PT_NPC]; + +#define PT_STORE_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \ + PT_STORE_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \ + PT_STORE_GLOBALS(base_reg) \ + PT_STORE_YREG(base_reg, g_scratch) \ + PT_STORE_INS(base_reg) + +#define PT_STORE_ALL_FAST(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \ + PT_STORE_GLOBALS(base_reg) \ + PT_STORE_YREG(base_reg, g_scratch) + +/* Store the fpu register window*/ +#define FW_STORE(reg) \ + std %f0, [reg + FW_F0]; \ + std %f2, [reg + FW_F2]; \ + std %f4, [reg + FW_F4]; \ + std %f6, [reg + FW_F6]; \ + std %f8, [reg + FW_F8]; \ + std %f10, [reg + FW_F10]; \ + std %f12, [reg + FW_F12]; \ + std %f14, [reg + FW_F14]; \ + std %f16, [reg + FW_F16]; \ + std %f18, [reg + FW_F18]; \ + std %f20, [reg + FW_F20]; \ + std %f22, [reg + FW_F22]; \ + std %f24, [reg + FW_F24]; \ + std %f26, [reg + FW_F26]; \ + std %f28, [reg + FW_F28]; \ + std %f30, [reg + FW_F30]; \ + st %fsr, [reg + FW_FSR]; + +/* Load a fpu register window from the area beginning at reg. */ +#define FW_LOAD(reg) \ + ldd [reg + FW_F0], %f0; \ + ldd [reg + FW_F2], %f2; \ + ldd [reg + FW_F4], %f4; \ + ldd [reg + FW_F6], %f6; \ + ldd [reg + FW_F8], %f8; \ + ldd [reg + FW_F10], %f10; \ + ldd [reg + FW_F12], %f12; \ + ldd [reg + FW_F14], %f14; \ + ldd [reg + FW_F16], %f16; \ + ldd [reg + FW_F18], %f18; \ + ldd [reg + FW_F20], %f20; \ + ldd [reg + FW_F22], %f22; \ + ldd [reg + FW_F24], %f24; \ + ldd [reg + FW_F26], %f26; \ + ldd [reg + FW_F28], %f28; \ + ldd [reg + FW_F30], %f30; \ + ld [reg + FW_FSR], %fsr; + +#define SET_WIM_CWPMIN2(psr_reg,tmp1,tmp2,tmp3,tmp4) \ + sethi %hi(_nwindows_min2), %##tmp1; \ + and %##psr_reg, SPARC_PSR_WIN_MASK, %##tmp3; \ + mov 1, %##tmp2; \ + ld [ %##tmp1 + %lo(_nwindows_min2)], %##tmp1; \ + sll %##tmp2, %##tmp3, %##tmp3; \ + sll %##tmp3, 2, %##tmp4; \ + srl %##tmp3, %##tmp1, %##tmp1; \ + or %##tmp4, %##tmp1, %##tmp3; \ + wr %##tmp3, 0x0, %wim; \ + nop; nop; nop; + +#define SET_WIM_CWPMIN1(psr_reg,tmp1,tmp2,tmp3,tmp4) \ + sethi %hi(_nwindows_min1), %##tmp1; \ + and %##psr_reg, SPARC_PSR_WIN_MASK, %##tmp3; \ + mov 1, %##tmp2; \ + ld [ %##tmp1 + %lo(_nwindows_min1)], %##tmp1; \ + sll %##tmp2, %##tmp3, %##tmp3; \ + sll %##tmp3, 1, %##tmp4; \ + srl %##tmp3, %##tmp1, %##tmp1; \ + or %##tmp4, %##tmp1, %##tmp3; \ + wr %##tmp3, 0x0, %wim; \ + nop; nop; nop; |