mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 02:03:56 -06:00
Move target-* CPU file into a target/ folder
We've currently got 18 architectures in QEMU, and thus 18 target-xxx folders in the root folder of the QEMU source tree. More architectures (e.g. RISC-V, AVR) are likely to be included soon, too, so the main folder of the QEMU sources slowly gets quite overcrowded with the target-xxx folders. To disburden the main folder a little bit, let's move the target-xxx folders into a dedicated target/ folder, so that target-xxx/ simply becomes target/xxx/ instead. Acked-by: Laurent Vivier <laurent@vivier.eu> [m68k part] Acked-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de> [tricore part] Acked-by: Michael Walle <michael@walle.cc> [lm32 part] Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com> [s390x part] Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com> [s390x part] Acked-by: Eduardo Habkost <ehabkost@redhat.com> [i386 part] Acked-by: Artyom Tarasenko <atar4qemu@gmail.com> [sparc part] Acked-by: Richard Henderson <rth@twiddle.net> [alpha part] Acked-by: Max Filippov <jcmvbkbc@gmail.com> [xtensa part] Reviewed-by: David Gibson <david@gibson.dropbear.id.au> [ppc part] Acked-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> [crisµblaze part] Acked-by: Guan Xuetao <gxt@mprc.pku.edu.cn> [unicore32 part] Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
parent
82ecffa8c0
commit
fcf5ef2ab5
369 changed files with 78 additions and 80 deletions
7
target/xtensa/Makefile.objs
Normal file
7
target/xtensa/Makefile.objs
Normal file
|
@ -0,0 +1,7 @@
|
|||
obj-y += xtensa-semi.o
|
||||
obj-y += core-dc232b.o
|
||||
obj-y += core-dc233c.o
|
||||
obj-y += core-fsf.o
|
||||
obj-$(CONFIG_SOFTMMU) += monitor.o
|
||||
obj-y += translate.o op_helper.o helper.o cpu.o
|
||||
obj-y += gdbstub.o
|
50
target/xtensa/core-dc232b.c
Normal file
50
target/xtensa/core-dc232b.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of the Open Source and Linux Lab 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 COPYRIGHT HOLDERS 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "exec/gdbstub.h"
|
||||
#include "qemu/host-utils.h"
|
||||
|
||||
#include "core-dc232b/core-isa.h"
|
||||
#include "overlay_tool.h"
|
||||
|
||||
static XtensaConfig dc232b __attribute__((unused)) = {
|
||||
.name = "dc232b",
|
||||
.gdb_regmap = {
|
||||
.num_regs = 120,
|
||||
.num_core_regs = 52,
|
||||
.reg = {
|
||||
#include "core-dc232b/gdb-config.c"
|
||||
}
|
||||
},
|
||||
.clock_freq_khz = 10000,
|
||||
DEFAULT_SECTIONS
|
||||
};
|
||||
|
||||
REGISTER_CORE(dc232b)
|
422
target/xtensa/core-dc232b/core-isa.h
Normal file
422
target/xtensa/core-dc232b/core-isa.h
Normal file
|
@ -0,0 +1,422 @@
|
|||
/*
|
||||
* Xtensa processor core configuration information.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (c) 1999-2007 Tensilica Inc.
|
||||
*/
|
||||
|
||||
#ifndef XTENSA_DC232B_CORE_ISA_H
|
||||
#define XTENSA_DC232B_CORE_ISA_H
|
||||
|
||||
/****************************************************************************
|
||||
Parameters Useful for Any Code, USER or PRIVILEGED
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Note: Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is
|
||||
* configured, and a value of 0 otherwise. These macros are always defined.
|
||||
*/
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
ISA
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_HAVE_BE 0 /* big-endian byte ordering */
|
||||
#define XCHAL_HAVE_WINDOWED 1 /* windowed registers option */
|
||||
#define XCHAL_NUM_AREGS 32 /* num of physical addr regs */
|
||||
#define XCHAL_NUM_AREGS_LOG2 5 /* log2(XCHAL_NUM_AREGS) */
|
||||
#define XCHAL_MAX_INSTRUCTION_SIZE 3 /* max instr bytes (3..8) */
|
||||
#define XCHAL_HAVE_DEBUG 1 /* debug option */
|
||||
#define XCHAL_HAVE_DENSITY 1 /* 16-bit instructions */
|
||||
#define XCHAL_HAVE_LOOPS 1 /* zero-overhead loops */
|
||||
#define XCHAL_HAVE_NSA 1 /* NSA/NSAU instructions */
|
||||
#define XCHAL_HAVE_MINMAX 1 /* MIN/MAX instructions */
|
||||
#define XCHAL_HAVE_SEXT 1 /* SEXT instruction */
|
||||
#define XCHAL_HAVE_CLAMPS 1 /* CLAMPS instruction */
|
||||
#define XCHAL_HAVE_MUL16 1 /* MUL16S/MUL16U instructions */
|
||||
#define XCHAL_HAVE_MUL32 1 /* MULL instruction */
|
||||
#define XCHAL_HAVE_MUL32_HIGH 0 /* MULUH/MULSH instructions */
|
||||
#define XCHAL_HAVE_DIV32 1 /* QUOS/QUOU/REMS/REMU insns */
|
||||
#define XCHAL_HAVE_L32R 1 /* L32R instruction */
|
||||
#define XCHAL_HAVE_ABSOLUTE_LITERALS 1 /* non-PC-rel (extended) L32R */
|
||||
#define XCHAL_HAVE_CONST16 0 /* CONST16 instruction */
|
||||
#define XCHAL_HAVE_ADDX 1 /* ADDX#/SUBX# instructions */
|
||||
#define XCHAL_HAVE_WIDE_BRANCHES 0 /* B*.W18 or B*.W15 instr's */
|
||||
#define XCHAL_HAVE_PREDICTED_BRANCHES 0 /* B[EQ/EQZ/NE/NEZ]T instr's */
|
||||
#define XCHAL_HAVE_CALL4AND12 1 /* (obsolete option) */
|
||||
#define XCHAL_HAVE_ABS 1 /* ABS instruction */
|
||||
/*#define XCHAL_HAVE_POPC 0*/ /* POPC instruction */
|
||||
/*#define XCHAL_HAVE_CRC 0*/ /* CRC instruction */
|
||||
#define XCHAL_HAVE_RELEASE_SYNC 1 /* L32AI/S32RI instructions */
|
||||
#define XCHAL_HAVE_S32C1I 1 /* S32C1I instruction */
|
||||
#define XCHAL_HAVE_SPECULATION 0 /* speculation */
|
||||
#define XCHAL_HAVE_FULL_RESET 1 /* all regs/state reset */
|
||||
#define XCHAL_NUM_CONTEXTS 1 /* */
|
||||
#define XCHAL_NUM_MISC_REGS 2 /* num of scratch regs (0..4) */
|
||||
#define XCHAL_HAVE_TAP_MASTER 0 /* JTAG TAP control instr's */
|
||||
#define XCHAL_HAVE_PRID 1 /* processor ID register */
|
||||
#define XCHAL_HAVE_THREADPTR 1 /* THREADPTR register */
|
||||
#define XCHAL_HAVE_BOOLEANS 0 /* boolean registers */
|
||||
#define XCHAL_HAVE_CP 1 /* CPENABLE reg (coprocessor) */
|
||||
#define XCHAL_CP_MAXCFG 8 /* max allowed cp id plus one */
|
||||
#define XCHAL_HAVE_MAC16 1 /* MAC16 package */
|
||||
#define XCHAL_HAVE_VECTORFPU2005 0 /* vector floating-point pkg */
|
||||
#define XCHAL_HAVE_FP 0 /* floating point pkg */
|
||||
#define XCHAL_HAVE_VECTRA1 0 /* Vectra I pkg */
|
||||
#define XCHAL_HAVE_VECTRALX 0 /* Vectra LX pkg */
|
||||
#define XCHAL_HAVE_HIFI2 0 /* HiFi2 Audio Engine pkg */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
MISC
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_NUM_WRITEBUFFER_ENTRIES 8 /* size of write buffer */
|
||||
#define XCHAL_INST_FETCH_WIDTH 4 /* instr-fetch width in bytes */
|
||||
#define XCHAL_DATA_WIDTH 4 /* data width in bytes */
|
||||
/* In T1050, applies to selected core load and store instructions (see ISA): */
|
||||
#define XCHAL_UNALIGNED_LOAD_EXCEPTION 1 /* unaligned loads cause exc. */
|
||||
#define XCHAL_UNALIGNED_STORE_EXCEPTION 1 /* unaligned stores cause exc.*/
|
||||
|
||||
#define XCHAL_SW_VERSION 701001 /* sw version of this header */
|
||||
|
||||
#define XCHAL_CORE_ID "dc232b" /* alphanum core name
|
||||
(CoreID) set in the Xtensa
|
||||
Processor Generator */
|
||||
|
||||
#define XCHAL_CORE_DESCRIPTION "Diamond 232L Standard Core Rev.B (LE)"
|
||||
#define XCHAL_BUILD_UNIQUE_ID 0x0000BEEF /* 22-bit sw build ID */
|
||||
|
||||
/*
|
||||
* These definitions describe the hardware targeted by this software.
|
||||
*/
|
||||
#define XCHAL_HW_CONFIGID0 0xC56307FE /* ConfigID hi 32 bits*/
|
||||
#define XCHAL_HW_CONFIGID1 0x0D40BEEF /* ConfigID lo 32 bits*/
|
||||
#define XCHAL_HW_VERSION_NAME "LX2.1.1" /* full version name */
|
||||
#define XCHAL_HW_VERSION_MAJOR 2210 /* major ver# of targeted hw */
|
||||
#define XCHAL_HW_VERSION_MINOR 1 /* minor ver# of targeted hw */
|
||||
#define XCHAL_HW_VERSION 221001 /* major*100+minor */
|
||||
#define XCHAL_HW_REL_LX2 1
|
||||
#define XCHAL_HW_REL_LX2_1 1
|
||||
#define XCHAL_HW_REL_LX2_1_1 1
|
||||
#define XCHAL_HW_CONFIGID_RELIABLE 1
|
||||
/* If software targets a *range* of hardware versions, these are the bounds: */
|
||||
#define XCHAL_HW_MIN_VERSION_MAJOR 2210 /* major v of earliest tgt hw */
|
||||
#define XCHAL_HW_MIN_VERSION_MINOR 1 /* minor v of earliest tgt hw */
|
||||
#define XCHAL_HW_MIN_VERSION 221001 /* earliest targeted hw */
|
||||
#define XCHAL_HW_MAX_VERSION_MAJOR 2210 /* major v of latest tgt hw */
|
||||
#define XCHAL_HW_MAX_VERSION_MINOR 1 /* minor v of latest tgt hw */
|
||||
#define XCHAL_HW_MAX_VERSION 221001 /* latest targeted hw */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
CACHE
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_ICACHE_LINESIZE 32 /* I-cache line size in bytes */
|
||||
#define XCHAL_DCACHE_LINESIZE 32 /* D-cache line size in bytes */
|
||||
#define XCHAL_ICACHE_LINEWIDTH 5 /* log2(I line size in bytes) */
|
||||
#define XCHAL_DCACHE_LINEWIDTH 5 /* log2(D line size in bytes) */
|
||||
|
||||
#define XCHAL_ICACHE_SIZE 16384 /* I-cache size in bytes or 0 */
|
||||
#define XCHAL_DCACHE_SIZE 16384 /* D-cache size in bytes or 0 */
|
||||
|
||||
#define XCHAL_DCACHE_IS_WRITEBACK 1 /* writeback feature */
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
CACHE
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_HAVE_PIF 1 /* any outbound PIF present */
|
||||
|
||||
/* If present, cache size in bytes == (ways * 2^(linewidth + setwidth)). */
|
||||
|
||||
/* Number of cache sets in log2(lines per way): */
|
||||
#define XCHAL_ICACHE_SETWIDTH 7
|
||||
#define XCHAL_DCACHE_SETWIDTH 7
|
||||
|
||||
/* Cache set associativity (number of ways): */
|
||||
#define XCHAL_ICACHE_WAYS 4
|
||||
#define XCHAL_DCACHE_WAYS 4
|
||||
|
||||
/* Cache features: */
|
||||
#define XCHAL_ICACHE_LINE_LOCKABLE 1
|
||||
#define XCHAL_DCACHE_LINE_LOCKABLE 1
|
||||
#define XCHAL_ICACHE_ECC_PARITY 0
|
||||
#define XCHAL_DCACHE_ECC_PARITY 0
|
||||
|
||||
/* Number of encoded cache attr bits (see <xtensa/hal.h> for decoded bits): */
|
||||
#define XCHAL_CA_BITS 4
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
INTERNAL I/D RAM/ROMs and XLMI
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_NUM_INSTROM 0 /* number of core instr. ROMs */
|
||||
#define XCHAL_NUM_INSTRAM 0 /* number of core instr. RAMs */
|
||||
#define XCHAL_NUM_DATAROM 0 /* number of core data ROMs */
|
||||
#define XCHAL_NUM_DATARAM 0 /* number of core data RAMs */
|
||||
#define XCHAL_NUM_URAM 0 /* number of core unified RAMs*/
|
||||
#define XCHAL_NUM_XLMI 0 /* number of core XLMI ports */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
INTERRUPTS and TIMERS
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_HAVE_INTERRUPTS 1 /* interrupt option */
|
||||
#define XCHAL_HAVE_HIGHPRI_INTERRUPTS 1 /* med/high-pri. interrupts */
|
||||
#define XCHAL_HAVE_NMI 1 /* non-maskable interrupt */
|
||||
#define XCHAL_HAVE_CCOUNT 1 /* CCOUNT reg. (timer option) */
|
||||
#define XCHAL_NUM_TIMERS 3 /* number of CCOMPAREn regs */
|
||||
#define XCHAL_NUM_INTERRUPTS 22 /* number of interrupts */
|
||||
#define XCHAL_NUM_INTERRUPTS_LOG2 5 /* ceil(log2(NUM_INTERRUPTS)) */
|
||||
#define XCHAL_NUM_EXTINTERRUPTS 17 /* num of external interrupts */
|
||||
#define XCHAL_NUM_INTLEVELS 6 /* number of interrupt levels
|
||||
(not including level zero) */
|
||||
#define XCHAL_EXCM_LEVEL 3 /* level masked by PS.EXCM */
|
||||
/* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */
|
||||
|
||||
/* Masks of interrupts at each interrupt level: */
|
||||
#define XCHAL_INTLEVEL1_MASK 0x001F80FF
|
||||
#define XCHAL_INTLEVEL2_MASK 0x00000100
|
||||
#define XCHAL_INTLEVEL3_MASK 0x00200E00
|
||||
#define XCHAL_INTLEVEL4_MASK 0x00001000
|
||||
#define XCHAL_INTLEVEL5_MASK 0x00002000
|
||||
#define XCHAL_INTLEVEL6_MASK 0x00000000
|
||||
#define XCHAL_INTLEVEL7_MASK 0x00004000
|
||||
|
||||
/* Masks of interrupts at each range 1..n of interrupt levels: */
|
||||
#define XCHAL_INTLEVEL1_ANDBELOW_MASK 0x001F80FF
|
||||
#define XCHAL_INTLEVEL2_ANDBELOW_MASK 0x001F81FF
|
||||
#define XCHAL_INTLEVEL3_ANDBELOW_MASK 0x003F8FFF
|
||||
#define XCHAL_INTLEVEL4_ANDBELOW_MASK 0x003F9FFF
|
||||
#define XCHAL_INTLEVEL5_ANDBELOW_MASK 0x003FBFFF
|
||||
#define XCHAL_INTLEVEL6_ANDBELOW_MASK 0x003FBFFF
|
||||
#define XCHAL_INTLEVEL7_ANDBELOW_MASK 0x003FFFFF
|
||||
|
||||
/* Level of each interrupt: */
|
||||
#define XCHAL_INT0_LEVEL 1
|
||||
#define XCHAL_INT1_LEVEL 1
|
||||
#define XCHAL_INT2_LEVEL 1
|
||||
#define XCHAL_INT3_LEVEL 1
|
||||
#define XCHAL_INT4_LEVEL 1
|
||||
#define XCHAL_INT5_LEVEL 1
|
||||
#define XCHAL_INT6_LEVEL 1
|
||||
#define XCHAL_INT7_LEVEL 1
|
||||
#define XCHAL_INT8_LEVEL 2
|
||||
#define XCHAL_INT9_LEVEL 3
|
||||
#define XCHAL_INT10_LEVEL 3
|
||||
#define XCHAL_INT11_LEVEL 3
|
||||
#define XCHAL_INT12_LEVEL 4
|
||||
#define XCHAL_INT13_LEVEL 5
|
||||
#define XCHAL_INT14_LEVEL 7
|
||||
#define XCHAL_INT15_LEVEL 1
|
||||
#define XCHAL_INT16_LEVEL 1
|
||||
#define XCHAL_INT17_LEVEL 1
|
||||
#define XCHAL_INT18_LEVEL 1
|
||||
#define XCHAL_INT19_LEVEL 1
|
||||
#define XCHAL_INT20_LEVEL 1
|
||||
#define XCHAL_INT21_LEVEL 3
|
||||
#define XCHAL_DEBUGLEVEL 6 /* debug interrupt level */
|
||||
#define XCHAL_HAVE_DEBUG_EXTERN_INT 1 /* OCD external db interrupt */
|
||||
#define XCHAL_NMILEVEL 7 /* NMI "level" (for use with
|
||||
EXCSAVE/EPS/EPC_n, RFI n) */
|
||||
|
||||
/* Type of each interrupt: */
|
||||
#define XCHAL_INT0_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT1_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT2_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT3_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT4_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT5_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT6_TYPE XTHAL_INTTYPE_TIMER
|
||||
#define XCHAL_INT7_TYPE XTHAL_INTTYPE_SOFTWARE
|
||||
#define XCHAL_INT8_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT9_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT10_TYPE XTHAL_INTTYPE_TIMER
|
||||
#define XCHAL_INT11_TYPE XTHAL_INTTYPE_SOFTWARE
|
||||
#define XCHAL_INT12_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT13_TYPE XTHAL_INTTYPE_TIMER
|
||||
#define XCHAL_INT14_TYPE XTHAL_INTTYPE_NMI
|
||||
#define XCHAL_INT15_TYPE XTHAL_INTTYPE_EXTERN_EDGE
|
||||
#define XCHAL_INT16_TYPE XTHAL_INTTYPE_EXTERN_EDGE
|
||||
#define XCHAL_INT17_TYPE XTHAL_INTTYPE_EXTERN_EDGE
|
||||
#define XCHAL_INT18_TYPE XTHAL_INTTYPE_EXTERN_EDGE
|
||||
#define XCHAL_INT19_TYPE XTHAL_INTTYPE_EXTERN_EDGE
|
||||
#define XCHAL_INT20_TYPE XTHAL_INTTYPE_EXTERN_EDGE
|
||||
#define XCHAL_INT21_TYPE XTHAL_INTTYPE_EXTERN_EDGE
|
||||
|
||||
/* Masks of interrupts for each type of interrupt: */
|
||||
#define XCHAL_INTTYPE_MASK_UNCONFIGURED 0xFFC00000
|
||||
#define XCHAL_INTTYPE_MASK_SOFTWARE 0x00000880
|
||||
#define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x003F8000
|
||||
#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL 0x0000133F
|
||||
#define XCHAL_INTTYPE_MASK_TIMER 0x00002440
|
||||
#define XCHAL_INTTYPE_MASK_NMI 0x00004000
|
||||
#define XCHAL_INTTYPE_MASK_WRITE_ERROR 0x00000000
|
||||
|
||||
/* Interrupt numbers assigned to specific interrupt sources: */
|
||||
#define XCHAL_TIMER0_INTERRUPT 6 /* CCOMPARE0 */
|
||||
#define XCHAL_TIMER1_INTERRUPT 10 /* CCOMPARE1 */
|
||||
#define XCHAL_TIMER2_INTERRUPT 13 /* CCOMPARE2 */
|
||||
#define XCHAL_TIMER3_INTERRUPT XTHAL_TIMER_UNCONFIGURED
|
||||
#define XCHAL_NMI_INTERRUPT 14 /* non-maskable interrupt */
|
||||
|
||||
/* Interrupt numbers for levels at which only one interrupt is configured: */
|
||||
#define XCHAL_INTLEVEL2_NUM 8
|
||||
#define XCHAL_INTLEVEL4_NUM 12
|
||||
#define XCHAL_INTLEVEL5_NUM 13
|
||||
#define XCHAL_INTLEVEL7_NUM 14
|
||||
/* (There are many interrupts each at level(s) 1, 3.) */
|
||||
|
||||
|
||||
/*
|
||||
* External interrupt vectors/levels.
|
||||
* These macros describe how Xtensa processor interrupt numbers
|
||||
* (as numbered internally, eg. in INTERRUPT and INTENABLE registers)
|
||||
* map to external BInterrupt<n> pins, for those interrupts
|
||||
* configured as external (level-triggered, edge-triggered, or NMI).
|
||||
* See the Xtensa processor databook for more details.
|
||||
*/
|
||||
|
||||
/* Core interrupt numbers mapped to each EXTERNAL interrupt number: */
|
||||
#define XCHAL_EXTINT0_NUM 0 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT1_NUM 1 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT2_NUM 2 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT3_NUM 3 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT4_NUM 4 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT5_NUM 5 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT6_NUM 8 /* (intlevel 2) */
|
||||
#define XCHAL_EXTINT7_NUM 9 /* (intlevel 3) */
|
||||
#define XCHAL_EXTINT8_NUM 12 /* (intlevel 4) */
|
||||
#define XCHAL_EXTINT9_NUM 14 /* (intlevel 7) */
|
||||
#define XCHAL_EXTINT10_NUM 15 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT11_NUM 16 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT12_NUM 17 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT13_NUM 18 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT14_NUM 19 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT15_NUM 20 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT16_NUM 21 /* (intlevel 3) */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
EXCEPTIONS and VECTORS
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_XEA_VERSION 2 /* Xtensa Exception Architecture
|
||||
number: 1 == XEA1 (old)
|
||||
2 == XEA2 (new)
|
||||
0 == XEAX (extern) */
|
||||
#define XCHAL_HAVE_XEA1 0 /* Exception Architecture 1 */
|
||||
#define XCHAL_HAVE_XEA2 1 /* Exception Architecture 2 */
|
||||
#define XCHAL_HAVE_XEAX 0 /* External Exception Arch. */
|
||||
#define XCHAL_HAVE_EXCEPTIONS 1 /* exception option */
|
||||
#define XCHAL_HAVE_MEM_ECC_PARITY 0 /* local memory ECC/parity */
|
||||
#define XCHAL_HAVE_VECTOR_SELECT 1 /* relocatable vectors */
|
||||
#define XCHAL_HAVE_VECBASE 1 /* relocatable vectors */
|
||||
#define XCHAL_VECBASE_RESET_VADDR 0xD0000000 /* VECBASE reset value */
|
||||
#define XCHAL_VECBASE_RESET_PADDR 0x00000000
|
||||
#define XCHAL_RESET_VECBASE_OVERLAP 0
|
||||
|
||||
#define XCHAL_RESET_VECTOR0_VADDR 0xFE000000
|
||||
#define XCHAL_RESET_VECTOR0_PADDR 0xFE000000
|
||||
#define XCHAL_RESET_VECTOR1_VADDR 0xD8000500
|
||||
#define XCHAL_RESET_VECTOR1_PADDR 0x00000500
|
||||
#define XCHAL_RESET_VECTOR_VADDR 0xFE000000
|
||||
#define XCHAL_RESET_VECTOR_PADDR 0xFE000000
|
||||
#define XCHAL_USER_VECOFS 0x00000340
|
||||
#define XCHAL_USER_VECTOR_VADDR 0xD0000340
|
||||
#define XCHAL_USER_VECTOR_PADDR 0x00000340
|
||||
#define XCHAL_KERNEL_VECOFS 0x00000300
|
||||
#define XCHAL_KERNEL_VECTOR_VADDR 0xD0000300
|
||||
#define XCHAL_KERNEL_VECTOR_PADDR 0x00000300
|
||||
#define XCHAL_DOUBLEEXC_VECOFS 0x000003C0
|
||||
#define XCHAL_DOUBLEEXC_VECTOR_VADDR 0xD00003C0
|
||||
#define XCHAL_DOUBLEEXC_VECTOR_PADDR 0x000003C0
|
||||
#define XCHAL_WINDOW_OF4_VECOFS 0x00000000
|
||||
#define XCHAL_WINDOW_UF4_VECOFS 0x00000040
|
||||
#define XCHAL_WINDOW_OF8_VECOFS 0x00000080
|
||||
#define XCHAL_WINDOW_UF8_VECOFS 0x000000C0
|
||||
#define XCHAL_WINDOW_OF12_VECOFS 0x00000100
|
||||
#define XCHAL_WINDOW_UF12_VECOFS 0x00000140
|
||||
#define XCHAL_WINDOW_VECTORS_VADDR 0xD0000000
|
||||
#define XCHAL_WINDOW_VECTORS_PADDR 0x00000000
|
||||
#define XCHAL_INTLEVEL2_VECOFS 0x00000180
|
||||
#define XCHAL_INTLEVEL2_VECTOR_VADDR 0xD0000180
|
||||
#define XCHAL_INTLEVEL2_VECTOR_PADDR 0x00000180
|
||||
#define XCHAL_INTLEVEL3_VECOFS 0x000001C0
|
||||
#define XCHAL_INTLEVEL3_VECTOR_VADDR 0xD00001C0
|
||||
#define XCHAL_INTLEVEL3_VECTOR_PADDR 0x000001C0
|
||||
#define XCHAL_INTLEVEL4_VECOFS 0x00000200
|
||||
#define XCHAL_INTLEVEL4_VECTOR_VADDR 0xD0000200
|
||||
#define XCHAL_INTLEVEL4_VECTOR_PADDR 0x00000200
|
||||
#define XCHAL_INTLEVEL5_VECOFS 0x00000240
|
||||
#define XCHAL_INTLEVEL5_VECTOR_VADDR 0xD0000240
|
||||
#define XCHAL_INTLEVEL5_VECTOR_PADDR 0x00000240
|
||||
#define XCHAL_INTLEVEL6_VECOFS 0x00000280
|
||||
#define XCHAL_INTLEVEL6_VECTOR_VADDR 0xD0000280
|
||||
#define XCHAL_INTLEVEL6_VECTOR_PADDR 0x00000280
|
||||
#define XCHAL_DEBUG_VECOFS XCHAL_INTLEVEL6_VECOFS
|
||||
#define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL6_VECTOR_VADDR
|
||||
#define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL6_VECTOR_PADDR
|
||||
#define XCHAL_NMI_VECOFS 0x000002C0
|
||||
#define XCHAL_NMI_VECTOR_VADDR 0xD00002C0
|
||||
#define XCHAL_NMI_VECTOR_PADDR 0x000002C0
|
||||
#define XCHAL_INTLEVEL7_VECOFS XCHAL_NMI_VECOFS
|
||||
#define XCHAL_INTLEVEL7_VECTOR_VADDR XCHAL_NMI_VECTOR_VADDR
|
||||
#define XCHAL_INTLEVEL7_VECTOR_PADDR XCHAL_NMI_VECTOR_PADDR
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
DEBUG
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_HAVE_OCD 1 /* OnChipDebug option */
|
||||
#define XCHAL_NUM_IBREAK 2 /* number of IBREAKn regs */
|
||||
#define XCHAL_NUM_DBREAK 2 /* number of DBREAKn regs */
|
||||
#define XCHAL_HAVE_OCD_DIR_ARRAY 1 /* faster OCD option */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
MMU
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
/* See core-matmap.h header file for more details. */
|
||||
|
||||
#define XCHAL_HAVE_TLBS 1 /* inverse of HAVE_CACHEATTR */
|
||||
#define XCHAL_HAVE_SPANNING_WAY 0 /* one way maps I+D 4GB vaddr */
|
||||
#define XCHAL_HAVE_IDENTITY_MAP 0 /* vaddr == paddr always */
|
||||
#define XCHAL_HAVE_CACHEATTR 0 /* CACHEATTR register present */
|
||||
#define XCHAL_HAVE_MIMIC_CACHEATTR 0 /* region protection */
|
||||
#define XCHAL_HAVE_XLT_CACHEATTR 0 /* region prot. w/translation */
|
||||
#define XCHAL_HAVE_PTP_MMU 1 /* full MMU (with page table
|
||||
[autorefill] and protection)
|
||||
usable for an MMU-based OS */
|
||||
/* If none of the above last 4 are set, it's a custom TLB configuration. */
|
||||
#define XCHAL_ITLB_ARF_ENTRIES_LOG2 2 /* log2(autorefill way size) */
|
||||
#define XCHAL_DTLB_ARF_ENTRIES_LOG2 2 /* log2(autorefill way size) */
|
||||
|
||||
#define XCHAL_MMU_ASID_BITS 8 /* number of bits in ASIDs */
|
||||
#define XCHAL_MMU_RINGS 4 /* number of rings (1..4) */
|
||||
#define XCHAL_MMU_RING_BITS 2 /* num of bits in RING field */
|
||||
|
||||
#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */
|
||||
|
||||
|
||||
#endif /* XTENSA_DC232B_CORE_ISA_H */
|
261
target/xtensa/core-dc232b/gdb-config.c
Normal file
261
target/xtensa/core-dc232b/gdb-config.c
Normal file
|
@ -0,0 +1,261 @@
|
|||
/* Configuration for the Xtensa architecture for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
XTREG(0, 0, 32, 4, 4, 0x0020, 0x0006, -2, 9, 0x0100, pc,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(1, 4, 32, 4, 4, 0x0100, 0x0006, -2, 1, 0x0002, ar0,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(2, 8, 32, 4, 4, 0x0101, 0x0006, -2, 1, 0x0002, ar1,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(3, 12, 32, 4, 4, 0x0102, 0x0006, -2, 1, 0x0002, ar2,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(4, 16, 32, 4, 4, 0x0103, 0x0006, -2, 1, 0x0002, ar3,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(5, 20, 32, 4, 4, 0x0104, 0x0006, -2, 1, 0x0002, ar4,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(6, 24, 32, 4, 4, 0x0105, 0x0006, -2, 1, 0x0002, ar5,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(7, 28, 32, 4, 4, 0x0106, 0x0006, -2, 1, 0x0002, ar6,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(8, 32, 32, 4, 4, 0x0107, 0x0006, -2, 1, 0x0002, ar7,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(9, 36, 32, 4, 4, 0x0108, 0x0006, -2, 1, 0x0002, ar8,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(10, 40, 32, 4, 4, 0x0109, 0x0006, -2, 1, 0x0002, ar9,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(11, 44, 32, 4, 4, 0x010a, 0x0006, -2, 1, 0x0002, ar10,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(12, 48, 32, 4, 4, 0x010b, 0x0006, -2, 1, 0x0002, ar11,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(13, 52, 32, 4, 4, 0x010c, 0x0006, -2, 1, 0x0002, ar12,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(14, 56, 32, 4, 4, 0x010d, 0x0006, -2, 1, 0x0002, ar13,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(15, 60, 32, 4, 4, 0x010e, 0x0006, -2, 1, 0x0002, ar14,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(16, 64, 32, 4, 4, 0x010f, 0x0006, -2, 1, 0x0002, ar15,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(17, 68, 32, 4, 4, 0x0110, 0x0006, -2, 1, 0x0002, ar16,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(18, 72, 32, 4, 4, 0x0111, 0x0006, -2, 1, 0x0002, ar17,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(19, 76, 32, 4, 4, 0x0112, 0x0006, -2, 1, 0x0002, ar18,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(20, 80, 32, 4, 4, 0x0113, 0x0006, -2, 1, 0x0002, ar19,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(21, 84, 32, 4, 4, 0x0114, 0x0006, -2, 1, 0x0002, ar20,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(22, 88, 32, 4, 4, 0x0115, 0x0006, -2, 1, 0x0002, ar21,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(23, 92, 32, 4, 4, 0x0116, 0x0006, -2, 1, 0x0002, ar22,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(24, 96, 32, 4, 4, 0x0117, 0x0006, -2, 1, 0x0002, ar23,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(25, 100, 32, 4, 4, 0x0118, 0x0006, -2, 1, 0x0002, ar24,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(26, 104, 32, 4, 4, 0x0119, 0x0006, -2, 1, 0x0002, ar25,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(27, 108, 32, 4, 4, 0x011a, 0x0006, -2, 1, 0x0002, ar26,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(28, 112, 32, 4, 4, 0x011b, 0x0006, -2, 1, 0x0002, ar27,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(29, 116, 32, 4, 4, 0x011c, 0x0006, -2, 1, 0x0002, ar28,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(30, 120, 32, 4, 4, 0x011d, 0x0006, -2, 1, 0x0002, ar29,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(31, 124, 32, 4, 4, 0x011e, 0x0006, -2, 1, 0x0002, ar30,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(32, 128, 32, 4, 4, 0x011f, 0x0006, -2, 1, 0x0002, ar31,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(33, 132, 32, 4, 4, 0x0200, 0x0006, -2, 2, 0x1100, lbeg,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(34, 136, 32, 4, 4, 0x0201, 0x0006, -2, 2, 0x1100, lend,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(35, 140, 32, 4, 4, 0x0202, 0x0006, -2, 2, 0x1100, lcount,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(36, 144, 6, 4, 4, 0x0203, 0x0006, -2, 2, 0x1100, sar,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(37, 148, 32, 4, 4, 0x0205, 0x0006, -2, 2, 0x1100, litbase,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(38, 152, 3, 4, 4, 0x0248, 0x0006, -2, 2, 0x1002, windowbase,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(39, 156, 8, 4, 4, 0x0249, 0x0006, -2, 2, 0x1002, windowstart,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(40, 160, 32, 4, 4, 0x02b0, 0x0002, -2, 2, 0x1000, sr176,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(41, 164, 32, 4, 4, 0x02d0, 0x0002, -2, 2, 0x1000, sr208,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(42, 168, 19, 4, 4, 0x02e6, 0x0006, -2, 2, 0x1100, ps,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(43, 172, 32, 4, 4, 0x03e7, 0x0006, -2, 3, 0x0110, threadptr,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(44, 176, 32, 4, 4, 0x020c, 0x0006, -1, 2, 0x1100, scompare1,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(45, 180, 32, 4, 4, 0x0210, 0x0006, -1, 2, 0x1100, acclo,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(46, 184, 8, 4, 4, 0x0211, 0x0006, -1, 2, 0x1100, acchi,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(47, 188, 32, 4, 4, 0x0220, 0x0006, -1, 2, 0x1100, m0,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(48, 192, 32, 4, 4, 0x0221, 0x0006, -1, 2, 0x1100, m1,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(49, 196, 32, 4, 4, 0x0222, 0x0006, -1, 2, 0x1100, m2,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(50, 200, 32, 4, 4, 0x0223, 0x0006, -1, 2, 0x1100, m3,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(51, 204, 32, 4, 4, 0x03e6, 0x000e, -1, 3, 0x0110, expstate,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(52, 208, 32, 4, 4, 0x0253, 0x0007, -2, 2, 0x1000, ptevaddr,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(53, 212, 32, 4, 4, 0x0259, 0x000d, -2, 2, 0x1000, mmid,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(54, 216, 32, 4, 4, 0x025a, 0x0007, -2, 2, 0x1000, rasid,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(55, 220, 18, 4, 4, 0x025b, 0x0007, -2, 2, 0x1000, itlbcfg,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(56, 224, 18, 4, 4, 0x025c, 0x0007, -2, 2, 0x1000, dtlbcfg,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(57, 228, 2, 4, 4, 0x0260, 0x0007, -2, 2, 0x1000, ibreakenable,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(58, 232, 32, 4, 4, 0x0268, 0x0007, -2, 2, 0x1000, ddr,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(59, 236, 32, 4, 4, 0x0280, 0x0007, -2, 2, 0x1000, ibreaka0,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(60, 240, 32, 4, 4, 0x0281, 0x0007, -2, 2, 0x1000, ibreaka1,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(61, 244, 32, 4, 4, 0x0290, 0x0007, -2, 2, 0x1000, dbreaka0,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(62, 248, 32, 4, 4, 0x0291, 0x0007, -2, 2, 0x1000, dbreaka1,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(63, 252, 32, 4, 4, 0x02a0, 0x0007, -2, 2, 0x1000, dbreakc0,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(64, 256, 32, 4, 4, 0x02a1, 0x0007, -2, 2, 0x1000, dbreakc1,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(65, 260, 32, 4, 4, 0x02b1, 0x0007, -2, 2, 0x1000, epc1,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(66, 264, 32, 4, 4, 0x02b2, 0x0007, -2, 2, 0x1000, epc2,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(67, 268, 32, 4, 4, 0x02b3, 0x0007, -2, 2, 0x1000, epc3,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(68, 272, 32, 4, 4, 0x02b4, 0x0007, -2, 2, 0x1000, epc4,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(69, 276, 32, 4, 4, 0x02b5, 0x0007, -2, 2, 0x1000, epc5,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(70, 280, 32, 4, 4, 0x02b6, 0x0007, -2, 2, 0x1000, epc6,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(71, 284, 32, 4, 4, 0x02b7, 0x0007, -2, 2, 0x1000, epc7,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(72, 288, 32, 4, 4, 0x02c0, 0x0007, -2, 2, 0x1000, depc,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(73, 292, 19, 4, 4, 0x02c2, 0x0007, -2, 2, 0x1000, eps2,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(74, 296, 19, 4, 4, 0x02c3, 0x0007, -2, 2, 0x1000, eps3,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(75, 300, 19, 4, 4, 0x02c4, 0x0007, -2, 2, 0x1000, eps4,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(76, 304, 19, 4, 4, 0x02c5, 0x0007, -2, 2, 0x1000, eps5,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(77, 308, 19, 4, 4, 0x02c6, 0x0007, -2, 2, 0x1000, eps6,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(78, 312, 19, 4, 4, 0x02c7, 0x0007, -2, 2, 0x1000, eps7,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(79, 316, 32, 4, 4, 0x02d1, 0x0007, -2, 2, 0x1000, excsave1,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(80, 320, 32, 4, 4, 0x02d2, 0x0007, -2, 2, 0x1000, excsave2,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(81, 324, 32, 4, 4, 0x02d3, 0x0007, -2, 2, 0x1000, excsave3,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(82, 328, 32, 4, 4, 0x02d4, 0x0007, -2, 2, 0x1000, excsave4,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(83, 332, 32, 4, 4, 0x02d5, 0x0007, -2, 2, 0x1000, excsave5,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(84, 336, 32, 4, 4, 0x02d6, 0x0007, -2, 2, 0x1000, excsave6,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(85, 340, 32, 4, 4, 0x02d7, 0x0007, -2, 2, 0x1000, excsave7,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(86, 344, 8, 4, 4, 0x02e0, 0x0007, -2, 2, 0x1000, cpenable,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(87, 348, 22, 4, 4, 0x02e2, 0x000b, -2, 2, 0x1000, interrupt,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(88, 352, 22, 4, 4, 0x02e2, 0x000d, -2, 2, 0x1000, intset,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(89, 356, 22, 4, 4, 0x02e3, 0x000d, -2, 2, 0x1000, intclear,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(90, 360, 22, 4, 4, 0x02e4, 0x0007, -2, 2, 0x1000, intenable,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(91, 364, 32, 4, 4, 0x02e7, 0x0007, -2, 2, 0x1000, vecbase,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(92, 368, 6, 4, 4, 0x02e8, 0x0007, -2, 2, 0x1000, exccause,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(93, 372, 12, 4, 4, 0x02e9, 0x0003, -2, 2, 0x1000, debugcause,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(94, 376, 32, 4, 4, 0x02ea, 0x000f, -2, 2, 0x1000, ccount,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(95, 380, 32, 4, 4, 0x02eb, 0x0003, -2, 2, 0x1000, prid,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(96, 384, 32, 4, 4, 0x02ec, 0x000f, -2, 2, 0x1000, icount,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(97, 388, 4, 4, 4, 0x02ed, 0x0007, -2, 2, 0x1000, icountlevel,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(98, 392, 32, 4, 4, 0x02ee, 0x0007, -2, 2, 0x1000, excvaddr,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(99, 396, 32, 4, 4, 0x02f0, 0x000f, -2, 2, 0x1000, ccompare0,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(100, 400, 32, 4, 4, 0x02f1, 0x000f, -2, 2, 0x1000, ccompare1,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(101, 404, 32, 4, 4, 0x02f2, 0x000f, -2, 2, 0x1000, ccompare2,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(102, 408, 32, 4, 4, 0x02f4, 0x0007, -2, 2, 0x1000, misc0,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(103, 412, 32, 4, 4, 0x02f5, 0x0007, -2, 2, 0x1000, misc1,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(104, 416, 32, 4, 4, 0x0000, 0x0006, -2, 8, 0x0100, a0,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(105, 420, 32, 4, 4, 0x0001, 0x0006, -2, 8, 0x0100, a1,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(106, 424, 32, 4, 4, 0x0002, 0x0006, -2, 8, 0x0100, a2,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(107, 428, 32, 4, 4, 0x0003, 0x0006, -2, 8, 0x0100, a3,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(108, 432, 32, 4, 4, 0x0004, 0x0006, -2, 8, 0x0100, a4,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(109, 436, 32, 4, 4, 0x0005, 0x0006, -2, 8, 0x0100, a5,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(110, 440, 32, 4, 4, 0x0006, 0x0006, -2, 8, 0x0100, a6,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(111, 444, 32, 4, 4, 0x0007, 0x0006, -2, 8, 0x0100, a7,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(112, 448, 32, 4, 4, 0x0008, 0x0006, -2, 8, 0x0100, a8,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(113, 452, 32, 4, 4, 0x0009, 0x0006, -2, 8, 0x0100, a9,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(114, 456, 32, 4, 4, 0x000a, 0x0006, -2, 8, 0x0100, a10,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(115, 460, 32, 4, 4, 0x000b, 0x0006, -2, 8, 0x0100, a11,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(116, 464, 32, 4, 4, 0x000c, 0x0006, -2, 8, 0x0100, a12,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(117, 468, 32, 4, 4, 0x000d, 0x0006, -2, 8, 0x0100, a13,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(118, 472, 32, 4, 4, 0x000e, 0x0006, -2, 8, 0x0100, a14,
|
||||
0, 0, 0, 0, 0, 0)
|
||||
XTREG(119, 476, 32, 4, 4, 0x000f, 0x0006, -2, 8, 0x0100, a15,
|
||||
0, 0, 0, 0, 0, 0)
|
51
target/xtensa/core-dc233c.c
Normal file
51
target/xtensa/core-dc233c.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2012, Max Filippov, Open Source and Linux Lab.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of the Open Source and Linux Lab 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 COPYRIGHT HOLDERS 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "exec/gdbstub.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/host-utils.h"
|
||||
|
||||
#include "core-dc233c/core-isa.h"
|
||||
#include "overlay_tool.h"
|
||||
|
||||
static XtensaConfig dc233c __attribute__((unused)) = {
|
||||
.name = "dc233c",
|
||||
.gdb_regmap = {
|
||||
.num_regs = 121,
|
||||
.num_core_regs = 52,
|
||||
.reg = {
|
||||
#include "core-dc233c/gdb-config.c"
|
||||
}
|
||||
},
|
||||
.clock_freq_khz = 10000,
|
||||
DEFAULT_SECTIONS
|
||||
};
|
||||
|
||||
REGISTER_CORE(dc233c)
|
473
target/xtensa/core-dc233c/core-isa.h
Normal file
473
target/xtensa/core-dc233c/core-isa.h
Normal file
|
@ -0,0 +1,473 @@
|
|||
/*
|
||||
* xtensa/config/core-isa.h -- HAL definitions that are dependent on Xtensa
|
||||
* processor CORE configuration
|
||||
*
|
||||
* See <xtensa/config/core.h>, which includes this file, for more details.
|
||||
*/
|
||||
|
||||
/* Xtensa processor core configuration information.
|
||||
|
||||
Copyright (c) 1999-2010 Tensilica Inc.
|
||||
|
||||
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 XTENSA_DC233C_CORE_ISA_H
|
||||
#define XTENSA_DC233C_CORE_ISA_H
|
||||
|
||||
/****************************************************************************
|
||||
Parameters Useful for Any Code, USER or PRIVILEGED
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Note: Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is
|
||||
* configured, and a value of 0 otherwise. These macros are always defined.
|
||||
*/
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
ISA
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_HAVE_BE 0 /* big-endian byte ordering */
|
||||
#define XCHAL_HAVE_WINDOWED 1 /* windowed registers option */
|
||||
#define XCHAL_NUM_AREGS 32 /* num of physical addr regs */
|
||||
#define XCHAL_NUM_AREGS_LOG2 5 /* log2(XCHAL_NUM_AREGS) */
|
||||
#define XCHAL_MAX_INSTRUCTION_SIZE 3 /* max instr bytes (3..8) */
|
||||
#define XCHAL_HAVE_DEBUG 1 /* debug option */
|
||||
#define XCHAL_HAVE_DENSITY 1 /* 16-bit instructions */
|
||||
#define XCHAL_HAVE_LOOPS 1 /* zero-overhead loops */
|
||||
#define XCHAL_HAVE_NSA 1 /* NSA/NSAU instructions */
|
||||
#define XCHAL_HAVE_MINMAX 1 /* MIN/MAX instructions */
|
||||
#define XCHAL_HAVE_SEXT 1 /* SEXT instruction */
|
||||
#define XCHAL_HAVE_CLAMPS 1 /* CLAMPS instruction */
|
||||
#define XCHAL_HAVE_MUL16 1 /* MUL16S/MUL16U instructions */
|
||||
#define XCHAL_HAVE_MUL32 1 /* MULL instruction */
|
||||
#define XCHAL_HAVE_MUL32_HIGH 0 /* MULUH/MULSH instructions */
|
||||
#define XCHAL_HAVE_DIV32 1 /* QUOS/QUOU/REMS/REMU instructions */
|
||||
#define XCHAL_HAVE_L32R 1 /* L32R instruction */
|
||||
#define XCHAL_HAVE_ABSOLUTE_LITERALS 1 /* non-PC-rel (extended) L32R */
|
||||
#define XCHAL_HAVE_CONST16 0 /* CONST16 instruction */
|
||||
#define XCHAL_HAVE_ADDX 1 /* ADDX#/SUBX# instructions */
|
||||
#define XCHAL_HAVE_WIDE_BRANCHES 0 /* B*.W18 or B*.W15 instr's */
|
||||
#define XCHAL_HAVE_PREDICTED_BRANCHES 0 /* B[EQ/EQZ/NE/NEZ]T instr's */
|
||||
#define XCHAL_HAVE_CALL4AND12 1 /* (obsolete option) */
|
||||
#define XCHAL_HAVE_ABS 1 /* ABS instruction */
|
||||
/*#define XCHAL_HAVE_POPC 0*/ /* POPC instruction */
|
||||
/*#define XCHAL_HAVE_CRC 0*/ /* CRC instruction */
|
||||
#define XCHAL_HAVE_RELEASE_SYNC 1 /* L32AI/S32RI instructions */
|
||||
#define XCHAL_HAVE_S32C1I 1 /* S32C1I instruction */
|
||||
#define XCHAL_HAVE_SPECULATION 0 /* speculation */
|
||||
#define XCHAL_HAVE_FULL_RESET 1 /* all regs/state reset */
|
||||
#define XCHAL_NUM_CONTEXTS 1 /* */
|
||||
#define XCHAL_NUM_MISC_REGS 2 /* num of scratch regs (0..4) */
|
||||
#define XCHAL_HAVE_TAP_MASTER 0 /* JTAG TAP control instr's */
|
||||
#define XCHAL_HAVE_PRID 1 /* processor ID register */
|
||||
#define XCHAL_HAVE_EXTERN_REGS 1 /* WER/RER instructions */
|
||||
#define XCHAL_HAVE_MP_INTERRUPTS 0 /* interrupt distributor port */
|
||||
#define XCHAL_HAVE_MP_RUNSTALL 0 /* core RunStall control port */
|
||||
#define XCHAL_HAVE_THREADPTR 1 /* THREADPTR register */
|
||||
#define XCHAL_HAVE_BOOLEANS 0 /* boolean registers */
|
||||
#define XCHAL_HAVE_CP 1 /* CPENABLE reg (coprocessor) */
|
||||
#define XCHAL_CP_MAXCFG 8 /* max allowed cp id plus one */
|
||||
#define XCHAL_HAVE_MAC16 1 /* MAC16 package */
|
||||
#define XCHAL_HAVE_VECTORFPU2005 0 /* vector floating-point pkg */
|
||||
#define XCHAL_HAVE_FP 0 /* floating point pkg */
|
||||
#define XCHAL_HAVE_DFP 0 /* double precision FP pkg */
|
||||
#define XCHAL_HAVE_DFP_accel 0 /* double precision FP acceleration pkg */
|
||||
#define XCHAL_HAVE_VECTRA1 0 /* Vectra I pkg */
|
||||
#define XCHAL_HAVE_VECTRALX 0 /* Vectra LX pkg */
|
||||
#define XCHAL_HAVE_HIFIPRO 0 /* HiFiPro Audio Engine pkg */
|
||||
#define XCHAL_HAVE_HIFI2 0 /* HiFi2 Audio Engine pkg */
|
||||
#define XCHAL_HAVE_HIFI2EP 0 /* HiFi2EP */
|
||||
#define XCHAL_HAVE_CONNXD2 0 /* ConnX D2 pkg */
|
||||
#define XCHAL_HAVE_BBE16 0 /* ConnX BBE16 pkg */
|
||||
#define XCHAL_HAVE_BBE16_RSQRT 0 /* BBE16 & vector recip sqrt */
|
||||
#define XCHAL_HAVE_BBE16_VECDIV 0 /* BBE16 & vector divide */
|
||||
#define XCHAL_HAVE_BBE16_DESPREAD 0 /* BBE16 & despread */
|
||||
#define XCHAL_HAVE_BSP3 0 /* ConnX BSP3 pkg */
|
||||
#define XCHAL_HAVE_SSP16 0 /* ConnX SSP16 pkg */
|
||||
#define XCHAL_HAVE_SSP16_VITERBI 0 /* SSP16 & viterbi */
|
||||
#define XCHAL_HAVE_TURBO16 0 /* ConnX Turbo16 pkg */
|
||||
#define XCHAL_HAVE_BBP16 0 /* ConnX BBP16 pkg */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
MISC
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_NUM_WRITEBUFFER_ENTRIES 8 /* size of write buffer */
|
||||
#define XCHAL_INST_FETCH_WIDTH 4 /* instr-fetch width in bytes */
|
||||
#define XCHAL_DATA_WIDTH 4 /* data width in bytes */
|
||||
/* In T1050, applies to selected core load and store instructions (see ISA): */
|
||||
#define XCHAL_UNALIGNED_LOAD_EXCEPTION 1 /* unaligned loads cause exc. */
|
||||
#define XCHAL_UNALIGNED_STORE_EXCEPTION 1 /* unaligned stores cause exc.*/
|
||||
#define XCHAL_UNALIGNED_LOAD_HW 0 /* unaligned loads work in hw */
|
||||
#define XCHAL_UNALIGNED_STORE_HW 0 /* unaligned stores work in hw*/
|
||||
|
||||
#define XCHAL_SW_VERSION 900001 /* sw version of this header */
|
||||
|
||||
#define XCHAL_CORE_ID "dc233c" /* alphanum core name
|
||||
(CoreID) set in the Xtensa
|
||||
Processor Generator */
|
||||
|
||||
#define XCHAL_CORE_DESCRIPTION "dc233c"
|
||||
#define XCHAL_BUILD_UNIQUE_ID 0x00004B21 /* 22-bit sw build ID */
|
||||
|
||||
/*
|
||||
* These definitions describe the hardware targeted by this software.
|
||||
*/
|
||||
#define XCHAL_HW_CONFIGID0 0xC56707FE /* ConfigID hi 32 bits*/
|
||||
#define XCHAL_HW_CONFIGID1 0x14404B21 /* ConfigID lo 32 bits*/
|
||||
#define XCHAL_HW_VERSION_NAME "LX4.0.1" /* full version name */
|
||||
#define XCHAL_HW_VERSION_MAJOR 2400 /* major ver# of targeted hw */
|
||||
#define XCHAL_HW_VERSION_MINOR 1 /* minor ver# of targeted hw */
|
||||
#define XCHAL_HW_VERSION 240001 /* major*100+minor */
|
||||
#define XCHAL_HW_REL_LX4 1
|
||||
#define XCHAL_HW_REL_LX4_0 1
|
||||
#define XCHAL_HW_REL_LX4_0_1 1
|
||||
#define XCHAL_HW_CONFIGID_RELIABLE 1
|
||||
/* If software targets a *range* of hardware versions, these are the bounds: */
|
||||
#define XCHAL_HW_MIN_VERSION_MAJOR 2400 /* major v of earliest tgt hw */
|
||||
#define XCHAL_HW_MIN_VERSION_MINOR 1 /* minor v of earliest tgt hw */
|
||||
#define XCHAL_HW_MIN_VERSION 240001 /* earliest targeted hw */
|
||||
#define XCHAL_HW_MAX_VERSION_MAJOR 2400 /* major v of latest tgt hw */
|
||||
#define XCHAL_HW_MAX_VERSION_MINOR 1 /* minor v of latest tgt hw */
|
||||
#define XCHAL_HW_MAX_VERSION 240001 /* latest targeted hw */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
CACHE
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_ICACHE_LINESIZE 32 /* I-cache line size in bytes */
|
||||
#define XCHAL_DCACHE_LINESIZE 32 /* D-cache line size in bytes */
|
||||
#define XCHAL_ICACHE_LINEWIDTH 5 /* log2(I line size in bytes) */
|
||||
#define XCHAL_DCACHE_LINEWIDTH 5 /* log2(D line size in bytes) */
|
||||
|
||||
#define XCHAL_ICACHE_SIZE 16384 /* I-cache size in bytes or 0 */
|
||||
#define XCHAL_DCACHE_SIZE 16384 /* D-cache size in bytes or 0 */
|
||||
|
||||
#define XCHAL_DCACHE_IS_WRITEBACK 1 /* writeback feature */
|
||||
#define XCHAL_DCACHE_IS_COHERENT 0 /* MP coherence feature */
|
||||
|
||||
#define XCHAL_HAVE_PREFETCH 0 /* PREFCTL register */
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
CACHE
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_HAVE_PIF 1 /* any outbound PIF present */
|
||||
|
||||
/* If present, cache size in bytes == (ways * 2^(linewidth + setwidth)). */
|
||||
|
||||
/* Number of cache sets in log2(lines per way): */
|
||||
#define XCHAL_ICACHE_SETWIDTH 7
|
||||
#define XCHAL_DCACHE_SETWIDTH 7
|
||||
|
||||
/* Cache set associativity (number of ways): */
|
||||
#define XCHAL_ICACHE_WAYS 4
|
||||
#define XCHAL_DCACHE_WAYS 4
|
||||
|
||||
/* Cache features: */
|
||||
#define XCHAL_ICACHE_LINE_LOCKABLE 1
|
||||
#define XCHAL_DCACHE_LINE_LOCKABLE 1
|
||||
#define XCHAL_ICACHE_ECC_PARITY 0
|
||||
#define XCHAL_DCACHE_ECC_PARITY 0
|
||||
|
||||
/* Cache access size in bytes (affects operation of SICW instruction): */
|
||||
#define XCHAL_ICACHE_ACCESS_SIZE 4
|
||||
#define XCHAL_DCACHE_ACCESS_SIZE 4
|
||||
|
||||
/* Number of encoded cache attr bits (see <xtensa/hal.h> for decoded bits): */
|
||||
#define XCHAL_CA_BITS 4
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
INTERNAL I/D RAM/ROMs and XLMI
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_NUM_INSTROM 0 /* number of core instr. ROMs */
|
||||
#define XCHAL_NUM_INSTRAM 0 /* number of core instr. RAMs */
|
||||
#define XCHAL_NUM_DATAROM 0 /* number of core data ROMs */
|
||||
#define XCHAL_NUM_DATARAM 0 /* number of core data RAMs */
|
||||
#define XCHAL_NUM_URAM 0 /* number of core unified RAMs*/
|
||||
#define XCHAL_NUM_XLMI 0 /* number of core XLMI ports */
|
||||
|
||||
#define XCHAL_HAVE_IMEM_LOADSTORE 1 /* can load/store to IROM/IRAM*/
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
INTERRUPTS and TIMERS
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_HAVE_INTERRUPTS 1 /* interrupt option */
|
||||
#define XCHAL_HAVE_HIGHPRI_INTERRUPTS 1 /* med/high-pri. interrupts */
|
||||
#define XCHAL_HAVE_NMI 1 /* non-maskable interrupt */
|
||||
#define XCHAL_HAVE_CCOUNT 1 /* CCOUNT reg. (timer option) */
|
||||
#define XCHAL_NUM_TIMERS 3 /* number of CCOMPAREn regs */
|
||||
#define XCHAL_NUM_INTERRUPTS 22 /* number of interrupts */
|
||||
#define XCHAL_NUM_INTERRUPTS_LOG2 5 /* ceil(log2(NUM_INTERRUPTS)) */
|
||||
#define XCHAL_NUM_EXTINTERRUPTS 17 /* num of external interrupts */
|
||||
#define XCHAL_NUM_INTLEVELS 6 /* number of interrupt levels
|
||||
(not including level zero) */
|
||||
#define XCHAL_EXCM_LEVEL 3 /* level masked by PS.EXCM */
|
||||
/* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */
|
||||
|
||||
/* Masks of interrupts at each interrupt level: */
|
||||
#define XCHAL_INTLEVEL1_MASK 0x001F80FF
|
||||
#define XCHAL_INTLEVEL2_MASK 0x00000100
|
||||
#define XCHAL_INTLEVEL3_MASK 0x00200E00
|
||||
#define XCHAL_INTLEVEL4_MASK 0x00001000
|
||||
#define XCHAL_INTLEVEL5_MASK 0x00002000
|
||||
#define XCHAL_INTLEVEL6_MASK 0x00000000
|
||||
#define XCHAL_INTLEVEL7_MASK 0x00004000
|
||||
|
||||
/* Masks of interrupts at each range 1..n of interrupt levels: */
|
||||
#define XCHAL_INTLEVEL1_ANDBELOW_MASK 0x001F80FF
|
||||
#define XCHAL_INTLEVEL2_ANDBELOW_MASK 0x001F81FF
|
||||
#define XCHAL_INTLEVEL3_ANDBELOW_MASK 0x003F8FFF
|
||||
#define XCHAL_INTLEVEL4_ANDBELOW_MASK 0x003F9FFF
|
||||
#define XCHAL_INTLEVEL5_ANDBELOW_MASK 0x003FBFFF
|
||||
#define XCHAL_INTLEVEL6_ANDBELOW_MASK 0x003FBFFF
|
||||
#define XCHAL_INTLEVEL7_ANDBELOW_MASK 0x003FFFFF
|
||||
|
||||
/* Level of each interrupt: */
|
||||
#define XCHAL_INT0_LEVEL 1
|
||||
#define XCHAL_INT1_LEVEL 1
|
||||
#define XCHAL_INT2_LEVEL 1
|
||||
#define XCHAL_INT3_LEVEL 1
|
||||
#define XCHAL_INT4_LEVEL 1
|
||||
#define XCHAL_INT5_LEVEL 1
|
||||
#define XCHAL_INT6_LEVEL 1
|
||||
#define XCHAL_INT7_LEVEL 1
|
||||
#define XCHAL_INT8_LEVEL 2
|
||||
#define XCHAL_INT9_LEVEL 3
|
||||
#define XCHAL_INT10_LEVEL 3
|
||||
#define XCHAL_INT11_LEVEL 3
|
||||
#define XCHAL_INT12_LEVEL 4
|
||||
#define XCHAL_INT13_LEVEL 5
|
||||
#define XCHAL_INT14_LEVEL 7
|
||||
#define XCHAL_INT15_LEVEL 1
|
||||
#define XCHAL_INT16_LEVEL 1
|
||||
#define XCHAL_INT17_LEVEL 1
|
||||
#define XCHAL_INT18_LEVEL 1
|
||||
#define XCHAL_INT19_LEVEL 1
|
||||
#define XCHAL_INT20_LEVEL 1
|
||||
#define XCHAL_INT21_LEVEL 3
|
||||
#define XCHAL_DEBUGLEVEL 6 /* debug interrupt level */
|
||||
#define XCHAL_HAVE_DEBUG_EXTERN_INT 1 /* OCD external db interrupt */
|
||||
#define XCHAL_NMILEVEL 7 /* NMI "level" (for use with
|
||||
EXCSAVE/EPS/EPC_n, RFI n) */
|
||||
|
||||
/* Type of each interrupt: */
|
||||
#define XCHAL_INT0_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT1_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT2_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT3_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT4_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT5_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT6_TYPE XTHAL_INTTYPE_TIMER
|
||||
#define XCHAL_INT7_TYPE XTHAL_INTTYPE_SOFTWARE
|
||||
#define XCHAL_INT8_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT9_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT10_TYPE XTHAL_INTTYPE_TIMER
|
||||
#define XCHAL_INT11_TYPE XTHAL_INTTYPE_SOFTWARE
|
||||
#define XCHAL_INT12_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT13_TYPE XTHAL_INTTYPE_TIMER
|
||||
#define XCHAL_INT14_TYPE XTHAL_INTTYPE_NMI
|
||||
#define XCHAL_INT15_TYPE XTHAL_INTTYPE_EXTERN_EDGE
|
||||
#define XCHAL_INT16_TYPE XTHAL_INTTYPE_EXTERN_EDGE
|
||||
#define XCHAL_INT17_TYPE XTHAL_INTTYPE_EXTERN_EDGE
|
||||
#define XCHAL_INT18_TYPE XTHAL_INTTYPE_EXTERN_EDGE
|
||||
#define XCHAL_INT19_TYPE XTHAL_INTTYPE_EXTERN_EDGE
|
||||
#define XCHAL_INT20_TYPE XTHAL_INTTYPE_EXTERN_EDGE
|
||||
#define XCHAL_INT21_TYPE XTHAL_INTTYPE_EXTERN_EDGE
|
||||
|
||||
/* Masks of interrupts for each type of interrupt: */
|
||||
#define XCHAL_INTTYPE_MASK_UNCONFIGURED 0xFFC00000
|
||||
#define XCHAL_INTTYPE_MASK_SOFTWARE 0x00000880
|
||||
#define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x003F8000
|
||||
#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL 0x0000133F
|
||||
#define XCHAL_INTTYPE_MASK_TIMER 0x00002440
|
||||
#define XCHAL_INTTYPE_MASK_NMI 0x00004000
|
||||
#define XCHAL_INTTYPE_MASK_WRITE_ERROR 0x00000000
|
||||
|
||||
/* Interrupt numbers assigned to specific interrupt sources: */
|
||||
#define XCHAL_TIMER0_INTERRUPT 6 /* CCOMPARE0 */
|
||||
#define XCHAL_TIMER1_INTERRUPT 10 /* CCOMPARE1 */
|
||||
#define XCHAL_TIMER2_INTERRUPT 13 /* CCOMPARE2 */
|
||||
#define XCHAL_TIMER3_INTERRUPT XTHAL_TIMER_UNCONFIGURED
|
||||
#define XCHAL_NMI_INTERRUPT 14 /* non-maskable interrupt */
|
||||
|
||||
/* Interrupt numbers for levels at which only one interrupt is configured: */
|
||||
#define XCHAL_INTLEVEL2_NUM 8
|
||||
#define XCHAL_INTLEVEL4_NUM 12
|
||||
#define XCHAL_INTLEVEL5_NUM 13
|
||||
#define XCHAL_INTLEVEL7_NUM 14
|
||||
/* (There are many interrupts each at level(s) 1, 3.) */
|
||||
|
||||
|
||||
/*
|
||||
* External interrupt vectors/levels.
|
||||
* These macros describe how Xtensa processor interrupt numbers
|
||||
* (as numbered internally, eg. in INTERRUPT and INTENABLE registers)
|
||||
* map to external BInterrupt<n> pins, for those interrupts
|
||||
* configured as external (level-triggered, edge-triggered, or NMI).
|
||||
* See the Xtensa processor databook for more details.
|
||||
*/
|
||||
|
||||
/* Core interrupt numbers mapped to each EXTERNAL interrupt number: */
|
||||
#define XCHAL_EXTINT0_NUM 0 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT1_NUM 1 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT2_NUM 2 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT3_NUM 3 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT4_NUM 4 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT5_NUM 5 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT6_NUM 8 /* (intlevel 2) */
|
||||
#define XCHAL_EXTINT7_NUM 9 /* (intlevel 3) */
|
||||
#define XCHAL_EXTINT8_NUM 12 /* (intlevel 4) */
|
||||
#define XCHAL_EXTINT9_NUM 14 /* (intlevel 7) */
|
||||
#define XCHAL_EXTINT10_NUM 15 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT11_NUM 16 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT12_NUM 17 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT13_NUM 18 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT14_NUM 19 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT15_NUM 20 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT16_NUM 21 /* (intlevel 3) */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
EXCEPTIONS and VECTORS
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_XEA_VERSION 2 /* Xtensa Exception Architecture
|
||||
number: 1 == XEA1 (old)
|
||||
2 == XEA2 (new)
|
||||
0 == XEAX (extern) or TX */
|
||||
#define XCHAL_HAVE_XEA1 0 /* Exception Architecture 1 */
|
||||
#define XCHAL_HAVE_XEA2 1 /* Exception Architecture 2 */
|
||||
#define XCHAL_HAVE_XEAX 0 /* External Exception Arch. */
|
||||
#define XCHAL_HAVE_EXCEPTIONS 1 /* exception option */
|
||||
#define XCHAL_HAVE_HALT 0 /* halt architecture option */
|
||||
#define XCHAL_HAVE_BOOTLOADER 0 /* boot loader (for TX) */
|
||||
#define XCHAL_HAVE_MEM_ECC_PARITY 0 /* local memory ECC/parity */
|
||||
#define XCHAL_HAVE_VECTOR_SELECT 1 /* relocatable vectors */
|
||||
#define XCHAL_HAVE_VECBASE 1 /* relocatable vectors */
|
||||
#define XCHAL_VECBASE_RESET_VADDR 0x00002000 /* VECBASE reset value */
|
||||
#define XCHAL_VECBASE_RESET_PADDR 0x00002000
|
||||
#define XCHAL_RESET_VECBASE_OVERLAP 0
|
||||
|
||||
#define XCHAL_RESET_VECTOR0_VADDR 0xFE000000
|
||||
#define XCHAL_RESET_VECTOR0_PADDR 0xFE000000
|
||||
#define XCHAL_RESET_VECTOR1_VADDR 0x00001000
|
||||
#define XCHAL_RESET_VECTOR1_PADDR 0x00001000
|
||||
#define XCHAL_RESET_VECTOR_VADDR 0xFE000000
|
||||
#define XCHAL_RESET_VECTOR_PADDR 0xFE000000
|
||||
#define XCHAL_USER_VECOFS 0x00000340
|
||||
#define XCHAL_USER_VECTOR_VADDR 0x00002340
|
||||
#define XCHAL_USER_VECTOR_PADDR 0x00002340
|
||||
#define XCHAL_KERNEL_VECOFS 0x00000300
|
||||
#define XCHAL_KERNEL_VECTOR_VADDR 0x00002300
|
||||
#define XCHAL_KERNEL_VECTOR_PADDR 0x00002300
|
||||
#define XCHAL_DOUBLEEXC_VECOFS 0x000003C0
|
||||
#define XCHAL_DOUBLEEXC_VECTOR_VADDR 0x000023C0
|
||||
#define XCHAL_DOUBLEEXC_VECTOR_PADDR 0x000023C0
|
||||
#define XCHAL_WINDOW_OF4_VECOFS 0x00000000
|
||||
#define XCHAL_WINDOW_UF4_VECOFS 0x00000040
|
||||
#define XCHAL_WINDOW_OF8_VECOFS 0x00000080
|
||||
#define XCHAL_WINDOW_UF8_VECOFS 0x000000C0
|
||||
#define XCHAL_WINDOW_OF12_VECOFS 0x00000100
|
||||
#define XCHAL_WINDOW_UF12_VECOFS 0x00000140
|
||||
#define XCHAL_WINDOW_VECTORS_VADDR 0x00002000
|
||||
#define XCHAL_WINDOW_VECTORS_PADDR 0x00002000
|
||||
#define XCHAL_INTLEVEL2_VECOFS 0x00000180
|
||||
#define XCHAL_INTLEVEL2_VECTOR_VADDR 0x00002180
|
||||
#define XCHAL_INTLEVEL2_VECTOR_PADDR 0x00002180
|
||||
#define XCHAL_INTLEVEL3_VECOFS 0x000001C0
|
||||
#define XCHAL_INTLEVEL3_VECTOR_VADDR 0x000021C0
|
||||
#define XCHAL_INTLEVEL3_VECTOR_PADDR 0x000021C0
|
||||
#define XCHAL_INTLEVEL4_VECOFS 0x00000200
|
||||
#define XCHAL_INTLEVEL4_VECTOR_VADDR 0x00002200
|
||||
#define XCHAL_INTLEVEL4_VECTOR_PADDR 0x00002200
|
||||
#define XCHAL_INTLEVEL5_VECOFS 0x00000240
|
||||
#define XCHAL_INTLEVEL5_VECTOR_VADDR 0x00002240
|
||||
#define XCHAL_INTLEVEL5_VECTOR_PADDR 0x00002240
|
||||
#define XCHAL_INTLEVEL6_VECOFS 0x00000280
|
||||
#define XCHAL_INTLEVEL6_VECTOR_VADDR 0x00002280
|
||||
#define XCHAL_INTLEVEL6_VECTOR_PADDR 0x00002280
|
||||
#define XCHAL_DEBUG_VECOFS XCHAL_INTLEVEL6_VECOFS
|
||||
#define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL6_VECTOR_VADDR
|
||||
#define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL6_VECTOR_PADDR
|
||||
#define XCHAL_NMI_VECOFS 0x000002C0
|
||||
#define XCHAL_NMI_VECTOR_VADDR 0x000022C0
|
||||
#define XCHAL_NMI_VECTOR_PADDR 0x000022C0
|
||||
#define XCHAL_INTLEVEL7_VECOFS XCHAL_NMI_VECOFS
|
||||
#define XCHAL_INTLEVEL7_VECTOR_VADDR XCHAL_NMI_VECTOR_VADDR
|
||||
#define XCHAL_INTLEVEL7_VECTOR_PADDR XCHAL_NMI_VECTOR_PADDR
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
DEBUG
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_HAVE_OCD 1 /* OnChipDebug option */
|
||||
#define XCHAL_NUM_IBREAK 2 /* number of IBREAKn regs */
|
||||
#define XCHAL_NUM_DBREAK 2 /* number of DBREAKn regs */
|
||||
#define XCHAL_HAVE_OCD_DIR_ARRAY 1 /* faster OCD option */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
MMU
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
/* See core-matmap.h header file for more details. */
|
||||
|
||||
#define XCHAL_HAVE_TLBS 1 /* inverse of HAVE_CACHEATTR */
|
||||
#define XCHAL_HAVE_SPANNING_WAY 1 /* one way maps I+D 4GB vaddr */
|
||||
#define XCHAL_SPANNING_WAY 6 /* TLB spanning way number */
|
||||
#define XCHAL_HAVE_IDENTITY_MAP 0 /* vaddr == paddr always */
|
||||
#define XCHAL_HAVE_CACHEATTR 0 /* CACHEATTR register present */
|
||||
#define XCHAL_HAVE_MIMIC_CACHEATTR 0 /* region protection */
|
||||
#define XCHAL_HAVE_XLT_CACHEATTR 0 /* region prot. w/translation */
|
||||
#define XCHAL_HAVE_PTP_MMU 1 /* full MMU (with page table
|
||||
[autorefill] and protection)
|
||||
usable for an MMU-based OS */
|
||||
/* If none of the above last 4 are set, it's a custom TLB configuration. */
|
||||
#define XCHAL_ITLB_ARF_ENTRIES_LOG2 2 /* log2(autorefill way size) */
|
||||
#define XCHAL_DTLB_ARF_ENTRIES_LOG2 2 /* log2(autorefill way size) */
|
||||
|
||||
#define XCHAL_MMU_ASID_BITS 8 /* number of bits in ASIDs */
|
||||
#define XCHAL_MMU_RINGS 4 /* number of rings (1..4) */
|
||||
#define XCHAL_MMU_RING_BITS 2 /* num of bits in RING field */
|
||||
|
||||
#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */
|
||||
|
||||
|
||||
#endif /* XTENSA_DC233C_CORE_ISA_H */
|
145
target/xtensa/core-dc233c/gdb-config.c
Normal file
145
target/xtensa/core-dc233c/gdb-config.c
Normal file
|
@ -0,0 +1,145 @@
|
|||
/* Configuration for the Xtensa architecture for GDB, the GNU debugger.
|
||||
|
||||
Copyright (c) 2003-2010 Tensilica Inc.
|
||||
|
||||
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. */
|
||||
|
||||
/* idx ofs bi sz al targno flags cp typ group name */
|
||||
XTREG(0, 0, 32, 4, 4, 0x0020, 0x0006, -2, 9, 0x0100, pc, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(1, 4, 32, 4, 4, 0x0100, 0x0006, -2, 1, 0x0002, ar0, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(2, 8, 32, 4, 4, 0x0101, 0x0006, -2, 1, 0x0002, ar1, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(3, 12, 32, 4, 4, 0x0102, 0x0006, -2, 1, 0x0002, ar2, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(4, 16, 32, 4, 4, 0x0103, 0x0006, -2, 1, 0x0002, ar3, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(5, 20, 32, 4, 4, 0x0104, 0x0006, -2, 1, 0x0002, ar4, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(6, 24, 32, 4, 4, 0x0105, 0x0006, -2, 1, 0x0002, ar5, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(7, 28, 32, 4, 4, 0x0106, 0x0006, -2, 1, 0x0002, ar6, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(8, 32, 32, 4, 4, 0x0107, 0x0006, -2, 1, 0x0002, ar7, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(9, 36, 32, 4, 4, 0x0108, 0x0006, -2, 1, 0x0002, ar8, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(10, 40, 32, 4, 4, 0x0109, 0x0006, -2, 1, 0x0002, ar9, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(11, 44, 32, 4, 4, 0x010a, 0x0006, -2, 1, 0x0002, ar10, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(12, 48, 32, 4, 4, 0x010b, 0x0006, -2, 1, 0x0002, ar11, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(13, 52, 32, 4, 4, 0x010c, 0x0006, -2, 1, 0x0002, ar12, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(14, 56, 32, 4, 4, 0x010d, 0x0006, -2, 1, 0x0002, ar13, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(15, 60, 32, 4, 4, 0x010e, 0x0006, -2, 1, 0x0002, ar14, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(16, 64, 32, 4, 4, 0x010f, 0x0006, -2, 1, 0x0002, ar15, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(17, 68, 32, 4, 4, 0x0110, 0x0006, -2, 1, 0x0002, ar16, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(18, 72, 32, 4, 4, 0x0111, 0x0006, -2, 1, 0x0002, ar17, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(19, 76, 32, 4, 4, 0x0112, 0x0006, -2, 1, 0x0002, ar18, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(20, 80, 32, 4, 4, 0x0113, 0x0006, -2, 1, 0x0002, ar19, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(21, 84, 32, 4, 4, 0x0114, 0x0006, -2, 1, 0x0002, ar20, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(22, 88, 32, 4, 4, 0x0115, 0x0006, -2, 1, 0x0002, ar21, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(23, 92, 32, 4, 4, 0x0116, 0x0006, -2, 1, 0x0002, ar22, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(24, 96, 32, 4, 4, 0x0117, 0x0006, -2, 1, 0x0002, ar23, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(25, 100, 32, 4, 4, 0x0118, 0x0006, -2, 1, 0x0002, ar24, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(26, 104, 32, 4, 4, 0x0119, 0x0006, -2, 1, 0x0002, ar25, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(27, 108, 32, 4, 4, 0x011a, 0x0006, -2, 1, 0x0002, ar26, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(28, 112, 32, 4, 4, 0x011b, 0x0006, -2, 1, 0x0002, ar27, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(29, 116, 32, 4, 4, 0x011c, 0x0006, -2, 1, 0x0002, ar28, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(30, 120, 32, 4, 4, 0x011d, 0x0006, -2, 1, 0x0002, ar29, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(31, 124, 32, 4, 4, 0x011e, 0x0006, -2, 1, 0x0002, ar30, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(32, 128, 32, 4, 4, 0x011f, 0x0006, -2, 1, 0x0002, ar31, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(33, 132, 32, 4, 4, 0x0200, 0x0006, -2, 2, 0x1100, lbeg, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(34, 136, 32, 4, 4, 0x0201, 0x0006, -2, 2, 0x1100, lend, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(35, 140, 32, 4, 4, 0x0202, 0x0006, -2, 2, 0x1100, lcount, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(36, 144, 6, 4, 4, 0x0203, 0x0006, -2, 2, 0x1100, sar, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(37, 148, 32, 4, 4, 0x0205, 0x0006, -2, 2, 0x1100, litbase, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(38, 152, 3, 4, 4, 0x0248, 0x0006, -2, 2, 0x1002, windowbase, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(39, 156, 8, 4, 4, 0x0249, 0x0006, -2, 2, 0x1002, windowstart, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(40, 160, 32, 4, 4, 0x02b0, 0x0002, -2, 2, 0x1000, sr176, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(41, 164, 32, 4, 4, 0x02d0, 0x0002, -2, 2, 0x1000, sr208, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(42, 168, 19, 4, 4, 0x02e6, 0x0006, -2, 2, 0x1100, ps, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(43, 172, 32, 4, 4, 0x03e7, 0x0006, -2, 3, 0x0110, threadptr, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(44, 176, 32, 4, 4, 0x020c, 0x0006, -1, 2, 0x1100, scompare1, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(45, 180, 32, 4, 4, 0x0210, 0x0006, -1, 2, 0x1100, acclo, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(46, 184, 8, 4, 4, 0x0211, 0x0006, -1, 2, 0x1100, acchi, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(47, 188, 32, 4, 4, 0x0220, 0x0006, -1, 2, 0x1100, m0, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(48, 192, 32, 4, 4, 0x0221, 0x0006, -1, 2, 0x1100, m1, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(49, 196, 32, 4, 4, 0x0222, 0x0006, -1, 2, 0x1100, m2, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(50, 200, 32, 4, 4, 0x0223, 0x0006, -1, 2, 0x1100, m3, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(51, 204, 32, 4, 4, 0x03e6, 0x000e, -1, 3, 0x0110, expstate, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(52, 208, 32, 4, 4, 0x0253, 0x0007, -2, 2, 0x1000, ptevaddr, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(53, 212, 32, 4, 4, 0x0259, 0x000d, -2, 2, 0x1000, mmid, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(54, 216, 32, 4, 4, 0x025a, 0x0007, -2, 2, 0x1000, rasid, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(55, 220, 25, 4, 4, 0x025b, 0x0007, -2, 2, 0x1000, itlbcfg, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(56, 224, 25, 4, 4, 0x025c, 0x0007, -2, 2, 0x1000, dtlbcfg, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(57, 228, 2, 4, 4, 0x0260, 0x0007, -2, 2, 0x1000, ibreakenable, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(58, 232, 6, 4, 4, 0x0263, 0x0007, -2, 2, 0x1000, atomctl, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(59, 236, 32, 4, 4, 0x0268, 0x0007, -2, 2, 0x1000, ddr, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(60, 240, 32, 4, 4, 0x0280, 0x0007, -2, 2, 0x1000, ibreaka0, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(61, 244, 32, 4, 4, 0x0281, 0x0007, -2, 2, 0x1000, ibreaka1, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(62, 248, 32, 4, 4, 0x0290, 0x0007, -2, 2, 0x1000, dbreaka0, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(63, 252, 32, 4, 4, 0x0291, 0x0007, -2, 2, 0x1000, dbreaka1, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(64, 256, 32, 4, 4, 0x02a0, 0x0007, -2, 2, 0x1000, dbreakc0, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(65, 260, 32, 4, 4, 0x02a1, 0x0007, -2, 2, 0x1000, dbreakc1, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(66, 264, 32, 4, 4, 0x02b1, 0x0007, -2, 2, 0x1000, epc1, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(67, 268, 32, 4, 4, 0x02b2, 0x0007, -2, 2, 0x1000, epc2, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(68, 272, 32, 4, 4, 0x02b3, 0x0007, -2, 2, 0x1000, epc3, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(69, 276, 32, 4, 4, 0x02b4, 0x0007, -2, 2, 0x1000, epc4, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(70, 280, 32, 4, 4, 0x02b5, 0x0007, -2, 2, 0x1000, epc5, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(71, 284, 32, 4, 4, 0x02b6, 0x0007, -2, 2, 0x1000, epc6, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(72, 288, 32, 4, 4, 0x02b7, 0x0007, -2, 2, 0x1000, epc7, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(73, 292, 32, 4, 4, 0x02c0, 0x0007, -2, 2, 0x1000, depc, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(74, 296, 19, 4, 4, 0x02c2, 0x0007, -2, 2, 0x1000, eps2, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(75, 300, 19, 4, 4, 0x02c3, 0x0007, -2, 2, 0x1000, eps3, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(76, 304, 19, 4, 4, 0x02c4, 0x0007, -2, 2, 0x1000, eps4, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(77, 308, 19, 4, 4, 0x02c5, 0x0007, -2, 2, 0x1000, eps5, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(78, 312, 19, 4, 4, 0x02c6, 0x0007, -2, 2, 0x1000, eps6, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(79, 316, 19, 4, 4, 0x02c7, 0x0007, -2, 2, 0x1000, eps7, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(80, 320, 32, 4, 4, 0x02d1, 0x0007, -2, 2, 0x1000, excsave1, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(81, 324, 32, 4, 4, 0x02d2, 0x0007, -2, 2, 0x1000, excsave2, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(82, 328, 32, 4, 4, 0x02d3, 0x0007, -2, 2, 0x1000, excsave3, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(83, 332, 32, 4, 4, 0x02d4, 0x0007, -2, 2, 0x1000, excsave4, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(84, 336, 32, 4, 4, 0x02d5, 0x0007, -2, 2, 0x1000, excsave5, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(85, 340, 32, 4, 4, 0x02d6, 0x0007, -2, 2, 0x1000, excsave6, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(86, 344, 32, 4, 4, 0x02d7, 0x0007, -2, 2, 0x1000, excsave7, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(87, 348, 8, 4, 4, 0x02e0, 0x0007, -2, 2, 0x1000, cpenable, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(88, 352, 22, 4, 4, 0x02e2, 0x000b, -2, 2, 0x1000, interrupt, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(89, 356, 22, 4, 4, 0x02e2, 0x000d, -2, 2, 0x1000, intset, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(90, 360, 22, 4, 4, 0x02e3, 0x000d, -2, 2, 0x1000, intclear, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(91, 364, 22, 4, 4, 0x02e4, 0x0007, -2, 2, 0x1000, intenable, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(92, 368, 32, 4, 4, 0x02e7, 0x0007, -2, 2, 0x1000, vecbase, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(93, 372, 6, 4, 4, 0x02e8, 0x0007, -2, 2, 0x1000, exccause, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(94, 376, 12, 4, 4, 0x02e9, 0x0003, -2, 2, 0x1000, debugcause, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(95, 380, 32, 4, 4, 0x02ea, 0x000f, -2, 2, 0x1000, ccount, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(96, 384, 32, 4, 4, 0x02eb, 0x0003, -2, 2, 0x1000, prid, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(97, 388, 32, 4, 4, 0x02ec, 0x000f, -2, 2, 0x1000, icount, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(98, 392, 4, 4, 4, 0x02ed, 0x0007, -2, 2, 0x1000, icountlevel, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(99, 396, 32, 4, 4, 0x02ee, 0x0007, -2, 2, 0x1000, excvaddr, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(100, 400, 32, 4, 4, 0x02f0, 0x000f, -2, 2, 0x1000, ccompare0, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(101, 404, 32, 4, 4, 0x02f1, 0x000f, -2, 2, 0x1000, ccompare1, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(102, 408, 32, 4, 4, 0x02f2, 0x000f, -2, 2, 0x1000, ccompare2, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(103, 412, 32, 4, 4, 0x02f4, 0x0007, -2, 2, 0x1000, misc0, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(104, 416, 32, 4, 4, 0x02f5, 0x0007, -2, 2, 0x1000, misc1, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(105, 420, 32, 4, 4, 0x0000, 0x0006, -2, 8, 0x0100, a0, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(106, 424, 32, 4, 4, 0x0001, 0x0006, -2, 8, 0x0100, a1, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(107, 428, 32, 4, 4, 0x0002, 0x0006, -2, 8, 0x0100, a2, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(108, 432, 32, 4, 4, 0x0003, 0x0006, -2, 8, 0x0100, a3, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(109, 436, 32, 4, 4, 0x0004, 0x0006, -2, 8, 0x0100, a4, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(110, 440, 32, 4, 4, 0x0005, 0x0006, -2, 8, 0x0100, a5, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(111, 444, 32, 4, 4, 0x0006, 0x0006, -2, 8, 0x0100, a6, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(112, 448, 32, 4, 4, 0x0007, 0x0006, -2, 8, 0x0100, a7, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(113, 452, 32, 4, 4, 0x0008, 0x0006, -2, 8, 0x0100, a8, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(114, 456, 32, 4, 4, 0x0009, 0x0006, -2, 8, 0x0100, a9, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(115, 460, 32, 4, 4, 0x000a, 0x0006, -2, 8, 0x0100, a10, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(116, 464, 32, 4, 4, 0x000b, 0x0006, -2, 8, 0x0100, a11, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(117, 468, 32, 4, 4, 0x000c, 0x0006, -2, 8, 0x0100, a12, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(118, 472, 32, 4, 4, 0x000d, 0x0006, -2, 8, 0x0100, a13, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(119, 476, 32, 4, 4, 0x000e, 0x0006, -2, 8, 0x0100, a14, 0, 0, 0, 0, 0, 0)
|
||||
XTREG(120, 480, 32, 4, 4, 0x000f, 0x0006, -2, 8, 0x0100, a15, 0, 0, 0, 0, 0, 0)
|
49
target/xtensa/core-fsf.c
Normal file
49
target/xtensa/core-fsf.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of the Open Source and Linux Lab 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 COPYRIGHT HOLDERS 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "exec/gdbstub.h"
|
||||
#include "qemu/host-utils.h"
|
||||
|
||||
#include "core-fsf/core-isa.h"
|
||||
#include "overlay_tool.h"
|
||||
|
||||
static XtensaConfig fsf __attribute__((unused)) = {
|
||||
.name = "fsf",
|
||||
.gdb_regmap = {
|
||||
/* GDB for this core is not supported currently */
|
||||
.reg = {
|
||||
XTREG_END
|
||||
},
|
||||
},
|
||||
.clock_freq_khz = 10000,
|
||||
DEFAULT_SECTIONS
|
||||
};
|
||||
|
||||
REGISTER_CORE(fsf)
|
360
target/xtensa/core-fsf/core-isa.h
Normal file
360
target/xtensa/core-fsf/core-isa.h
Normal file
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
* Xtensa processor core configuration information.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 1999-2006 Tensilica Inc.
|
||||
*/
|
||||
|
||||
#ifndef XTENSA_FSF_CORE_ISA_H
|
||||
#define XTENSA_FSF_CORE_ISA_H
|
||||
|
||||
/****************************************************************************
|
||||
Parameters Useful for Any Code, USER or PRIVILEGED
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Note: Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is
|
||||
* configured, and a value of 0 otherwise. These macros are always defined.
|
||||
*/
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
ISA
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_HAVE_BE 1 /* big-endian byte ordering */
|
||||
#define XCHAL_HAVE_WINDOWED 1 /* windowed registers option */
|
||||
#define XCHAL_NUM_AREGS 64 /* num of physical addr regs */
|
||||
#define XCHAL_NUM_AREGS_LOG2 6 /* log2(XCHAL_NUM_AREGS) */
|
||||
#define XCHAL_MAX_INSTRUCTION_SIZE 3 /* max instr bytes (3..8) */
|
||||
#define XCHAL_HAVE_DEBUG 1 /* debug option */
|
||||
#define XCHAL_HAVE_DENSITY 1 /* 16-bit instructions */
|
||||
#define XCHAL_HAVE_LOOPS 1 /* zero-overhead loops */
|
||||
#define XCHAL_HAVE_NSA 1 /* NSA/NSAU instructions */
|
||||
#define XCHAL_HAVE_MINMAX 0 /* MIN/MAX instructions */
|
||||
#define XCHAL_HAVE_SEXT 0 /* SEXT instruction */
|
||||
#define XCHAL_HAVE_CLAMPS 0 /* CLAMPS instruction */
|
||||
#define XCHAL_HAVE_MUL16 0 /* MUL16S/MUL16U instructions */
|
||||
#define XCHAL_HAVE_MUL32 0 /* MULL instruction */
|
||||
#define XCHAL_HAVE_MUL32_HIGH 0 /* MULUH/MULSH instructions */
|
||||
#define XCHAL_HAVE_L32R 1 /* L32R instruction */
|
||||
#define XCHAL_HAVE_ABSOLUTE_LITERALS 1 /* non-PC-rel (extended) L32R */
|
||||
#define XCHAL_HAVE_CONST16 0 /* CONST16 instruction */
|
||||
#define XCHAL_HAVE_ADDX 1 /* ADDX#/SUBX# instructions */
|
||||
#define XCHAL_HAVE_WIDE_BRANCHES 0 /* B*.W18 or B*.W15 instr's */
|
||||
#define XCHAL_HAVE_PREDICTED_BRANCHES 0 /* B[EQ/EQZ/NE/NEZ]T instr's */
|
||||
#define XCHAL_HAVE_CALL4AND12 1 /* (obsolete option) */
|
||||
#define XCHAL_HAVE_ABS 1 /* ABS instruction */
|
||||
/*#define XCHAL_HAVE_POPC 0*/ /* POPC instruction */
|
||||
/*#define XCHAL_HAVE_CRC 0*/ /* CRC instruction */
|
||||
#define XCHAL_HAVE_RELEASE_SYNC 0 /* L32AI/S32RI instructions */
|
||||
#define XCHAL_HAVE_S32C1I 0 /* S32C1I instruction */
|
||||
#define XCHAL_HAVE_SPECULATION 0 /* speculation */
|
||||
#define XCHAL_HAVE_FULL_RESET 1 /* all regs/state reset */
|
||||
#define XCHAL_NUM_CONTEXTS 1 /* */
|
||||
#define XCHAL_NUM_MISC_REGS 2 /* num of scratch regs (0..4) */
|
||||
#define XCHAL_HAVE_TAP_MASTER 0 /* JTAG TAP control instr's */
|
||||
#define XCHAL_HAVE_PRID 1 /* processor ID register */
|
||||
#define XCHAL_HAVE_THREADPTR 1 /* THREADPTR register */
|
||||
#define XCHAL_HAVE_BOOLEANS 0 /* boolean registers */
|
||||
#define XCHAL_HAVE_CP 0 /* CPENABLE reg (coprocessor) */
|
||||
#define XCHAL_CP_MAXCFG 0 /* max allowed cp id plus one */
|
||||
#define XCHAL_HAVE_MAC16 0 /* MAC16 package */
|
||||
#define XCHAL_HAVE_VECTORFPU2005 0 /* vector floating-point pkg */
|
||||
#define XCHAL_HAVE_FP 0 /* floating point pkg */
|
||||
#define XCHAL_HAVE_VECTRA1 0 /* Vectra I pkg */
|
||||
#define XCHAL_HAVE_VECTRALX 0 /* Vectra LX pkg */
|
||||
#define XCHAL_HAVE_HIFI2 0 /* HiFi2 Audio Engine pkg */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
MISC
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_NUM_WRITEBUFFER_ENTRIES 4 /* size of write buffer */
|
||||
#define XCHAL_INST_FETCH_WIDTH 4 /* instr-fetch width in bytes */
|
||||
#define XCHAL_DATA_WIDTH 4 /* data width in bytes */
|
||||
/* In T1050, applies to selected core load and store instructions (see ISA): */
|
||||
#define XCHAL_UNALIGNED_LOAD_EXCEPTION 1 /* unaligned loads cause exc. */
|
||||
#define XCHAL_UNALIGNED_STORE_EXCEPTION 1 /* unaligned stores cause exc.*/
|
||||
|
||||
#define XCHAL_SW_VERSION 800002 /* sw version of this header */
|
||||
|
||||
#define XCHAL_CORE_ID "fsf" /* alphanum core name
|
||||
(CoreID) set in the Xtensa
|
||||
Processor Generator */
|
||||
|
||||
#define XCHAL_CORE_DESCRIPTION "fsf standard core"
|
||||
#define XCHAL_BUILD_UNIQUE_ID 0x00006700 /* 22-bit sw build ID */
|
||||
|
||||
/*
|
||||
* These definitions describe the hardware targeted by this software.
|
||||
*/
|
||||
#define XCHAL_HW_CONFIGID0 0xC103C3FF /* ConfigID hi 32 bits*/
|
||||
#define XCHAL_HW_CONFIGID1 0x0C006700 /* ConfigID lo 32 bits*/
|
||||
#define XCHAL_HW_VERSION_NAME "LX2.0.0" /* full version name */
|
||||
#define XCHAL_HW_VERSION_MAJOR 2200 /* major ver# of targeted hw */
|
||||
#define XCHAL_HW_VERSION_MINOR 0 /* minor ver# of targeted hw */
|
||||
#define XTHAL_HW_REL_LX2 1
|
||||
#define XTHAL_HW_REL_LX2_0 1
|
||||
#define XTHAL_HW_REL_LX2_0_0 1
|
||||
#define XCHAL_HW_CONFIGID_RELIABLE 1
|
||||
/* If software targets a *range* of hardware versions, these are the bounds: */
|
||||
#define XCHAL_HW_MIN_VERSION_MAJOR 2200 /* major v of earliest tgt hw */
|
||||
#define XCHAL_HW_MIN_VERSION_MINOR 0 /* minor v of earliest tgt hw */
|
||||
#define XCHAL_HW_MAX_VERSION_MAJOR 2200 /* major v of latest tgt hw */
|
||||
#define XCHAL_HW_MAX_VERSION_MINOR 0 /* minor v of latest tgt hw */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
CACHE
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_ICACHE_LINESIZE 16 /* I-cache line size in bytes */
|
||||
#define XCHAL_DCACHE_LINESIZE 16 /* D-cache line size in bytes */
|
||||
#define XCHAL_ICACHE_LINEWIDTH 4 /* log2(I line size in bytes) */
|
||||
#define XCHAL_DCACHE_LINEWIDTH 4 /* log2(D line size in bytes) */
|
||||
|
||||
#define XCHAL_ICACHE_SIZE 8192 /* I-cache size in bytes or 0 */
|
||||
#define XCHAL_DCACHE_SIZE 8192 /* D-cache size in bytes or 0 */
|
||||
|
||||
#define XCHAL_DCACHE_IS_WRITEBACK 0 /* writeback feature */
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
CACHE
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_HAVE_PIF 1 /* any outbound PIF present */
|
||||
|
||||
/* If present, cache size in bytes == (ways * 2^(linewidth + setwidth)). */
|
||||
|
||||
/* Number of cache sets in log2(lines per way): */
|
||||
#define XCHAL_ICACHE_SETWIDTH 8
|
||||
#define XCHAL_DCACHE_SETWIDTH 8
|
||||
|
||||
/* Cache set associativity (number of ways): */
|
||||
#define XCHAL_ICACHE_WAYS 2
|
||||
#define XCHAL_DCACHE_WAYS 2
|
||||
|
||||
/* Cache features: */
|
||||
#define XCHAL_ICACHE_LINE_LOCKABLE 0
|
||||
#define XCHAL_DCACHE_LINE_LOCKABLE 0
|
||||
#define XCHAL_ICACHE_ECC_PARITY 0
|
||||
#define XCHAL_DCACHE_ECC_PARITY 0
|
||||
|
||||
/* Number of encoded cache attr bits (see <xtensa/hal.h> for decoded bits): */
|
||||
#define XCHAL_CA_BITS 4
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
INTERNAL I/D RAM/ROMs and XLMI
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_NUM_INSTROM 0 /* number of core instr. ROMs */
|
||||
#define XCHAL_NUM_INSTRAM 0 /* number of core instr. RAMs */
|
||||
#define XCHAL_NUM_DATAROM 0 /* number of core data ROMs */
|
||||
#define XCHAL_NUM_DATARAM 0 /* number of core data RAMs */
|
||||
#define XCHAL_NUM_URAM 0 /* number of core unified RAMs*/
|
||||
#define XCHAL_NUM_XLMI 0 /* number of core XLMI ports */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
INTERRUPTS and TIMERS
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_HAVE_INTERRUPTS 1 /* interrupt option */
|
||||
#define XCHAL_HAVE_HIGHPRI_INTERRUPTS 1 /* med/high-pri. interrupts */
|
||||
#define XCHAL_HAVE_NMI 0 /* non-maskable interrupt */
|
||||
#define XCHAL_HAVE_CCOUNT 1 /* CCOUNT reg. (timer option) */
|
||||
#define XCHAL_NUM_TIMERS 3 /* number of CCOMPAREn regs */
|
||||
#define XCHAL_NUM_INTERRUPTS 17 /* number of interrupts */
|
||||
#define XCHAL_NUM_INTERRUPTS_LOG2 5 /* ceil(log2(NUM_INTERRUPTS)) */
|
||||
#define XCHAL_NUM_EXTINTERRUPTS 10 /* num of external interrupts */
|
||||
#define XCHAL_NUM_INTLEVELS 4 /* number of interrupt levels
|
||||
(not including level zero) */
|
||||
#define XCHAL_EXCM_LEVEL 1 /* level masked by PS.EXCM */
|
||||
/* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */
|
||||
|
||||
/* Masks of interrupts at each interrupt level: */
|
||||
#define XCHAL_INTLEVEL1_MASK 0x000064F9
|
||||
#define XCHAL_INTLEVEL2_MASK 0x00008902
|
||||
#define XCHAL_INTLEVEL3_MASK 0x00011204
|
||||
#define XCHAL_INTLEVEL4_MASK 0x00000000
|
||||
#define XCHAL_INTLEVEL5_MASK 0x00000000
|
||||
#define XCHAL_INTLEVEL6_MASK 0x00000000
|
||||
#define XCHAL_INTLEVEL7_MASK 0x00000000
|
||||
|
||||
/* Masks of interrupts at each range 1..n of interrupt levels: */
|
||||
#define XCHAL_INTLEVEL1_ANDBELOW_MASK 0x000064F9
|
||||
#define XCHAL_INTLEVEL2_ANDBELOW_MASK 0x0000EDFB
|
||||
#define XCHAL_INTLEVEL3_ANDBELOW_MASK 0x0001FFFF
|
||||
#define XCHAL_INTLEVEL4_ANDBELOW_MASK 0x0001FFFF
|
||||
#define XCHAL_INTLEVEL5_ANDBELOW_MASK 0x0001FFFF
|
||||
#define XCHAL_INTLEVEL6_ANDBELOW_MASK 0x0001FFFF
|
||||
#define XCHAL_INTLEVEL7_ANDBELOW_MASK 0x0001FFFF
|
||||
|
||||
/* Level of each interrupt: */
|
||||
#define XCHAL_INT0_LEVEL 1
|
||||
#define XCHAL_INT1_LEVEL 2
|
||||
#define XCHAL_INT2_LEVEL 3
|
||||
#define XCHAL_INT3_LEVEL 1
|
||||
#define XCHAL_INT4_LEVEL 1
|
||||
#define XCHAL_INT5_LEVEL 1
|
||||
#define XCHAL_INT6_LEVEL 1
|
||||
#define XCHAL_INT7_LEVEL 1
|
||||
#define XCHAL_INT8_LEVEL 2
|
||||
#define XCHAL_INT9_LEVEL 3
|
||||
#define XCHAL_INT10_LEVEL 1
|
||||
#define XCHAL_INT11_LEVEL 2
|
||||
#define XCHAL_INT12_LEVEL 3
|
||||
#define XCHAL_INT13_LEVEL 1
|
||||
#define XCHAL_INT14_LEVEL 1
|
||||
#define XCHAL_INT15_LEVEL 2
|
||||
#define XCHAL_INT16_LEVEL 3
|
||||
#define XCHAL_DEBUGLEVEL 4 /* debug interrupt level */
|
||||
#define XCHAL_HAVE_DEBUG_EXTERN_INT 0 /* OCD external db interrupt */
|
||||
|
||||
/* Type of each interrupt: */
|
||||
#define XCHAL_INT0_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT1_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT2_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT3_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT4_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT5_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT6_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
|
||||
#define XCHAL_INT7_TYPE XTHAL_INTTYPE_EXTERN_EDGE
|
||||
#define XCHAL_INT8_TYPE XTHAL_INTTYPE_EXTERN_EDGE
|
||||
#define XCHAL_INT9_TYPE XTHAL_INTTYPE_EXTERN_EDGE
|
||||
#define XCHAL_INT10_TYPE XTHAL_INTTYPE_TIMER
|
||||
#define XCHAL_INT11_TYPE XTHAL_INTTYPE_TIMER
|
||||
#define XCHAL_INT12_TYPE XTHAL_INTTYPE_TIMER
|
||||
#define XCHAL_INT13_TYPE XTHAL_INTTYPE_SOFTWARE
|
||||
#define XCHAL_INT14_TYPE XTHAL_INTTYPE_SOFTWARE
|
||||
#define XCHAL_INT15_TYPE XTHAL_INTTYPE_SOFTWARE
|
||||
#define XCHAL_INT16_TYPE XTHAL_INTTYPE_SOFTWARE
|
||||
|
||||
/* Masks of interrupts for each type of interrupt: */
|
||||
#define XCHAL_INTTYPE_MASK_UNCONFIGURED 0xFFFE0000
|
||||
#define XCHAL_INTTYPE_MASK_SOFTWARE 0x0001E000
|
||||
#define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x00000380
|
||||
#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL 0x0000007F
|
||||
#define XCHAL_INTTYPE_MASK_TIMER 0x00001C00
|
||||
#define XCHAL_INTTYPE_MASK_NMI 0x00000000
|
||||
#define XCHAL_INTTYPE_MASK_WRITE_ERROR 0x00000000
|
||||
|
||||
/* Interrupt numbers assigned to specific interrupt sources: */
|
||||
#define XCHAL_TIMER0_INTERRUPT 10 /* CCOMPARE0 */
|
||||
#define XCHAL_TIMER1_INTERRUPT 11 /* CCOMPARE1 */
|
||||
#define XCHAL_TIMER2_INTERRUPT 12 /* CCOMPARE2 */
|
||||
#define XCHAL_TIMER3_INTERRUPT XTHAL_TIMER_UNCONFIGURED
|
||||
|
||||
/* Interrupt numbers for levels at which only one interrupt is configured: */
|
||||
/* (There are many interrupts each at level(s) 1, 2, 3.) */
|
||||
|
||||
|
||||
/*
|
||||
* External interrupt vectors/levels.
|
||||
* These macros describe how Xtensa processor interrupt numbers
|
||||
* (as numbered internally, eg. in INTERRUPT and INTENABLE registers)
|
||||
* map to external BInterrupt<n> pins, for those interrupts
|
||||
* configured as external (level-triggered, edge-triggered, or NMI).
|
||||
* See the Xtensa processor databook for more details.
|
||||
*/
|
||||
|
||||
/* Core interrupt numbers mapped to each EXTERNAL interrupt number: */
|
||||
#define XCHAL_EXTINT0_NUM 0 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT1_NUM 1 /* (intlevel 2) */
|
||||
#define XCHAL_EXTINT2_NUM 2 /* (intlevel 3) */
|
||||
#define XCHAL_EXTINT3_NUM 3 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT4_NUM 4 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT5_NUM 5 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT6_NUM 6 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT7_NUM 7 /* (intlevel 1) */
|
||||
#define XCHAL_EXTINT8_NUM 8 /* (intlevel 2) */
|
||||
#define XCHAL_EXTINT9_NUM 9 /* (intlevel 3) */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
EXCEPTIONS and VECTORS
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_XEA_VERSION 2 /* Xtensa Exception Architecture
|
||||
number: 1 == XEA1 (old)
|
||||
2 == XEA2 (new)
|
||||
0 == XEAX (extern) */
|
||||
#define XCHAL_HAVE_XEA1 0 /* Exception Architecture 1 */
|
||||
#define XCHAL_HAVE_XEA2 1 /* Exception Architecture 2 */
|
||||
#define XCHAL_HAVE_XEAX 0 /* External Exception Arch. */
|
||||
#define XCHAL_HAVE_EXCEPTIONS 1 /* exception option */
|
||||
#define XCHAL_HAVE_MEM_ECC_PARITY 0 /* local memory ECC/parity */
|
||||
|
||||
#define XCHAL_RESET_VECTOR_VADDR 0xFE000020
|
||||
#define XCHAL_RESET_VECTOR_PADDR 0xFE000020
|
||||
#define XCHAL_USER_VECTOR_VADDR 0xD0000220
|
||||
#define XCHAL_USER_VECTOR_PADDR 0x00000220
|
||||
#define XCHAL_KERNEL_VECTOR_VADDR 0xD0000200
|
||||
#define XCHAL_KERNEL_VECTOR_PADDR 0x00000200
|
||||
#define XCHAL_DOUBLEEXC_VECTOR_VADDR 0xD0000290
|
||||
#define XCHAL_DOUBLEEXC_VECTOR_PADDR 0x00000290
|
||||
#define XCHAL_WINDOW_VECTORS_VADDR 0xD0000000
|
||||
#define XCHAL_WINDOW_VECTORS_PADDR 0x00000000
|
||||
#define XCHAL_INTLEVEL2_VECTOR_VADDR 0xD0000240
|
||||
#define XCHAL_INTLEVEL2_VECTOR_PADDR 0x00000240
|
||||
#define XCHAL_INTLEVEL3_VECTOR_VADDR 0xD0000250
|
||||
#define XCHAL_INTLEVEL3_VECTOR_PADDR 0x00000250
|
||||
#define XCHAL_INTLEVEL4_VECTOR_VADDR 0xFE000520
|
||||
#define XCHAL_INTLEVEL4_VECTOR_PADDR 0xFE000520
|
||||
#define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL4_VECTOR_VADDR
|
||||
#define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL4_VECTOR_PADDR
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
DEBUG
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
#define XCHAL_HAVE_OCD 1 /* OnChipDebug option */
|
||||
#define XCHAL_NUM_IBREAK 2 /* number of IBREAKn regs */
|
||||
#define XCHAL_NUM_DBREAK 2 /* number of DBREAKn regs */
|
||||
#define XCHAL_HAVE_OCD_DIR_ARRAY 1 /* faster OCD option */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
MMU
|
||||
----------------------------------------------------------------------*/
|
||||
|
||||
/* See <xtensa/config/core-matmap.h> header file for more details. */
|
||||
|
||||
#define XCHAL_HAVE_TLBS 1 /* inverse of HAVE_CACHEATTR */
|
||||
#define XCHAL_HAVE_SPANNING_WAY 0 /* one way maps I+D 4GB vaddr */
|
||||
#define XCHAL_HAVE_IDENTITY_MAP 0 /* vaddr == paddr always */
|
||||
#define XCHAL_HAVE_CACHEATTR 0 /* CACHEATTR register present */
|
||||
#define XCHAL_HAVE_MIMIC_CACHEATTR 0 /* region protection */
|
||||
#define XCHAL_HAVE_XLT_CACHEATTR 0 /* region prot. w/translation */
|
||||
#define XCHAL_HAVE_PTP_MMU 1 /* full MMU (with page table
|
||||
[autorefill] and protection)
|
||||
usable for an MMU-based OS */
|
||||
/* If none of the above last 4 are set, it's a custom TLB configuration. */
|
||||
#define XCHAL_ITLB_ARF_ENTRIES_LOG2 2 /* log2(autorefill way size) */
|
||||
#define XCHAL_DTLB_ARF_ENTRIES_LOG2 2 /* log2(autorefill way size) */
|
||||
|
||||
#define XCHAL_MMU_ASID_BITS 8 /* number of bits in ASIDs */
|
||||
#define XCHAL_MMU_RINGS 4 /* number of rings (1..4) */
|
||||
#define XCHAL_MMU_RING_BITS 2 /* num of bits in RING field */
|
||||
|
||||
#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */
|
||||
|
||||
|
||||
#endif /* XTENSA_FSF_CORE_ISA_H */
|
66
target/xtensa/cpu-qom.h
Normal file
66
target/xtensa/cpu-qom.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* QEMU Xtensa CPU
|
||||
*
|
||||
* Copyright (c) 2012 SUSE LINUX Products GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of the Open Source and Linux Lab 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 COPYRIGHT HOLDERS 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 AUTHOR 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.
|
||||
*/
|
||||
#ifndef QEMU_XTENSA_CPU_QOM_H
|
||||
#define QEMU_XTENSA_CPU_QOM_H
|
||||
|
||||
#include "qom/cpu.h"
|
||||
|
||||
#define TYPE_XTENSA_CPU "xtensa-cpu"
|
||||
|
||||
#define XTENSA_CPU_CLASS(class) \
|
||||
OBJECT_CLASS_CHECK(XtensaCPUClass, (class), TYPE_XTENSA_CPU)
|
||||
#define XTENSA_CPU(obj) \
|
||||
OBJECT_CHECK(XtensaCPU, (obj), TYPE_XTENSA_CPU)
|
||||
#define XTENSA_CPU_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(XtensaCPUClass, (obj), TYPE_XTENSA_CPU)
|
||||
|
||||
typedef struct XtensaConfig XtensaConfig;
|
||||
|
||||
/**
|
||||
* XtensaCPUClass:
|
||||
* @parent_realize: The parent class' realize handler.
|
||||
* @parent_reset: The parent class' reset handler.
|
||||
* @config: The CPU core configuration.
|
||||
*
|
||||
* An Xtensa CPU model.
|
||||
*/
|
||||
typedef struct XtensaCPUClass {
|
||||
/*< private >*/
|
||||
CPUClass parent_class;
|
||||
/*< public >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
|
||||
const XtensaConfig *config;
|
||||
} XtensaCPUClass;
|
||||
|
||||
typedef struct XtensaCPU XtensaCPU;
|
||||
|
||||
#endif
|
184
target/xtensa/cpu.c
Normal file
184
target/xtensa/cpu.c
Normal file
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* QEMU Xtensa CPU
|
||||
*
|
||||
* Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
|
||||
* Copyright (c) 2012 SUSE LINUX Products GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of the Open Source and Linux Lab 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 COPYRIGHT HOLDERS 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "cpu.h"
|
||||
#include "qemu-common.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "exec/exec-all.h"
|
||||
|
||||
|
||||
static void xtensa_cpu_set_pc(CPUState *cs, vaddr value)
|
||||
{
|
||||
XtensaCPU *cpu = XTENSA_CPU(cs);
|
||||
|
||||
cpu->env.pc = value;
|
||||
}
|
||||
|
||||
static bool xtensa_cpu_has_work(CPUState *cs)
|
||||
{
|
||||
XtensaCPU *cpu = XTENSA_CPU(cs);
|
||||
|
||||
return cpu->env.pending_irq_level;
|
||||
}
|
||||
|
||||
/* CPUClass::reset() */
|
||||
static void xtensa_cpu_reset(CPUState *s)
|
||||
{
|
||||
XtensaCPU *cpu = XTENSA_CPU(s);
|
||||
XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
|
||||
CPUXtensaState *env = &cpu->env;
|
||||
|
||||
xcc->parent_reset(s);
|
||||
|
||||
env->exception_taken = 0;
|
||||
env->pc = env->config->exception_vector[EXC_RESET];
|
||||
env->sregs[LITBASE] &= ~1;
|
||||
env->sregs[PS] = xtensa_option_enabled(env->config,
|
||||
XTENSA_OPTION_INTERRUPT) ? 0x1f : 0x10;
|
||||
env->sregs[VECBASE] = env->config->vecbase;
|
||||
env->sregs[IBREAKENABLE] = 0;
|
||||
env->sregs[CACHEATTR] = 0x22222222;
|
||||
env->sregs[ATOMCTL] = xtensa_option_enabled(env->config,
|
||||
XTENSA_OPTION_ATOMCTL) ? 0x28 : 0x15;
|
||||
env->sregs[CONFIGID0] = env->config->configid[0];
|
||||
env->sregs[CONFIGID1] = env->config->configid[1];
|
||||
|
||||
env->pending_irq_level = 0;
|
||||
reset_mmu(env);
|
||||
}
|
||||
|
||||
static ObjectClass *xtensa_cpu_class_by_name(const char *cpu_model)
|
||||
{
|
||||
ObjectClass *oc;
|
||||
char *typename;
|
||||
|
||||
if (cpu_model == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typename = g_strdup_printf("%s-" TYPE_XTENSA_CPU, cpu_model);
|
||||
oc = object_class_by_name(typename);
|
||||
g_free(typename);
|
||||
if (oc == NULL || !object_class_dynamic_cast(oc, TYPE_XTENSA_CPU) ||
|
||||
object_class_is_abstract(oc)) {
|
||||
return NULL;
|
||||
}
|
||||
return oc;
|
||||
}
|
||||
|
||||
static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
{
|
||||
CPUState *cs = CPU(dev);
|
||||
XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(dev);
|
||||
Error *local_err = NULL;
|
||||
|
||||
cpu_exec_realizefn(cs, &local_err);
|
||||
if (local_err != NULL) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
cs->gdb_num_regs = xcc->config->gdb_regmap.num_regs;
|
||||
|
||||
qemu_init_vcpu(cs);
|
||||
|
||||
xcc->parent_realize(dev, errp);
|
||||
}
|
||||
|
||||
static void xtensa_cpu_initfn(Object *obj)
|
||||
{
|
||||
CPUState *cs = CPU(obj);
|
||||
XtensaCPU *cpu = XTENSA_CPU(obj);
|
||||
XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(obj);
|
||||
CPUXtensaState *env = &cpu->env;
|
||||
static bool tcg_inited;
|
||||
|
||||
cs->env_ptr = env;
|
||||
env->config = xcc->config;
|
||||
|
||||
if (tcg_enabled() && !tcg_inited) {
|
||||
tcg_inited = true;
|
||||
xtensa_translate_init();
|
||||
}
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_xtensa_cpu = {
|
||||
.name = "cpu",
|
||||
.unmigratable = 1,
|
||||
};
|
||||
|
||||
static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
CPUClass *cc = CPU_CLASS(oc);
|
||||
XtensaCPUClass *xcc = XTENSA_CPU_CLASS(cc);
|
||||
|
||||
xcc->parent_realize = dc->realize;
|
||||
dc->realize = xtensa_cpu_realizefn;
|
||||
|
||||
xcc->parent_reset = cc->reset;
|
||||
cc->reset = xtensa_cpu_reset;
|
||||
|
||||
cc->class_by_name = xtensa_cpu_class_by_name;
|
||||
cc->has_work = xtensa_cpu_has_work;
|
||||
cc->do_interrupt = xtensa_cpu_do_interrupt;
|
||||
cc->cpu_exec_interrupt = xtensa_cpu_exec_interrupt;
|
||||
cc->dump_state = xtensa_cpu_dump_state;
|
||||
cc->set_pc = xtensa_cpu_set_pc;
|
||||
cc->gdb_read_register = xtensa_cpu_gdb_read_register;
|
||||
cc->gdb_write_register = xtensa_cpu_gdb_write_register;
|
||||
cc->gdb_stop_before_watchpoint = true;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
cc->do_unaligned_access = xtensa_cpu_do_unaligned_access;
|
||||
cc->get_phys_page_debug = xtensa_cpu_get_phys_page_debug;
|
||||
cc->do_unassigned_access = xtensa_cpu_do_unassigned_access;
|
||||
#endif
|
||||
cc->debug_excp_handler = xtensa_breakpoint_handler;
|
||||
dc->vmsd = &vmstate_xtensa_cpu;
|
||||
}
|
||||
|
||||
static const TypeInfo xtensa_cpu_type_info = {
|
||||
.name = TYPE_XTENSA_CPU,
|
||||
.parent = TYPE_CPU,
|
||||
.instance_size = sizeof(XtensaCPU),
|
||||
.instance_init = xtensa_cpu_initfn,
|
||||
.abstract = true,
|
||||
.class_size = sizeof(XtensaCPUClass),
|
||||
.class_init = xtensa_cpu_class_init,
|
||||
};
|
||||
|
||||
static void xtensa_cpu_register_types(void)
|
||||
{
|
||||
type_register_static(&xtensa_cpu_type_info);
|
||||
}
|
||||
|
||||
type_init(xtensa_cpu_register_types)
|
587
target/xtensa/cpu.h
Normal file
587
target/xtensa/cpu.h
Normal file
|
@ -0,0 +1,587 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of the Open Source and Linux Lab 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 COPYRIGHT HOLDERS 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
#ifndef XTENSA_CPU_H
|
||||
#define XTENSA_CPU_H
|
||||
|
||||
#define ALIGNED_ONLY
|
||||
#define TARGET_LONG_BITS 32
|
||||
|
||||
#define CPUArchState struct CPUXtensaState
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "cpu-qom.h"
|
||||
#include "exec/cpu-defs.h"
|
||||
#include "fpu/softfloat.h"
|
||||
|
||||
#define NB_MMU_MODES 4
|
||||
|
||||
#define TARGET_PHYS_ADDR_SPACE_BITS 32
|
||||
#define TARGET_VIRT_ADDR_SPACE_BITS 32
|
||||
#define TARGET_PAGE_BITS 12
|
||||
|
||||
enum {
|
||||
/* Additional instructions */
|
||||
XTENSA_OPTION_CODE_DENSITY,
|
||||
XTENSA_OPTION_LOOP,
|
||||
XTENSA_OPTION_EXTENDED_L32R,
|
||||
XTENSA_OPTION_16_BIT_IMUL,
|
||||
XTENSA_OPTION_32_BIT_IMUL,
|
||||
XTENSA_OPTION_32_BIT_IMUL_HIGH,
|
||||
XTENSA_OPTION_32_BIT_IDIV,
|
||||
XTENSA_OPTION_MAC16,
|
||||
XTENSA_OPTION_MISC_OP_NSA,
|
||||
XTENSA_OPTION_MISC_OP_MINMAX,
|
||||
XTENSA_OPTION_MISC_OP_SEXT,
|
||||
XTENSA_OPTION_MISC_OP_CLAMPS,
|
||||
XTENSA_OPTION_COPROCESSOR,
|
||||
XTENSA_OPTION_BOOLEAN,
|
||||
XTENSA_OPTION_FP_COPROCESSOR,
|
||||
XTENSA_OPTION_MP_SYNCHRO,
|
||||
XTENSA_OPTION_CONDITIONAL_STORE,
|
||||
XTENSA_OPTION_ATOMCTL,
|
||||
XTENSA_OPTION_DEPBITS,
|
||||
|
||||
/* Interrupts and exceptions */
|
||||
XTENSA_OPTION_EXCEPTION,
|
||||
XTENSA_OPTION_RELOCATABLE_VECTOR,
|
||||
XTENSA_OPTION_UNALIGNED_EXCEPTION,
|
||||
XTENSA_OPTION_INTERRUPT,
|
||||
XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
|
||||
XTENSA_OPTION_TIMER_INTERRUPT,
|
||||
|
||||
/* Local memory */
|
||||
XTENSA_OPTION_ICACHE,
|
||||
XTENSA_OPTION_ICACHE_TEST,
|
||||
XTENSA_OPTION_ICACHE_INDEX_LOCK,
|
||||
XTENSA_OPTION_DCACHE,
|
||||
XTENSA_OPTION_DCACHE_TEST,
|
||||
XTENSA_OPTION_DCACHE_INDEX_LOCK,
|
||||
XTENSA_OPTION_IRAM,
|
||||
XTENSA_OPTION_IROM,
|
||||
XTENSA_OPTION_DRAM,
|
||||
XTENSA_OPTION_DROM,
|
||||
XTENSA_OPTION_XLMI,
|
||||
XTENSA_OPTION_HW_ALIGNMENT,
|
||||
XTENSA_OPTION_MEMORY_ECC_PARITY,
|
||||
|
||||
/* Memory protection and translation */
|
||||
XTENSA_OPTION_REGION_PROTECTION,
|
||||
XTENSA_OPTION_REGION_TRANSLATION,
|
||||
XTENSA_OPTION_MMU,
|
||||
XTENSA_OPTION_CACHEATTR,
|
||||
|
||||
/* Other */
|
||||
XTENSA_OPTION_WINDOWED_REGISTER,
|
||||
XTENSA_OPTION_PROCESSOR_INTERFACE,
|
||||
XTENSA_OPTION_MISC_SR,
|
||||
XTENSA_OPTION_THREAD_POINTER,
|
||||
XTENSA_OPTION_PROCESSOR_ID,
|
||||
XTENSA_OPTION_DEBUG,
|
||||
XTENSA_OPTION_TRACE_PORT,
|
||||
};
|
||||
|
||||
enum {
|
||||
THREADPTR = 231,
|
||||
FCR = 232,
|
||||
FSR = 233,
|
||||
};
|
||||
|
||||
enum {
|
||||
LBEG = 0,
|
||||
LEND = 1,
|
||||
LCOUNT = 2,
|
||||
SAR = 3,
|
||||
BR = 4,
|
||||
LITBASE = 5,
|
||||
SCOMPARE1 = 12,
|
||||
ACCLO = 16,
|
||||
ACCHI = 17,
|
||||
MR = 32,
|
||||
WINDOW_BASE = 72,
|
||||
WINDOW_START = 73,
|
||||
PTEVADDR = 83,
|
||||
RASID = 90,
|
||||
ITLBCFG = 91,
|
||||
DTLBCFG = 92,
|
||||
IBREAKENABLE = 96,
|
||||
CACHEATTR = 98,
|
||||
ATOMCTL = 99,
|
||||
IBREAKA = 128,
|
||||
DBREAKA = 144,
|
||||
DBREAKC = 160,
|
||||
CONFIGID0 = 176,
|
||||
EPC1 = 177,
|
||||
DEPC = 192,
|
||||
EPS2 = 194,
|
||||
CONFIGID1 = 208,
|
||||
EXCSAVE1 = 209,
|
||||
CPENABLE = 224,
|
||||
INTSET = 226,
|
||||
INTCLEAR = 227,
|
||||
INTENABLE = 228,
|
||||
PS = 230,
|
||||
VECBASE = 231,
|
||||
EXCCAUSE = 232,
|
||||
DEBUGCAUSE = 233,
|
||||
CCOUNT = 234,
|
||||
PRID = 235,
|
||||
ICOUNT = 236,
|
||||
ICOUNTLEVEL = 237,
|
||||
EXCVADDR = 238,
|
||||
CCOMPARE = 240,
|
||||
MISC = 244,
|
||||
};
|
||||
|
||||
#define PS_INTLEVEL 0xf
|
||||
#define PS_INTLEVEL_SHIFT 0
|
||||
|
||||
#define PS_EXCM 0x10
|
||||
#define PS_UM 0x20
|
||||
|
||||
#define PS_RING 0xc0
|
||||
#define PS_RING_SHIFT 6
|
||||
|
||||
#define PS_OWB 0xf00
|
||||
#define PS_OWB_SHIFT 8
|
||||
|
||||
#define PS_CALLINC 0x30000
|
||||
#define PS_CALLINC_SHIFT 16
|
||||
#define PS_CALLINC_LEN 2
|
||||
|
||||
#define PS_WOE 0x40000
|
||||
|
||||
#define DEBUGCAUSE_IC 0x1
|
||||
#define DEBUGCAUSE_IB 0x2
|
||||
#define DEBUGCAUSE_DB 0x4
|
||||
#define DEBUGCAUSE_BI 0x8
|
||||
#define DEBUGCAUSE_BN 0x10
|
||||
#define DEBUGCAUSE_DI 0x20
|
||||
#define DEBUGCAUSE_DBNUM 0xf00
|
||||
#define DEBUGCAUSE_DBNUM_SHIFT 8
|
||||
|
||||
#define DBREAKC_SB 0x80000000
|
||||
#define DBREAKC_LB 0x40000000
|
||||
#define DBREAKC_SB_LB (DBREAKC_SB | DBREAKC_LB)
|
||||
#define DBREAKC_MASK 0x3f
|
||||
|
||||
#define MAX_NAREG 64
|
||||
#define MAX_NINTERRUPT 32
|
||||
#define MAX_NLEVEL 6
|
||||
#define MAX_NNMI 1
|
||||
#define MAX_NCCOMPARE 3
|
||||
#define MAX_TLB_WAY_SIZE 8
|
||||
#define MAX_NDBREAK 2
|
||||
|
||||
#define REGION_PAGE_MASK 0xe0000000
|
||||
|
||||
#define PAGE_CACHE_MASK 0x700
|
||||
#define PAGE_CACHE_SHIFT 8
|
||||
#define PAGE_CACHE_INVALID 0x000
|
||||
#define PAGE_CACHE_BYPASS 0x100
|
||||
#define PAGE_CACHE_WT 0x200
|
||||
#define PAGE_CACHE_WB 0x400
|
||||
#define PAGE_CACHE_ISOLATE 0x600
|
||||
|
||||
enum {
|
||||
/* Static vectors */
|
||||
EXC_RESET,
|
||||
EXC_MEMORY_ERROR,
|
||||
|
||||
/* Dynamic vectors */
|
||||
EXC_WINDOW_OVERFLOW4,
|
||||
EXC_WINDOW_UNDERFLOW4,
|
||||
EXC_WINDOW_OVERFLOW8,
|
||||
EXC_WINDOW_UNDERFLOW8,
|
||||
EXC_WINDOW_OVERFLOW12,
|
||||
EXC_WINDOW_UNDERFLOW12,
|
||||
EXC_IRQ,
|
||||
EXC_KERNEL,
|
||||
EXC_USER,
|
||||
EXC_DOUBLE,
|
||||
EXC_DEBUG,
|
||||
EXC_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
ILLEGAL_INSTRUCTION_CAUSE = 0,
|
||||
SYSCALL_CAUSE,
|
||||
INSTRUCTION_FETCH_ERROR_CAUSE,
|
||||
LOAD_STORE_ERROR_CAUSE,
|
||||
LEVEL1_INTERRUPT_CAUSE,
|
||||
ALLOCA_CAUSE,
|
||||
INTEGER_DIVIDE_BY_ZERO_CAUSE,
|
||||
PRIVILEGED_CAUSE = 8,
|
||||
LOAD_STORE_ALIGNMENT_CAUSE,
|
||||
|
||||
INSTR_PIF_DATA_ERROR_CAUSE = 12,
|
||||
LOAD_STORE_PIF_DATA_ERROR_CAUSE,
|
||||
INSTR_PIF_ADDR_ERROR_CAUSE,
|
||||
LOAD_STORE_PIF_ADDR_ERROR_CAUSE,
|
||||
|
||||
INST_TLB_MISS_CAUSE,
|
||||
INST_TLB_MULTI_HIT_CAUSE,
|
||||
INST_FETCH_PRIVILEGE_CAUSE,
|
||||
INST_FETCH_PROHIBITED_CAUSE = 20,
|
||||
LOAD_STORE_TLB_MISS_CAUSE = 24,
|
||||
LOAD_STORE_TLB_MULTI_HIT_CAUSE,
|
||||
LOAD_STORE_PRIVILEGE_CAUSE,
|
||||
LOAD_PROHIBITED_CAUSE = 28,
|
||||
STORE_PROHIBITED_CAUSE,
|
||||
|
||||
COPROCESSOR0_DISABLED = 32,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
INTTYPE_LEVEL,
|
||||
INTTYPE_EDGE,
|
||||
INTTYPE_NMI,
|
||||
INTTYPE_SOFTWARE,
|
||||
INTTYPE_TIMER,
|
||||
INTTYPE_DEBUG,
|
||||
INTTYPE_WRITE_ERR,
|
||||
INTTYPE_PROFILING,
|
||||
INTTYPE_MAX
|
||||
} interrupt_type;
|
||||
|
||||
typedef struct xtensa_tlb_entry {
|
||||
uint32_t vaddr;
|
||||
uint32_t paddr;
|
||||
uint8_t asid;
|
||||
uint8_t attr;
|
||||
bool variable;
|
||||
} xtensa_tlb_entry;
|
||||
|
||||
typedef struct xtensa_tlb {
|
||||
unsigned nways;
|
||||
const unsigned way_size[10];
|
||||
bool varway56;
|
||||
unsigned nrefillentries;
|
||||
} xtensa_tlb;
|
||||
|
||||
typedef struct XtensaGdbReg {
|
||||
int targno;
|
||||
int type;
|
||||
int group;
|
||||
unsigned size;
|
||||
} XtensaGdbReg;
|
||||
|
||||
typedef struct XtensaGdbRegmap {
|
||||
int num_regs;
|
||||
int num_core_regs;
|
||||
/* PC + a + ar + sr + ur */
|
||||
XtensaGdbReg reg[1 + 16 + 64 + 256 + 256];
|
||||
} XtensaGdbRegmap;
|
||||
|
||||
struct XtensaConfig {
|
||||
const char *name;
|
||||
uint64_t options;
|
||||
XtensaGdbRegmap gdb_regmap;
|
||||
unsigned nareg;
|
||||
int excm_level;
|
||||
int ndepc;
|
||||
uint32_t vecbase;
|
||||
uint32_t exception_vector[EXC_MAX];
|
||||
unsigned ninterrupt;
|
||||
unsigned nlevel;
|
||||
uint32_t interrupt_vector[MAX_NLEVEL + MAX_NNMI + 1];
|
||||
uint32_t level_mask[MAX_NLEVEL + MAX_NNMI + 1];
|
||||
uint32_t inttype_mask[INTTYPE_MAX];
|
||||
struct {
|
||||
uint32_t level;
|
||||
interrupt_type inttype;
|
||||
} interrupt[MAX_NINTERRUPT];
|
||||
unsigned nccompare;
|
||||
uint32_t timerint[MAX_NCCOMPARE];
|
||||
unsigned nextint;
|
||||
unsigned extint[MAX_NINTERRUPT];
|
||||
|
||||
unsigned debug_level;
|
||||
unsigned nibreak;
|
||||
unsigned ndbreak;
|
||||
|
||||
uint32_t configid[2];
|
||||
|
||||
uint32_t clock_freq_khz;
|
||||
|
||||
xtensa_tlb itlb;
|
||||
xtensa_tlb dtlb;
|
||||
};
|
||||
|
||||
typedef struct XtensaConfigList {
|
||||
const XtensaConfig *config;
|
||||
struct XtensaConfigList *next;
|
||||
} XtensaConfigList;
|
||||
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
enum {
|
||||
FP_F32_HIGH,
|
||||
FP_F32_LOW,
|
||||
};
|
||||
#else
|
||||
enum {
|
||||
FP_F32_LOW,
|
||||
FP_F32_HIGH,
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct CPUXtensaState {
|
||||
const XtensaConfig *config;
|
||||
uint32_t regs[16];
|
||||
uint32_t pc;
|
||||
uint32_t sregs[256];
|
||||
uint32_t uregs[256];
|
||||
uint32_t phys_regs[MAX_NAREG];
|
||||
union {
|
||||
float32 f32[2];
|
||||
float64 f64;
|
||||
} fregs[16];
|
||||
float_status fp_status;
|
||||
|
||||
xtensa_tlb_entry itlb[7][MAX_TLB_WAY_SIZE];
|
||||
xtensa_tlb_entry dtlb[10][MAX_TLB_WAY_SIZE];
|
||||
unsigned autorefill_idx;
|
||||
|
||||
int pending_irq_level; /* level of last raised IRQ */
|
||||
void **irq_inputs;
|
||||
QEMUTimer *ccompare_timer;
|
||||
uint32_t wake_ccount;
|
||||
int64_t halt_clock;
|
||||
|
||||
int exception_taken;
|
||||
|
||||
/* Watchpoints for DBREAK registers */
|
||||
struct CPUWatchpoint *cpu_watchpoint[MAX_NDBREAK];
|
||||
|
||||
CPU_COMMON
|
||||
} CPUXtensaState;
|
||||
|
||||
/**
|
||||
* XtensaCPU:
|
||||
* @env: #CPUXtensaState
|
||||
*
|
||||
* An Xtensa CPU.
|
||||
*/
|
||||
struct XtensaCPU {
|
||||
/*< private >*/
|
||||
CPUState parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
CPUXtensaState env;
|
||||
};
|
||||
|
||||
static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env)
|
||||
{
|
||||
return container_of(env, XtensaCPU, env);
|
||||
}
|
||||
|
||||
#define ENV_GET_CPU(e) CPU(xtensa_env_get_cpu(e))
|
||||
|
||||
#define ENV_OFFSET offsetof(XtensaCPU, env)
|
||||
|
||||
void xtensa_cpu_do_interrupt(CPUState *cpu);
|
||||
bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
|
||||
void xtensa_cpu_do_unassigned_access(CPUState *cpu, hwaddr addr,
|
||||
bool is_write, bool is_exec, int opaque,
|
||||
unsigned size);
|
||||
void xtensa_cpu_dump_state(CPUState *cpu, FILE *f,
|
||||
fprintf_function cpu_fprintf, int flags);
|
||||
hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||
int xtensa_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
|
||||
int xtensa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
|
||||
void xtensa_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
|
||||
MMUAccessType access_type,
|
||||
int mmu_idx, uintptr_t retaddr);
|
||||
|
||||
#define cpu_signal_handler cpu_xtensa_signal_handler
|
||||
#define cpu_list xtensa_cpu_list
|
||||
|
||||
#ifdef TARGET_WORDS_BIGENDIAN
|
||||
#define XTENSA_DEFAULT_CPU_MODEL "fsf"
|
||||
#else
|
||||
#define XTENSA_DEFAULT_CPU_MODEL "dc232b"
|
||||
#endif
|
||||
|
||||
XtensaCPU *cpu_xtensa_init(const char *cpu_model);
|
||||
|
||||
#define cpu_init(cpu_model) CPU(cpu_xtensa_init(cpu_model))
|
||||
|
||||
void xtensa_translate_init(void);
|
||||
void xtensa_breakpoint_handler(CPUState *cs);
|
||||
void xtensa_finalize_config(XtensaConfig *config);
|
||||
void xtensa_register_core(XtensaConfigList *node);
|
||||
void check_interrupts(CPUXtensaState *s);
|
||||
void xtensa_irq_init(CPUXtensaState *env);
|
||||
void *xtensa_get_extint(CPUXtensaState *env, unsigned extint);
|
||||
void xtensa_advance_ccount(CPUXtensaState *env, uint32_t d);
|
||||
void xtensa_timer_irq(CPUXtensaState *env, uint32_t id, uint32_t active);
|
||||
void xtensa_rearm_ccompare_timer(CPUXtensaState *env);
|
||||
int cpu_xtensa_signal_handler(int host_signum, void *pinfo, void *puc);
|
||||
void xtensa_cpu_list(FILE *f, fprintf_function cpu_fprintf);
|
||||
void xtensa_sync_window_from_phys(CPUXtensaState *env);
|
||||
void xtensa_sync_phys_from_window(CPUXtensaState *env);
|
||||
uint32_t xtensa_tlb_get_addr_mask(const CPUXtensaState *env, bool dtlb, uint32_t way);
|
||||
void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, bool dtlb,
|
||||
uint32_t *vpn, uint32_t wi, uint32_t *ei);
|
||||
int xtensa_tlb_lookup(const CPUXtensaState *env, uint32_t addr, bool dtlb,
|
||||
uint32_t *pwi, uint32_t *pei, uint8_t *pring);
|
||||
void xtensa_tlb_set_entry_mmu(const CPUXtensaState *env,
|
||||
xtensa_tlb_entry *entry, bool dtlb,
|
||||
unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte);
|
||||
void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb,
|
||||
unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte);
|
||||
int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb,
|
||||
uint32_t vaddr, int is_write, int mmu_idx,
|
||||
uint32_t *paddr, uint32_t *page_size, unsigned *access);
|
||||
void reset_mmu(CPUXtensaState *env);
|
||||
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUXtensaState *env);
|
||||
void debug_exception_env(CPUXtensaState *new_env, uint32_t cause);
|
||||
|
||||
|
||||
#define XTENSA_OPTION_BIT(opt) (((uint64_t)1) << (opt))
|
||||
#define XTENSA_OPTION_ALL (~(uint64_t)0)
|
||||
|
||||
static inline bool xtensa_option_bits_enabled(const XtensaConfig *config,
|
||||
uint64_t opt)
|
||||
{
|
||||
return (config->options & opt) != 0;
|
||||
}
|
||||
|
||||
static inline bool xtensa_option_enabled(const XtensaConfig *config, int opt)
|
||||
{
|
||||
return xtensa_option_bits_enabled(config, XTENSA_OPTION_BIT(opt));
|
||||
}
|
||||
|
||||
static inline int xtensa_get_cintlevel(const CPUXtensaState *env)
|
||||
{
|
||||
int level = (env->sregs[PS] & PS_INTLEVEL) >> PS_INTLEVEL_SHIFT;
|
||||
if ((env->sregs[PS] & PS_EXCM) && env->config->excm_level > level) {
|
||||
level = env->config->excm_level;
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
static inline int xtensa_get_ring(const CPUXtensaState *env)
|
||||
{
|
||||
if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
|
||||
return (env->sregs[PS] & PS_RING) >> PS_RING_SHIFT;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int xtensa_get_cring(const CPUXtensaState *env)
|
||||
{
|
||||
if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU) &&
|
||||
(env->sregs[PS] & PS_EXCM) == 0) {
|
||||
return (env->sregs[PS] & PS_RING) >> PS_RING_SHIFT;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline xtensa_tlb_entry *xtensa_tlb_get_entry(CPUXtensaState *env,
|
||||
bool dtlb, unsigned wi, unsigned ei)
|
||||
{
|
||||
return dtlb ?
|
||||
env->dtlb[wi] + ei :
|
||||
env->itlb[wi] + ei;
|
||||
}
|
||||
|
||||
static inline uint32_t xtensa_replicate_windowstart(CPUXtensaState *env)
|
||||
{
|
||||
return env->sregs[WINDOW_START] |
|
||||
(env->sregs[WINDOW_START] << env->config->nareg / 4);
|
||||
}
|
||||
|
||||
/* MMU modes definitions */
|
||||
#define MMU_MODE0_SUFFIX _ring0
|
||||
#define MMU_MODE1_SUFFIX _ring1
|
||||
#define MMU_MODE2_SUFFIX _ring2
|
||||
#define MMU_MODE3_SUFFIX _ring3
|
||||
|
||||
static inline int cpu_mmu_index(CPUXtensaState *env, bool ifetch)
|
||||
{
|
||||
return xtensa_get_cring(env);
|
||||
}
|
||||
|
||||
#define XTENSA_TBFLAG_RING_MASK 0x3
|
||||
#define XTENSA_TBFLAG_EXCM 0x4
|
||||
#define XTENSA_TBFLAG_LITBASE 0x8
|
||||
#define XTENSA_TBFLAG_DEBUG 0x10
|
||||
#define XTENSA_TBFLAG_ICOUNT 0x20
|
||||
#define XTENSA_TBFLAG_CPENABLE_MASK 0x3fc0
|
||||
#define XTENSA_TBFLAG_CPENABLE_SHIFT 6
|
||||
#define XTENSA_TBFLAG_EXCEPTION 0x4000
|
||||
#define XTENSA_TBFLAG_WINDOW_MASK 0x18000
|
||||
#define XTENSA_TBFLAG_WINDOW_SHIFT 15
|
||||
|
||||
static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
|
||||
target_ulong *cs_base, uint32_t *flags)
|
||||
{
|
||||
CPUState *cs = CPU(xtensa_env_get_cpu(env));
|
||||
|
||||
*pc = env->pc;
|
||||
*cs_base = 0;
|
||||
*flags = 0;
|
||||
*flags |= xtensa_get_ring(env);
|
||||
if (env->sregs[PS] & PS_EXCM) {
|
||||
*flags |= XTENSA_TBFLAG_EXCM;
|
||||
}
|
||||
if (xtensa_option_enabled(env->config, XTENSA_OPTION_EXTENDED_L32R) &&
|
||||
(env->sregs[LITBASE] & 1)) {
|
||||
*flags |= XTENSA_TBFLAG_LITBASE;
|
||||
}
|
||||
if (xtensa_option_enabled(env->config, XTENSA_OPTION_DEBUG)) {
|
||||
if (xtensa_get_cintlevel(env) < env->config->debug_level) {
|
||||
*flags |= XTENSA_TBFLAG_DEBUG;
|
||||
}
|
||||
if (xtensa_get_cintlevel(env) < env->sregs[ICOUNTLEVEL]) {
|
||||
*flags |= XTENSA_TBFLAG_ICOUNT;
|
||||
}
|
||||
}
|
||||
if (xtensa_option_enabled(env->config, XTENSA_OPTION_COPROCESSOR)) {
|
||||
*flags |= env->sregs[CPENABLE] << XTENSA_TBFLAG_CPENABLE_SHIFT;
|
||||
}
|
||||
if (cs->singlestep_enabled && env->exception_taken) {
|
||||
*flags |= XTENSA_TBFLAG_EXCEPTION;
|
||||
}
|
||||
if (xtensa_option_enabled(env->config, XTENSA_OPTION_WINDOWED_REGISTER) &&
|
||||
(env->sregs[PS] & (PS_WOE | PS_EXCM)) == PS_WOE) {
|
||||
uint32_t windowstart = xtensa_replicate_windowstart(env) >>
|
||||
(env->sregs[WINDOW_BASE] + 1);
|
||||
uint32_t w = ctz32(windowstart | 0x8);
|
||||
|
||||
*flags |= w << XTENSA_TBFLAG_WINDOW_SHIFT;
|
||||
} else {
|
||||
*flags |= 3 << XTENSA_TBFLAG_WINDOW_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
#include "exec/cpu-all.h"
|
||||
|
||||
#endif
|
128
target/xtensa/gdbstub.c
Normal file
128
target/xtensa/gdbstub.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Xtensa gdb server stub
|
||||
*
|
||||
* Copyright (c) 2003-2005 Fabrice Bellard
|
||||
* Copyright (c) 2013 SUSE LINUX Products GmbH
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu-common.h"
|
||||
#include "cpu.h"
|
||||
#include "exec/gdbstub.h"
|
||||
#include "qemu/log.h"
|
||||
|
||||
int xtensa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
|
||||
{
|
||||
XtensaCPU *cpu = XTENSA_CPU(cs);
|
||||
CPUXtensaState *env = &cpu->env;
|
||||
const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
|
||||
unsigned i;
|
||||
|
||||
if (n < 0 || n >= env->config->gdb_regmap.num_regs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (reg->type) {
|
||||
case 9: /*pc*/
|
||||
return gdb_get_reg32(mem_buf, env->pc);
|
||||
|
||||
case 1: /*ar*/
|
||||
xtensa_sync_phys_from_window(env);
|
||||
return gdb_get_reg32(mem_buf, env->phys_regs[(reg->targno & 0xff)
|
||||
% env->config->nareg]);
|
||||
|
||||
case 2: /*SR*/
|
||||
return gdb_get_reg32(mem_buf, env->sregs[reg->targno & 0xff]);
|
||||
|
||||
case 3: /*UR*/
|
||||
return gdb_get_reg32(mem_buf, env->uregs[reg->targno & 0xff]);
|
||||
|
||||
case 4: /*f*/
|
||||
i = reg->targno & 0x0f;
|
||||
switch (reg->size) {
|
||||
case 4:
|
||||
return gdb_get_reg32(mem_buf,
|
||||
float32_val(env->fregs[i].f32[FP_F32_LOW]));
|
||||
case 8:
|
||||
return gdb_get_reg64(mem_buf, float64_val(env->fregs[i].f64));
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
case 8: /*a*/
|
||||
return gdb_get_reg32(mem_buf, env->regs[reg->targno & 0x0f]);
|
||||
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "%s from reg %d of unsupported type %d\n",
|
||||
__func__, n, reg->type);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int xtensa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
||||
{
|
||||
XtensaCPU *cpu = XTENSA_CPU(cs);
|
||||
CPUXtensaState *env = &cpu->env;
|
||||
uint32_t tmp;
|
||||
const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
|
||||
|
||||
if (n < 0 || n >= env->config->gdb_regmap.num_regs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp = ldl_p(mem_buf);
|
||||
|
||||
switch (reg->type) {
|
||||
case 9: /*pc*/
|
||||
env->pc = tmp;
|
||||
break;
|
||||
|
||||
case 1: /*ar*/
|
||||
env->phys_regs[(reg->targno & 0xff) % env->config->nareg] = tmp;
|
||||
xtensa_sync_window_from_phys(env);
|
||||
break;
|
||||
|
||||
case 2: /*SR*/
|
||||
env->sregs[reg->targno & 0xff] = tmp;
|
||||
break;
|
||||
|
||||
case 3: /*UR*/
|
||||
env->uregs[reg->targno & 0xff] = tmp;
|
||||
break;
|
||||
|
||||
case 4: /*f*/
|
||||
switch (reg->size) {
|
||||
case 4:
|
||||
env->fregs[reg->targno & 0x0f].f32[FP_F32_LOW] = make_float32(tmp);
|
||||
return 4;
|
||||
case 8:
|
||||
env->fregs[reg->targno & 0x0f].f64 = make_float64(tmp);
|
||||
return 8;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
case 8: /*a*/
|
||||
env->regs[reg->targno & 0x0f] = tmp;
|
||||
break;
|
||||
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "%s to reg %d of unsupported type %d\n",
|
||||
__func__, n, reg->type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
730
target/xtensa/helper.c
Normal file
730
target/xtensa/helper.c
Normal file
|
@ -0,0 +1,730 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of the Open Source and Linux Lab 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 COPYRIGHT HOLDERS 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "exec/gdbstub.h"
|
||||
#include "qemu/host-utils.h"
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
#include "hw/loader.h"
|
||||
#endif
|
||||
|
||||
static struct XtensaConfigList *xtensa_cores;
|
||||
|
||||
static void xtensa_core_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
CPUClass *cc = CPU_CLASS(oc);
|
||||
XtensaCPUClass *xcc = XTENSA_CPU_CLASS(oc);
|
||||
const XtensaConfig *config = data;
|
||||
|
||||
xcc->config = config;
|
||||
|
||||
/* Use num_core_regs to see only non-privileged registers in an unmodified
|
||||
* gdb. Use num_regs to see all registers. gdb modification is required
|
||||
* for that: reset bit 0 in the 'flags' field of the registers definitions
|
||||
* in the gdb/xtensa-config.c inside gdb source tree or inside gdb overlay.
|
||||
*/
|
||||
cc->gdb_num_core_regs = config->gdb_regmap.num_regs;
|
||||
}
|
||||
|
||||
void xtensa_finalize_config(XtensaConfig *config)
|
||||
{
|
||||
unsigned i, n = 0;
|
||||
|
||||
if (config->gdb_regmap.num_regs) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; config->gdb_regmap.reg[i].targno >= 0; ++i) {
|
||||
n += (config->gdb_regmap.reg[i].type != 6);
|
||||
}
|
||||
config->gdb_regmap.num_regs = n;
|
||||
}
|
||||
|
||||
void xtensa_register_core(XtensaConfigList *node)
|
||||
{
|
||||
TypeInfo type = {
|
||||
.parent = TYPE_XTENSA_CPU,
|
||||
.class_init = xtensa_core_class_init,
|
||||
.class_data = (void *)node->config,
|
||||
};
|
||||
|
||||
node->next = xtensa_cores;
|
||||
xtensa_cores = node;
|
||||
type.name = g_strdup_printf("%s-" TYPE_XTENSA_CPU, node->config->name);
|
||||
type_register(&type);
|
||||
g_free((gpointer)type.name);
|
||||
}
|
||||
|
||||
static uint32_t check_hw_breakpoints(CPUXtensaState *env)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < env->config->ndbreak; ++i) {
|
||||
if (env->cpu_watchpoint[i] &&
|
||||
env->cpu_watchpoint[i]->flags & BP_WATCHPOINT_HIT) {
|
||||
return DEBUGCAUSE_DB | (i << DEBUGCAUSE_DBNUM_SHIFT);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void xtensa_breakpoint_handler(CPUState *cs)
|
||||
{
|
||||
XtensaCPU *cpu = XTENSA_CPU(cs);
|
||||
CPUXtensaState *env = &cpu->env;
|
||||
|
||||
if (cs->watchpoint_hit) {
|
||||
if (cs->watchpoint_hit->flags & BP_CPU) {
|
||||
uint32_t cause;
|
||||
|
||||
cs->watchpoint_hit = NULL;
|
||||
cause = check_hw_breakpoints(env);
|
||||
if (cause) {
|
||||
debug_exception_env(env, cause);
|
||||
}
|
||||
cpu_loop_exit_noexc(cs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XtensaCPU *cpu_xtensa_init(const char *cpu_model)
|
||||
{
|
||||
ObjectClass *oc;
|
||||
XtensaCPU *cpu;
|
||||
CPUXtensaState *env;
|
||||
|
||||
oc = cpu_class_by_name(TYPE_XTENSA_CPU, cpu_model);
|
||||
if (oc == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cpu = XTENSA_CPU(object_new(object_class_get_name(oc)));
|
||||
env = &cpu->env;
|
||||
|
||||
xtensa_irq_init(env);
|
||||
|
||||
object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
|
||||
|
||||
return cpu;
|
||||
}
|
||||
|
||||
|
||||
void xtensa_cpu_list(FILE *f, fprintf_function cpu_fprintf)
|
||||
{
|
||||
XtensaConfigList *core = xtensa_cores;
|
||||
cpu_fprintf(f, "Available CPUs:\n");
|
||||
for (; core; core = core->next) {
|
||||
cpu_fprintf(f, " %s\n", core->config->name);
|
||||
}
|
||||
}
|
||||
|
||||
hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
{
|
||||
XtensaCPU *cpu = XTENSA_CPU(cs);
|
||||
uint32_t paddr;
|
||||
uint32_t page_size;
|
||||
unsigned access;
|
||||
|
||||
if (xtensa_get_physical_addr(&cpu->env, false, addr, 0, 0,
|
||||
&paddr, &page_size, &access) == 0) {
|
||||
return paddr;
|
||||
}
|
||||
if (xtensa_get_physical_addr(&cpu->env, false, addr, 2, 0,
|
||||
&paddr, &page_size, &access) == 0) {
|
||||
return paddr;
|
||||
}
|
||||
return ~0;
|
||||
}
|
||||
|
||||
static uint32_t relocated_vector(CPUXtensaState *env, uint32_t vector)
|
||||
{
|
||||
if (xtensa_option_enabled(env->config,
|
||||
XTENSA_OPTION_RELOCATABLE_VECTOR)) {
|
||||
return vector - env->config->vecbase + env->sregs[VECBASE];
|
||||
} else {
|
||||
return vector;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Handle penging IRQ.
|
||||
* For the high priority interrupt jump to the corresponding interrupt vector.
|
||||
* For the level-1 interrupt convert it to either user, kernel or double
|
||||
* exception with the 'level-1 interrupt' exception cause.
|
||||
*/
|
||||
static void handle_interrupt(CPUXtensaState *env)
|
||||
{
|
||||
int level = env->pending_irq_level;
|
||||
|
||||
if (level > xtensa_get_cintlevel(env) &&
|
||||
level <= env->config->nlevel &&
|
||||
(env->config->level_mask[level] &
|
||||
env->sregs[INTSET] &
|
||||
env->sregs[INTENABLE])) {
|
||||
CPUState *cs = CPU(xtensa_env_get_cpu(env));
|
||||
|
||||
if (level > 1) {
|
||||
env->sregs[EPC1 + level - 1] = env->pc;
|
||||
env->sregs[EPS2 + level - 2] = env->sregs[PS];
|
||||
env->sregs[PS] =
|
||||
(env->sregs[PS] & ~PS_INTLEVEL) | level | PS_EXCM;
|
||||
env->pc = relocated_vector(env,
|
||||
env->config->interrupt_vector[level]);
|
||||
} else {
|
||||
env->sregs[EXCCAUSE] = LEVEL1_INTERRUPT_CAUSE;
|
||||
|
||||
if (env->sregs[PS] & PS_EXCM) {
|
||||
if (env->config->ndepc) {
|
||||
env->sregs[DEPC] = env->pc;
|
||||
} else {
|
||||
env->sregs[EPC1] = env->pc;
|
||||
}
|
||||
cs->exception_index = EXC_DOUBLE;
|
||||
} else {
|
||||
env->sregs[EPC1] = env->pc;
|
||||
cs->exception_index =
|
||||
(env->sregs[PS] & PS_UM) ? EXC_USER : EXC_KERNEL;
|
||||
}
|
||||
env->sregs[PS] |= PS_EXCM;
|
||||
}
|
||||
env->exception_taken = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void xtensa_cpu_do_interrupt(CPUState *cs)
|
||||
{
|
||||
XtensaCPU *cpu = XTENSA_CPU(cs);
|
||||
CPUXtensaState *env = &cpu->env;
|
||||
|
||||
if (cs->exception_index == EXC_IRQ) {
|
||||
qemu_log_mask(CPU_LOG_INT,
|
||||
"%s(EXC_IRQ) level = %d, cintlevel = %d, "
|
||||
"pc = %08x, a0 = %08x, ps = %08x, "
|
||||
"intset = %08x, intenable = %08x, "
|
||||
"ccount = %08x\n",
|
||||
__func__, env->pending_irq_level, xtensa_get_cintlevel(env),
|
||||
env->pc, env->regs[0], env->sregs[PS],
|
||||
env->sregs[INTSET], env->sregs[INTENABLE],
|
||||
env->sregs[CCOUNT]);
|
||||
handle_interrupt(env);
|
||||
}
|
||||
|
||||
switch (cs->exception_index) {
|
||||
case EXC_WINDOW_OVERFLOW4:
|
||||
case EXC_WINDOW_UNDERFLOW4:
|
||||
case EXC_WINDOW_OVERFLOW8:
|
||||
case EXC_WINDOW_UNDERFLOW8:
|
||||
case EXC_WINDOW_OVERFLOW12:
|
||||
case EXC_WINDOW_UNDERFLOW12:
|
||||
case EXC_KERNEL:
|
||||
case EXC_USER:
|
||||
case EXC_DOUBLE:
|
||||
case EXC_DEBUG:
|
||||
qemu_log_mask(CPU_LOG_INT, "%s(%d) "
|
||||
"pc = %08x, a0 = %08x, ps = %08x, ccount = %08x\n",
|
||||
__func__, cs->exception_index,
|
||||
env->pc, env->regs[0], env->sregs[PS], env->sregs[CCOUNT]);
|
||||
if (env->config->exception_vector[cs->exception_index]) {
|
||||
env->pc = relocated_vector(env,
|
||||
env->config->exception_vector[cs->exception_index]);
|
||||
env->exception_taken = 1;
|
||||
} else {
|
||||
qemu_log_mask(CPU_LOG_INT, "%s(pc = %08x) bad exception_index: %d\n",
|
||||
__func__, env->pc, cs->exception_index);
|
||||
}
|
||||
break;
|
||||
|
||||
case EXC_IRQ:
|
||||
break;
|
||||
|
||||
default:
|
||||
qemu_log("%s(pc = %08x) unknown exception_index: %d\n",
|
||||
__func__, env->pc, cs->exception_index);
|
||||
break;
|
||||
}
|
||||
check_interrupts(env);
|
||||
}
|
||||
|
||||
bool xtensa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
|
||||
{
|
||||
if (interrupt_request & CPU_INTERRUPT_HARD) {
|
||||
cs->exception_index = EXC_IRQ;
|
||||
xtensa_cpu_do_interrupt(cs);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void reset_tlb_mmu_all_ways(CPUXtensaState *env,
|
||||
const xtensa_tlb *tlb, xtensa_tlb_entry entry[][MAX_TLB_WAY_SIZE])
|
||||
{
|
||||
unsigned wi, ei;
|
||||
|
||||
for (wi = 0; wi < tlb->nways; ++wi) {
|
||||
for (ei = 0; ei < tlb->way_size[wi]; ++ei) {
|
||||
entry[wi][ei].asid = 0;
|
||||
entry[wi][ei].variable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void reset_tlb_mmu_ways56(CPUXtensaState *env,
|
||||
const xtensa_tlb *tlb, xtensa_tlb_entry entry[][MAX_TLB_WAY_SIZE])
|
||||
{
|
||||
if (!tlb->varway56) {
|
||||
static const xtensa_tlb_entry way5[] = {
|
||||
{
|
||||
.vaddr = 0xd0000000,
|
||||
.paddr = 0,
|
||||
.asid = 1,
|
||||
.attr = 7,
|
||||
.variable = false,
|
||||
}, {
|
||||
.vaddr = 0xd8000000,
|
||||
.paddr = 0,
|
||||
.asid = 1,
|
||||
.attr = 3,
|
||||
.variable = false,
|
||||
}
|
||||
};
|
||||
static const xtensa_tlb_entry way6[] = {
|
||||
{
|
||||
.vaddr = 0xe0000000,
|
||||
.paddr = 0xf0000000,
|
||||
.asid = 1,
|
||||
.attr = 7,
|
||||
.variable = false,
|
||||
}, {
|
||||
.vaddr = 0xf0000000,
|
||||
.paddr = 0xf0000000,
|
||||
.asid = 1,
|
||||
.attr = 3,
|
||||
.variable = false,
|
||||
}
|
||||
};
|
||||
memcpy(entry[5], way5, sizeof(way5));
|
||||
memcpy(entry[6], way6, sizeof(way6));
|
||||
} else {
|
||||
uint32_t ei;
|
||||
for (ei = 0; ei < 8; ++ei) {
|
||||
entry[6][ei].vaddr = ei << 29;
|
||||
entry[6][ei].paddr = ei << 29;
|
||||
entry[6][ei].asid = 1;
|
||||
entry[6][ei].attr = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void reset_tlb_region_way0(CPUXtensaState *env,
|
||||
xtensa_tlb_entry entry[][MAX_TLB_WAY_SIZE])
|
||||
{
|
||||
unsigned ei;
|
||||
|
||||
for (ei = 0; ei < 8; ++ei) {
|
||||
entry[0][ei].vaddr = ei << 29;
|
||||
entry[0][ei].paddr = ei << 29;
|
||||
entry[0][ei].asid = 1;
|
||||
entry[0][ei].attr = 2;
|
||||
entry[0][ei].variable = true;
|
||||
}
|
||||
}
|
||||
|
||||
void reset_mmu(CPUXtensaState *env)
|
||||
{
|
||||
if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
|
||||
env->sregs[RASID] = 0x04030201;
|
||||
env->sregs[ITLBCFG] = 0;
|
||||
env->sregs[DTLBCFG] = 0;
|
||||
env->autorefill_idx = 0;
|
||||
reset_tlb_mmu_all_ways(env, &env->config->itlb, env->itlb);
|
||||
reset_tlb_mmu_all_ways(env, &env->config->dtlb, env->dtlb);
|
||||
reset_tlb_mmu_ways56(env, &env->config->itlb, env->itlb);
|
||||
reset_tlb_mmu_ways56(env, &env->config->dtlb, env->dtlb);
|
||||
} else {
|
||||
reset_tlb_region_way0(env, env->itlb);
|
||||
reset_tlb_region_way0(env, env->dtlb);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned get_ring(const CPUXtensaState *env, uint8_t asid)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
if (((env->sregs[RASID] >> i * 8) & 0xff) == asid) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Lookup xtensa TLB for the given virtual address.
|
||||
* See ISA, 4.6.2.2
|
||||
*
|
||||
* \param pwi: [out] way index
|
||||
* \param pei: [out] entry index
|
||||
* \param pring: [out] access ring
|
||||
* \return 0 if ok, exception cause code otherwise
|
||||
*/
|
||||
int xtensa_tlb_lookup(const CPUXtensaState *env, uint32_t addr, bool dtlb,
|
||||
uint32_t *pwi, uint32_t *pei, uint8_t *pring)
|
||||
{
|
||||
const xtensa_tlb *tlb = dtlb ?
|
||||
&env->config->dtlb : &env->config->itlb;
|
||||
const xtensa_tlb_entry (*entry)[MAX_TLB_WAY_SIZE] = dtlb ?
|
||||
env->dtlb : env->itlb;
|
||||
|
||||
int nhits = 0;
|
||||
unsigned wi;
|
||||
|
||||
for (wi = 0; wi < tlb->nways; ++wi) {
|
||||
uint32_t vpn;
|
||||
uint32_t ei;
|
||||
split_tlb_entry_spec_way(env, addr, dtlb, &vpn, wi, &ei);
|
||||
if (entry[wi][ei].vaddr == vpn && entry[wi][ei].asid) {
|
||||
unsigned ring = get_ring(env, entry[wi][ei].asid);
|
||||
if (ring < 4) {
|
||||
if (++nhits > 1) {
|
||||
return dtlb ?
|
||||
LOAD_STORE_TLB_MULTI_HIT_CAUSE :
|
||||
INST_TLB_MULTI_HIT_CAUSE;
|
||||
}
|
||||
*pwi = wi;
|
||||
*pei = ei;
|
||||
*pring = ring;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nhits ? 0 :
|
||||
(dtlb ? LOAD_STORE_TLB_MISS_CAUSE : INST_TLB_MISS_CAUSE);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Convert MMU ATTR to PAGE_{READ,WRITE,EXEC} mask.
|
||||
* See ISA, 4.6.5.10
|
||||
*/
|
||||
static unsigned mmu_attr_to_access(uint32_t attr)
|
||||
{
|
||||
unsigned access = 0;
|
||||
|
||||
if (attr < 12) {
|
||||
access |= PAGE_READ;
|
||||
if (attr & 0x1) {
|
||||
access |= PAGE_EXEC;
|
||||
}
|
||||
if (attr & 0x2) {
|
||||
access |= PAGE_WRITE;
|
||||
}
|
||||
|
||||
switch (attr & 0xc) {
|
||||
case 0:
|
||||
access |= PAGE_CACHE_BYPASS;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
access |= PAGE_CACHE_WB;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
access |= PAGE_CACHE_WT;
|
||||
break;
|
||||
}
|
||||
} else if (attr == 13) {
|
||||
access |= PAGE_READ | PAGE_WRITE | PAGE_CACHE_ISOLATE;
|
||||
}
|
||||
return access;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Convert region protection ATTR to PAGE_{READ,WRITE,EXEC} mask.
|
||||
* See ISA, 4.6.3.3
|
||||
*/
|
||||
static unsigned region_attr_to_access(uint32_t attr)
|
||||
{
|
||||
static const unsigned access[16] = {
|
||||
[0] = PAGE_READ | PAGE_WRITE | PAGE_CACHE_WT,
|
||||
[1] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_WT,
|
||||
[2] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_BYPASS,
|
||||
[3] = PAGE_EXEC | PAGE_CACHE_WB,
|
||||
[4] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_WB,
|
||||
[5] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_WB,
|
||||
[14] = PAGE_READ | PAGE_WRITE | PAGE_CACHE_ISOLATE,
|
||||
};
|
||||
|
||||
return access[attr & 0xf];
|
||||
}
|
||||
|
||||
/*!
|
||||
* Convert cacheattr to PAGE_{READ,WRITE,EXEC} mask.
|
||||
* See ISA, A.2.14 The Cache Attribute Register
|
||||
*/
|
||||
static unsigned cacheattr_attr_to_access(uint32_t attr)
|
||||
{
|
||||
static const unsigned access[16] = {
|
||||
[0] = PAGE_READ | PAGE_WRITE | PAGE_CACHE_WT,
|
||||
[1] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_WT,
|
||||
[2] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_BYPASS,
|
||||
[3] = PAGE_EXEC | PAGE_CACHE_WB,
|
||||
[4] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_WB,
|
||||
[14] = PAGE_READ | PAGE_WRITE | PAGE_CACHE_ISOLATE,
|
||||
};
|
||||
|
||||
return access[attr & 0xf];
|
||||
}
|
||||
|
||||
static bool is_access_granted(unsigned access, int is_write)
|
||||
{
|
||||
switch (is_write) {
|
||||
case 0:
|
||||
return access & PAGE_READ;
|
||||
|
||||
case 1:
|
||||
return access & PAGE_WRITE;
|
||||
|
||||
case 2:
|
||||
return access & PAGE_EXEC;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int get_pte(CPUXtensaState *env, uint32_t vaddr, uint32_t *pte);
|
||||
|
||||
static int get_physical_addr_mmu(CPUXtensaState *env, bool update_tlb,
|
||||
uint32_t vaddr, int is_write, int mmu_idx,
|
||||
uint32_t *paddr, uint32_t *page_size, unsigned *access,
|
||||
bool may_lookup_pt)
|
||||
{
|
||||
bool dtlb = is_write != 2;
|
||||
uint32_t wi;
|
||||
uint32_t ei;
|
||||
uint8_t ring;
|
||||
uint32_t vpn;
|
||||
uint32_t pte;
|
||||
const xtensa_tlb_entry *entry = NULL;
|
||||
xtensa_tlb_entry tmp_entry;
|
||||
int ret = xtensa_tlb_lookup(env, vaddr, dtlb, &wi, &ei, &ring);
|
||||
|
||||
if ((ret == INST_TLB_MISS_CAUSE || ret == LOAD_STORE_TLB_MISS_CAUSE) &&
|
||||
may_lookup_pt && get_pte(env, vaddr, &pte) == 0) {
|
||||
ring = (pte >> 4) & 0x3;
|
||||
wi = 0;
|
||||
split_tlb_entry_spec_way(env, vaddr, dtlb, &vpn, wi, &ei);
|
||||
|
||||
if (update_tlb) {
|
||||
wi = ++env->autorefill_idx & 0x3;
|
||||
xtensa_tlb_set_entry(env, dtlb, wi, ei, vpn, pte);
|
||||
env->sregs[EXCVADDR] = vaddr;
|
||||
qemu_log_mask(CPU_LOG_MMU, "%s: autorefill(%08x): %08x -> %08x\n",
|
||||
__func__, vaddr, vpn, pte);
|
||||
} else {
|
||||
xtensa_tlb_set_entry_mmu(env, &tmp_entry, dtlb, wi, ei, vpn, pte);
|
||||
entry = &tmp_entry;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (entry == NULL) {
|
||||
entry = xtensa_tlb_get_entry(env, dtlb, wi, ei);
|
||||
}
|
||||
|
||||
if (ring < mmu_idx) {
|
||||
return dtlb ?
|
||||
LOAD_STORE_PRIVILEGE_CAUSE :
|
||||
INST_FETCH_PRIVILEGE_CAUSE;
|
||||
}
|
||||
|
||||
*access = mmu_attr_to_access(entry->attr) &
|
||||
~(dtlb ? PAGE_EXEC : PAGE_READ | PAGE_WRITE);
|
||||
if (!is_access_granted(*access, is_write)) {
|
||||
return dtlb ?
|
||||
(is_write ?
|
||||
STORE_PROHIBITED_CAUSE :
|
||||
LOAD_PROHIBITED_CAUSE) :
|
||||
INST_FETCH_PROHIBITED_CAUSE;
|
||||
}
|
||||
|
||||
*paddr = entry->paddr | (vaddr & ~xtensa_tlb_get_addr_mask(env, dtlb, wi));
|
||||
*page_size = ~xtensa_tlb_get_addr_mask(env, dtlb, wi) + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_pte(CPUXtensaState *env, uint32_t vaddr, uint32_t *pte)
|
||||
{
|
||||
CPUState *cs = CPU(xtensa_env_get_cpu(env));
|
||||
uint32_t paddr;
|
||||
uint32_t page_size;
|
||||
unsigned access;
|
||||
uint32_t pt_vaddr =
|
||||
(env->sregs[PTEVADDR] | (vaddr >> 10)) & 0xfffffffc;
|
||||
int ret = get_physical_addr_mmu(env, false, pt_vaddr, 0, 0,
|
||||
&paddr, &page_size, &access, false);
|
||||
|
||||
qemu_log_mask(CPU_LOG_MMU, "%s: trying autorefill(%08x) -> %08x\n",
|
||||
__func__, vaddr, ret ? ~0 : paddr);
|
||||
|
||||
if (ret == 0) {
|
||||
*pte = ldl_phys(cs->as, paddr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_physical_addr_region(CPUXtensaState *env,
|
||||
uint32_t vaddr, int is_write, int mmu_idx,
|
||||
uint32_t *paddr, uint32_t *page_size, unsigned *access)
|
||||
{
|
||||
bool dtlb = is_write != 2;
|
||||
uint32_t wi = 0;
|
||||
uint32_t ei = (vaddr >> 29) & 0x7;
|
||||
const xtensa_tlb_entry *entry =
|
||||
xtensa_tlb_get_entry(env, dtlb, wi, ei);
|
||||
|
||||
*access = region_attr_to_access(entry->attr);
|
||||
if (!is_access_granted(*access, is_write)) {
|
||||
return dtlb ?
|
||||
(is_write ?
|
||||
STORE_PROHIBITED_CAUSE :
|
||||
LOAD_PROHIBITED_CAUSE) :
|
||||
INST_FETCH_PROHIBITED_CAUSE;
|
||||
}
|
||||
|
||||
*paddr = entry->paddr | (vaddr & ~REGION_PAGE_MASK);
|
||||
*page_size = ~REGION_PAGE_MASK + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Convert virtual address to physical addr.
|
||||
* MMU may issue pagewalk and change xtensa autorefill TLB way entry.
|
||||
*
|
||||
* \return 0 if ok, exception cause code otherwise
|
||||
*/
|
||||
int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb,
|
||||
uint32_t vaddr, int is_write, int mmu_idx,
|
||||
uint32_t *paddr, uint32_t *page_size, unsigned *access)
|
||||
{
|
||||
if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
|
||||
return get_physical_addr_mmu(env, update_tlb,
|
||||
vaddr, is_write, mmu_idx, paddr, page_size, access, true);
|
||||
} else if (xtensa_option_bits_enabled(env->config,
|
||||
XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) |
|
||||
XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION))) {
|
||||
return get_physical_addr_region(env, vaddr, is_write, mmu_idx,
|
||||
paddr, page_size, access);
|
||||
} else {
|
||||
*paddr = vaddr;
|
||||
*page_size = TARGET_PAGE_SIZE;
|
||||
*access = cacheattr_attr_to_access(
|
||||
env->sregs[CACHEATTR] >> ((vaddr & 0xe0000000) >> 27));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_tlb(FILE *f, fprintf_function cpu_fprintf,
|
||||
CPUXtensaState *env, bool dtlb)
|
||||
{
|
||||
unsigned wi, ei;
|
||||
const xtensa_tlb *conf =
|
||||
dtlb ? &env->config->dtlb : &env->config->itlb;
|
||||
unsigned (*attr_to_access)(uint32_t) =
|
||||
xtensa_option_enabled(env->config, XTENSA_OPTION_MMU) ?
|
||||
mmu_attr_to_access : region_attr_to_access;
|
||||
|
||||
for (wi = 0; wi < conf->nways; ++wi) {
|
||||
uint32_t sz = ~xtensa_tlb_get_addr_mask(env, dtlb, wi) + 1;
|
||||
const char *sz_text;
|
||||
bool print_header = true;
|
||||
|
||||
if (sz >= 0x100000) {
|
||||
sz >>= 20;
|
||||
sz_text = "MB";
|
||||
} else {
|
||||
sz >>= 10;
|
||||
sz_text = "KB";
|
||||
}
|
||||
|
||||
for (ei = 0; ei < conf->way_size[wi]; ++ei) {
|
||||
const xtensa_tlb_entry *entry =
|
||||
xtensa_tlb_get_entry(env, dtlb, wi, ei);
|
||||
|
||||
if (entry->asid) {
|
||||
static const char * const cache_text[8] = {
|
||||
[PAGE_CACHE_BYPASS >> PAGE_CACHE_SHIFT] = "Bypass",
|
||||
[PAGE_CACHE_WT >> PAGE_CACHE_SHIFT] = "WT",
|
||||
[PAGE_CACHE_WB >> PAGE_CACHE_SHIFT] = "WB",
|
||||
[PAGE_CACHE_ISOLATE >> PAGE_CACHE_SHIFT] = "Isolate",
|
||||
};
|
||||
unsigned access = attr_to_access(entry->attr);
|
||||
unsigned cache_idx = (access & PAGE_CACHE_MASK) >>
|
||||
PAGE_CACHE_SHIFT;
|
||||
|
||||
if (print_header) {
|
||||
print_header = false;
|
||||
cpu_fprintf(f, "Way %u (%d %s)\n", wi, sz, sz_text);
|
||||
cpu_fprintf(f,
|
||||
"\tVaddr Paddr ASID Attr RWX Cache\n"
|
||||
"\t---------- ---------- ---- ---- --- -------\n");
|
||||
}
|
||||
cpu_fprintf(f,
|
||||
"\t0x%08x 0x%08x 0x%02x 0x%02x %c%c%c %-7s\n",
|
||||
entry->vaddr,
|
||||
entry->paddr,
|
||||
entry->asid,
|
||||
entry->attr,
|
||||
(access & PAGE_READ) ? 'R' : '-',
|
||||
(access & PAGE_WRITE) ? 'W' : '-',
|
||||
(access & PAGE_EXEC) ? 'X' : '-',
|
||||
cache_text[cache_idx] ? cache_text[cache_idx] :
|
||||
"Invalid");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUXtensaState *env)
|
||||
{
|
||||
if (xtensa_option_bits_enabled(env->config,
|
||||
XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) |
|
||||
XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION) |
|
||||
XTENSA_OPTION_BIT(XTENSA_OPTION_MMU))) {
|
||||
|
||||
cpu_fprintf(f, "ITLB:\n");
|
||||
dump_tlb(f, cpu_fprintf, env, false);
|
||||
cpu_fprintf(f, "\nDTLB:\n");
|
||||
dump_tlb(f, cpu_fprintf, env, true);
|
||||
} else {
|
||||
cpu_fprintf(f, "No TLB for this CPU core\n");
|
||||
}
|
||||
}
|
58
target/xtensa/helper.h
Normal file
58
target/xtensa/helper.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
DEF_HELPER_2(exception, noreturn, env, i32)
|
||||
DEF_HELPER_3(exception_cause, noreturn, env, i32, i32)
|
||||
DEF_HELPER_4(exception_cause_vaddr, noreturn, env, i32, i32, i32)
|
||||
DEF_HELPER_3(debug_exception, noreturn, env, i32, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_1(nsa, TCG_CALL_NO_RWG_SE, i32, i32)
|
||||
DEF_HELPER_FLAGS_1(nsau, TCG_CALL_NO_RWG_SE, i32, i32)
|
||||
DEF_HELPER_2(wsr_windowbase, void, env, i32)
|
||||
DEF_HELPER_4(entry, void, env, i32, i32, i32)
|
||||
DEF_HELPER_2(retw, i32, env, i32)
|
||||
DEF_HELPER_2(rotw, void, env, i32)
|
||||
DEF_HELPER_3(window_check, noreturn, env, i32, i32)
|
||||
DEF_HELPER_1(restore_owb, void, env)
|
||||
DEF_HELPER_2(movsp, void, env, i32)
|
||||
DEF_HELPER_2(wsr_lbeg, void, env, i32)
|
||||
DEF_HELPER_2(wsr_lend, void, env, i32)
|
||||
DEF_HELPER_1(simcall, void, env)
|
||||
DEF_HELPER_1(dump_state, void, env)
|
||||
|
||||
DEF_HELPER_3(waiti, void, env, i32, i32)
|
||||
DEF_HELPER_3(timer_irq, void, env, i32, i32)
|
||||
DEF_HELPER_2(advance_ccount, void, env, i32)
|
||||
DEF_HELPER_1(check_interrupts, void, env)
|
||||
DEF_HELPER_3(check_atomctl, void, env, i32, i32)
|
||||
|
||||
DEF_HELPER_2(itlb_hit_test, void, env, i32)
|
||||
DEF_HELPER_2(wsr_rasid, void, env, i32)
|
||||
DEF_HELPER_FLAGS_3(rtlb0, TCG_CALL_NO_RWG_SE, i32, env, i32, i32)
|
||||
DEF_HELPER_FLAGS_3(rtlb1, TCG_CALL_NO_RWG_SE, i32, env, i32, i32)
|
||||
DEF_HELPER_3(itlb, void, env, i32, i32)
|
||||
DEF_HELPER_3(ptlb, i32, env, i32, i32)
|
||||
DEF_HELPER_4(wtlb, void, env, i32, i32, i32)
|
||||
|
||||
DEF_HELPER_2(wsr_ibreakenable, void, env, i32)
|
||||
DEF_HELPER_3(wsr_ibreaka, void, env, i32, i32)
|
||||
DEF_HELPER_3(wsr_dbreaka, void, env, i32, i32)
|
||||
DEF_HELPER_3(wsr_dbreakc, void, env, i32, i32)
|
||||
|
||||
DEF_HELPER_2(wur_fcr, void, env, i32)
|
||||
DEF_HELPER_FLAGS_1(abs_s, TCG_CALL_NO_RWG_SE, f32, f32)
|
||||
DEF_HELPER_FLAGS_1(neg_s, TCG_CALL_NO_RWG_SE, f32, f32)
|
||||
DEF_HELPER_3(add_s, f32, env, f32, f32)
|
||||
DEF_HELPER_3(sub_s, f32, env, f32, f32)
|
||||
DEF_HELPER_3(mul_s, f32, env, f32, f32)
|
||||
DEF_HELPER_4(madd_s, f32, env, f32, f32, f32)
|
||||
DEF_HELPER_4(msub_s, f32, env, f32, f32, f32)
|
||||
DEF_HELPER_FLAGS_3(ftoi, TCG_CALL_NO_RWG_SE, i32, f32, i32, i32)
|
||||
DEF_HELPER_FLAGS_3(ftoui, TCG_CALL_NO_RWG_SE, i32, f32, i32, i32)
|
||||
DEF_HELPER_3(itof, f32, env, i32, i32)
|
||||
DEF_HELPER_3(uitof, f32, env, i32, i32)
|
||||
|
||||
DEF_HELPER_4(un_s, void, env, i32, f32, f32)
|
||||
DEF_HELPER_4(oeq_s, void, env, i32, f32, f32)
|
||||
DEF_HELPER_4(ueq_s, void, env, i32, f32, f32)
|
||||
DEF_HELPER_4(olt_s, void, env, i32, f32, f32)
|
||||
DEF_HELPER_4(ult_s, void, env, i32, f32, f32)
|
||||
DEF_HELPER_4(ole_s, void, env, i32, f32, f32)
|
||||
DEF_HELPER_4(ule_s, void, env, i32, f32, f32)
|
51
target/xtensa/import_core.sh
Executable file
51
target/xtensa/import_core.sh
Executable file
|
@ -0,0 +1,51 @@
|
|||
#! /bin/bash -e
|
||||
|
||||
OVERLAY="$1"
|
||||
NAME="$2"
|
||||
FREQ=40000
|
||||
BASE=$(dirname "$0")
|
||||
TARGET="$BASE"/core-$NAME
|
||||
|
||||
[ $# -ge 2 -a -f "$OVERLAY" ] || { cat <<EOF
|
||||
Usage: $0 overlay-archive-to-import core-name [frequency-in-KHz]
|
||||
overlay-archive-to-import: file name of xtensa-config-overlay.tar.gz
|
||||
to import configuration from.
|
||||
core-name: QEMU name of the imported core. Must be valid
|
||||
C identifier.
|
||||
frequency-in-KHz: core frequency (40MHz if not specified).
|
||||
EOF
|
||||
exit
|
||||
}
|
||||
|
||||
[ $# -ge 3 ] && FREQ="$3"
|
||||
mkdir -p "$TARGET"
|
||||
tar -xf "$OVERLAY" -C "$TARGET" --strip-components=1 \
|
||||
--xform='s/core/core-isa/' config/core.h
|
||||
tar -xf "$OVERLAY" -O gdb/xtensa-config.c | \
|
||||
sed -n '1,/*\//p;/XTREG/,/XTREG_END/p' > "$TARGET"/gdb-config.c
|
||||
|
||||
cat <<EOF > "${TARGET}.c"
|
||||
#include "cpu.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "exec/gdbstub.h"
|
||||
#include "qemu/host-utils.h"
|
||||
|
||||
#include "core-$NAME/core-isa.h"
|
||||
#include "overlay_tool.h"
|
||||
|
||||
static XtensaConfig $NAME __attribute__((unused)) = {
|
||||
.name = "$NAME",
|
||||
.gdb_regmap = {
|
||||
.reg = {
|
||||
#include "core-$NAME/gdb-config.c"
|
||||
}
|
||||
},
|
||||
.clock_freq_khz = $FREQ,
|
||||
DEFAULT_SECTIONS
|
||||
};
|
||||
|
||||
REGISTER_CORE($NAME)
|
||||
EOF
|
||||
|
||||
grep -q core-${NAME}.o "$BASE"/Makefile.objs || \
|
||||
echo "obj-y += core-${NAME}.o" >> "$BASE"/Makefile.objs
|
35
target/xtensa/monitor.c
Normal file
35
target/xtensa/monitor.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* QEMU monitor
|
||||
*
|
||||
* Copyright (c) 2003-2004 Fabrice Bellard
|
||||
*
|
||||
* 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 "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
#include "monitor/monitor.h"
|
||||
#include "monitor/hmp-target.h"
|
||||
#include "hmp.h"
|
||||
|
||||
void hmp_info_tlb(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
CPUArchState *env1 = mon_get_cpu_env();
|
||||
|
||||
dump_mmu((FILE*)mon, (fprintf_function)monitor_printf, env1);
|
||||
}
|
984
target/xtensa/op_helper.c
Normal file
984
target/xtensa/op_helper.c
Normal file
|
@ -0,0 +1,984 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of the Open Source and Linux Lab 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 COPYRIGHT HOLDERS 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
#include "exec/helper-proto.h"
|
||||
#include "qemu/host-utils.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "exec/cpu_ldst.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "qemu/timer.h"
|
||||
|
||||
void xtensa_cpu_do_unaligned_access(CPUState *cs,
|
||||
vaddr addr, MMUAccessType access_type,
|
||||
int mmu_idx, uintptr_t retaddr)
|
||||
{
|
||||
XtensaCPU *cpu = XTENSA_CPU(cs);
|
||||
CPUXtensaState *env = &cpu->env;
|
||||
|
||||
if (xtensa_option_enabled(env->config, XTENSA_OPTION_UNALIGNED_EXCEPTION) &&
|
||||
!xtensa_option_enabled(env->config, XTENSA_OPTION_HW_ALIGNMENT)) {
|
||||
cpu_restore_state(CPU(cpu), retaddr);
|
||||
HELPER(exception_cause_vaddr)(env,
|
||||
env->pc, LOAD_STORE_ALIGNMENT_CAUSE, addr);
|
||||
}
|
||||
}
|
||||
|
||||
void tlb_fill(CPUState *cs, target_ulong vaddr, MMUAccessType access_type,
|
||||
int mmu_idx, uintptr_t retaddr)
|
||||
{
|
||||
XtensaCPU *cpu = XTENSA_CPU(cs);
|
||||
CPUXtensaState *env = &cpu->env;
|
||||
uint32_t paddr;
|
||||
uint32_t page_size;
|
||||
unsigned access;
|
||||
int ret = xtensa_get_physical_addr(env, true, vaddr, access_type, mmu_idx,
|
||||
&paddr, &page_size, &access);
|
||||
|
||||
qemu_log_mask(CPU_LOG_MMU, "%s(%08x, %d, %d) -> %08x, ret = %d\n",
|
||||
__func__, vaddr, access_type, mmu_idx, paddr, ret);
|
||||
|
||||
if (ret == 0) {
|
||||
tlb_set_page(cs,
|
||||
vaddr & TARGET_PAGE_MASK,
|
||||
paddr & TARGET_PAGE_MASK,
|
||||
access, mmu_idx, page_size);
|
||||
} else {
|
||||
cpu_restore_state(cs, retaddr);
|
||||
HELPER(exception_cause_vaddr)(env, env->pc, ret, vaddr);
|
||||
}
|
||||
}
|
||||
|
||||
void xtensa_cpu_do_unassigned_access(CPUState *cs, hwaddr addr,
|
||||
bool is_write, bool is_exec, int opaque,
|
||||
unsigned size)
|
||||
{
|
||||
XtensaCPU *cpu = XTENSA_CPU(cs);
|
||||
CPUXtensaState *env = &cpu->env;
|
||||
|
||||
HELPER(exception_cause_vaddr)(env, env->pc,
|
||||
is_exec ?
|
||||
INSTR_PIF_ADDR_ERROR_CAUSE :
|
||||
LOAD_STORE_PIF_ADDR_ERROR_CAUSE,
|
||||
is_exec ? addr : cs->mem_io_vaddr);
|
||||
}
|
||||
|
||||
static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr)
|
||||
{
|
||||
uint32_t paddr;
|
||||
uint32_t page_size;
|
||||
unsigned access;
|
||||
int ret = xtensa_get_physical_addr(env, false, vaddr, 2, 0,
|
||||
&paddr, &page_size, &access);
|
||||
if (ret == 0) {
|
||||
tb_invalidate_phys_addr(&address_space_memory, paddr);
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(exception)(CPUXtensaState *env, uint32_t excp)
|
||||
{
|
||||
CPUState *cs = CPU(xtensa_env_get_cpu(env));
|
||||
|
||||
cs->exception_index = excp;
|
||||
if (excp == EXCP_DEBUG) {
|
||||
env->exception_taken = 0;
|
||||
}
|
||||
cpu_loop_exit(cs);
|
||||
}
|
||||
|
||||
void HELPER(exception_cause)(CPUXtensaState *env, uint32_t pc, uint32_t cause)
|
||||
{
|
||||
uint32_t vector;
|
||||
|
||||
env->pc = pc;
|
||||
if (env->sregs[PS] & PS_EXCM) {
|
||||
if (env->config->ndepc) {
|
||||
env->sregs[DEPC] = pc;
|
||||
} else {
|
||||
env->sregs[EPC1] = pc;
|
||||
}
|
||||
vector = EXC_DOUBLE;
|
||||
} else {
|
||||
env->sregs[EPC1] = pc;
|
||||
vector = (env->sregs[PS] & PS_UM) ? EXC_USER : EXC_KERNEL;
|
||||
}
|
||||
|
||||
env->sregs[EXCCAUSE] = cause;
|
||||
env->sregs[PS] |= PS_EXCM;
|
||||
|
||||
HELPER(exception)(env, vector);
|
||||
}
|
||||
|
||||
void HELPER(exception_cause_vaddr)(CPUXtensaState *env,
|
||||
uint32_t pc, uint32_t cause, uint32_t vaddr)
|
||||
{
|
||||
env->sregs[EXCVADDR] = vaddr;
|
||||
HELPER(exception_cause)(env, pc, cause);
|
||||
}
|
||||
|
||||
void debug_exception_env(CPUXtensaState *env, uint32_t cause)
|
||||
{
|
||||
if (xtensa_get_cintlevel(env) < env->config->debug_level) {
|
||||
HELPER(debug_exception)(env, env->pc, cause);
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(debug_exception)(CPUXtensaState *env, uint32_t pc, uint32_t cause)
|
||||
{
|
||||
unsigned level = env->config->debug_level;
|
||||
|
||||
env->pc = pc;
|
||||
env->sregs[DEBUGCAUSE] = cause;
|
||||
env->sregs[EPC1 + level - 1] = pc;
|
||||
env->sregs[EPS2 + level - 2] = env->sregs[PS];
|
||||
env->sregs[PS] = (env->sregs[PS] & ~PS_INTLEVEL) | PS_EXCM |
|
||||
(level << PS_INTLEVEL_SHIFT);
|
||||
HELPER(exception)(env, EXC_DEBUG);
|
||||
}
|
||||
|
||||
uint32_t HELPER(nsa)(uint32_t v)
|
||||
{
|
||||
if (v & 0x80000000) {
|
||||
v = ~v;
|
||||
}
|
||||
return v ? clz32(v) - 1 : 31;
|
||||
}
|
||||
|
||||
uint32_t HELPER(nsau)(uint32_t v)
|
||||
{
|
||||
return v ? clz32(v) : 32;
|
||||
}
|
||||
|
||||
static void copy_window_from_phys(CPUXtensaState *env,
|
||||
uint32_t window, uint32_t phys, uint32_t n)
|
||||
{
|
||||
assert(phys < env->config->nareg);
|
||||
if (phys + n <= env->config->nareg) {
|
||||
memcpy(env->regs + window, env->phys_regs + phys,
|
||||
n * sizeof(uint32_t));
|
||||
} else {
|
||||
uint32_t n1 = env->config->nareg - phys;
|
||||
memcpy(env->regs + window, env->phys_regs + phys,
|
||||
n1 * sizeof(uint32_t));
|
||||
memcpy(env->regs + window + n1, env->phys_regs,
|
||||
(n - n1) * sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
|
||||
static void copy_phys_from_window(CPUXtensaState *env,
|
||||
uint32_t phys, uint32_t window, uint32_t n)
|
||||
{
|
||||
assert(phys < env->config->nareg);
|
||||
if (phys + n <= env->config->nareg) {
|
||||
memcpy(env->phys_regs + phys, env->regs + window,
|
||||
n * sizeof(uint32_t));
|
||||
} else {
|
||||
uint32_t n1 = env->config->nareg - phys;
|
||||
memcpy(env->phys_regs + phys, env->regs + window,
|
||||
n1 * sizeof(uint32_t));
|
||||
memcpy(env->phys_regs, env->regs + window + n1,
|
||||
(n - n1) * sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline unsigned windowbase_bound(unsigned a, const CPUXtensaState *env)
|
||||
{
|
||||
return a & (env->config->nareg / 4 - 1);
|
||||
}
|
||||
|
||||
static inline unsigned windowstart_bit(unsigned a, const CPUXtensaState *env)
|
||||
{
|
||||
return 1 << windowbase_bound(a, env);
|
||||
}
|
||||
|
||||
void xtensa_sync_window_from_phys(CPUXtensaState *env)
|
||||
{
|
||||
copy_window_from_phys(env, 0, env->sregs[WINDOW_BASE] * 4, 16);
|
||||
}
|
||||
|
||||
void xtensa_sync_phys_from_window(CPUXtensaState *env)
|
||||
{
|
||||
copy_phys_from_window(env, env->sregs[WINDOW_BASE] * 4, 0, 16);
|
||||
}
|
||||
|
||||
static void rotate_window_abs(CPUXtensaState *env, uint32_t position)
|
||||
{
|
||||
xtensa_sync_phys_from_window(env);
|
||||
env->sregs[WINDOW_BASE] = windowbase_bound(position, env);
|
||||
xtensa_sync_window_from_phys(env);
|
||||
}
|
||||
|
||||
static void rotate_window(CPUXtensaState *env, uint32_t delta)
|
||||
{
|
||||
rotate_window_abs(env, env->sregs[WINDOW_BASE] + delta);
|
||||
}
|
||||
|
||||
void HELPER(wsr_windowbase)(CPUXtensaState *env, uint32_t v)
|
||||
{
|
||||
rotate_window_abs(env, v);
|
||||
}
|
||||
|
||||
void HELPER(entry)(CPUXtensaState *env, uint32_t pc, uint32_t s, uint32_t imm)
|
||||
{
|
||||
int callinc = (env->sregs[PS] & PS_CALLINC) >> PS_CALLINC_SHIFT;
|
||||
if (s > 3 || ((env->sregs[PS] & (PS_WOE | PS_EXCM)) ^ PS_WOE) != 0) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "Illegal entry instruction(pc = %08x), PS = %08x\n",
|
||||
pc, env->sregs[PS]);
|
||||
HELPER(exception_cause)(env, pc, ILLEGAL_INSTRUCTION_CAUSE);
|
||||
} else {
|
||||
uint32_t windowstart = xtensa_replicate_windowstart(env) >>
|
||||
(env->sregs[WINDOW_BASE] + 1);
|
||||
|
||||
if (windowstart & ((1 << callinc) - 1)) {
|
||||
HELPER(window_check)(env, pc, callinc);
|
||||
}
|
||||
env->regs[(callinc << 2) | (s & 3)] = env->regs[s] - (imm << 3);
|
||||
rotate_window(env, callinc);
|
||||
env->sregs[WINDOW_START] |=
|
||||
windowstart_bit(env->sregs[WINDOW_BASE], env);
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(window_check)(CPUXtensaState *env, uint32_t pc, uint32_t w)
|
||||
{
|
||||
uint32_t windowbase = windowbase_bound(env->sregs[WINDOW_BASE], env);
|
||||
uint32_t windowstart = xtensa_replicate_windowstart(env) >>
|
||||
(env->sregs[WINDOW_BASE] + 1);
|
||||
uint32_t n = ctz32(windowstart) + 1;
|
||||
|
||||
assert(n <= w);
|
||||
|
||||
rotate_window(env, n);
|
||||
env->sregs[PS] = (env->sregs[PS] & ~PS_OWB) |
|
||||
(windowbase << PS_OWB_SHIFT) | PS_EXCM;
|
||||
env->sregs[EPC1] = env->pc = pc;
|
||||
|
||||
switch (ctz32(windowstart >> n)) {
|
||||
case 0:
|
||||
HELPER(exception)(env, EXC_WINDOW_OVERFLOW4);
|
||||
break;
|
||||
case 1:
|
||||
HELPER(exception)(env, EXC_WINDOW_OVERFLOW8);
|
||||
break;
|
||||
default:
|
||||
HELPER(exception)(env, EXC_WINDOW_OVERFLOW12);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t HELPER(retw)(CPUXtensaState *env, uint32_t pc)
|
||||
{
|
||||
int n = (env->regs[0] >> 30) & 0x3;
|
||||
int m = 0;
|
||||
uint32_t windowbase = windowbase_bound(env->sregs[WINDOW_BASE], env);
|
||||
uint32_t windowstart = env->sregs[WINDOW_START];
|
||||
uint32_t ret_pc = 0;
|
||||
|
||||
if (windowstart & windowstart_bit(windowbase - 1, env)) {
|
||||
m = 1;
|
||||
} else if (windowstart & windowstart_bit(windowbase - 2, env)) {
|
||||
m = 2;
|
||||
} else if (windowstart & windowstart_bit(windowbase - 3, env)) {
|
||||
m = 3;
|
||||
}
|
||||
|
||||
if (n == 0 || (m != 0 && m != n) ||
|
||||
((env->sregs[PS] & (PS_WOE | PS_EXCM)) ^ PS_WOE) != 0) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "Illegal retw instruction(pc = %08x), "
|
||||
"PS = %08x, m = %d, n = %d\n",
|
||||
pc, env->sregs[PS], m, n);
|
||||
HELPER(exception_cause)(env, pc, ILLEGAL_INSTRUCTION_CAUSE);
|
||||
} else {
|
||||
int owb = windowbase;
|
||||
|
||||
ret_pc = (pc & 0xc0000000) | (env->regs[0] & 0x3fffffff);
|
||||
|
||||
rotate_window(env, -n);
|
||||
if (windowstart & windowstart_bit(env->sregs[WINDOW_BASE], env)) {
|
||||
env->sregs[WINDOW_START] &= ~windowstart_bit(owb, env);
|
||||
} else {
|
||||
/* window underflow */
|
||||
env->sregs[PS] = (env->sregs[PS] & ~PS_OWB) |
|
||||
(windowbase << PS_OWB_SHIFT) | PS_EXCM;
|
||||
env->sregs[EPC1] = env->pc = pc;
|
||||
|
||||
if (n == 1) {
|
||||
HELPER(exception)(env, EXC_WINDOW_UNDERFLOW4);
|
||||
} else if (n == 2) {
|
||||
HELPER(exception)(env, EXC_WINDOW_UNDERFLOW8);
|
||||
} else if (n == 3) {
|
||||
HELPER(exception)(env, EXC_WINDOW_UNDERFLOW12);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret_pc;
|
||||
}
|
||||
|
||||
void HELPER(rotw)(CPUXtensaState *env, uint32_t imm4)
|
||||
{
|
||||
rotate_window(env, imm4);
|
||||
}
|
||||
|
||||
void HELPER(restore_owb)(CPUXtensaState *env)
|
||||
{
|
||||
rotate_window_abs(env, (env->sregs[PS] & PS_OWB) >> PS_OWB_SHIFT);
|
||||
}
|
||||
|
||||
void HELPER(movsp)(CPUXtensaState *env, uint32_t pc)
|
||||
{
|
||||
if ((env->sregs[WINDOW_START] &
|
||||
(windowstart_bit(env->sregs[WINDOW_BASE] - 3, env) |
|
||||
windowstart_bit(env->sregs[WINDOW_BASE] - 2, env) |
|
||||
windowstart_bit(env->sregs[WINDOW_BASE] - 1, env))) == 0) {
|
||||
HELPER(exception_cause)(env, pc, ALLOCA_CAUSE);
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(wsr_lbeg)(CPUXtensaState *env, uint32_t v)
|
||||
{
|
||||
if (env->sregs[LBEG] != v) {
|
||||
tb_invalidate_virtual_addr(env, env->sregs[LEND] - 1);
|
||||
env->sregs[LBEG] = v;
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(wsr_lend)(CPUXtensaState *env, uint32_t v)
|
||||
{
|
||||
if (env->sregs[LEND] != v) {
|
||||
tb_invalidate_virtual_addr(env, env->sregs[LEND] - 1);
|
||||
env->sregs[LEND] = v;
|
||||
tb_invalidate_virtual_addr(env, env->sregs[LEND] - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(dump_state)(CPUXtensaState *env)
|
||||
{
|
||||
XtensaCPU *cpu = xtensa_env_get_cpu(env);
|
||||
|
||||
cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
|
||||
}
|
||||
|
||||
void HELPER(waiti)(CPUXtensaState *env, uint32_t pc, uint32_t intlevel)
|
||||
{
|
||||
CPUState *cpu;
|
||||
|
||||
env->pc = pc;
|
||||
env->sregs[PS] = (env->sregs[PS] & ~PS_INTLEVEL) |
|
||||
(intlevel << PS_INTLEVEL_SHIFT);
|
||||
check_interrupts(env);
|
||||
if (env->pending_irq_level) {
|
||||
cpu_loop_exit(CPU(xtensa_env_get_cpu(env)));
|
||||
return;
|
||||
}
|
||||
|
||||
cpu = CPU(xtensa_env_get_cpu(env));
|
||||
env->halt_clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
cpu->halted = 1;
|
||||
if (xtensa_option_enabled(env->config, XTENSA_OPTION_TIMER_INTERRUPT)) {
|
||||
xtensa_rearm_ccompare_timer(env);
|
||||
}
|
||||
HELPER(exception)(env, EXCP_HLT);
|
||||
}
|
||||
|
||||
void HELPER(timer_irq)(CPUXtensaState *env, uint32_t id, uint32_t active)
|
||||
{
|
||||
xtensa_timer_irq(env, id, active);
|
||||
}
|
||||
|
||||
void HELPER(advance_ccount)(CPUXtensaState *env, uint32_t d)
|
||||
{
|
||||
xtensa_advance_ccount(env, d);
|
||||
}
|
||||
|
||||
void HELPER(check_interrupts)(CPUXtensaState *env)
|
||||
{
|
||||
check_interrupts(env);
|
||||
}
|
||||
|
||||
void HELPER(itlb_hit_test)(CPUXtensaState *env, uint32_t vaddr)
|
||||
{
|
||||
get_page_addr_code(env, vaddr);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Check vaddr accessibility/cache attributes and raise an exception if
|
||||
* specified by the ATOMCTL SR.
|
||||
*
|
||||
* Note: local memory exclusion is not implemented
|
||||
*/
|
||||
void HELPER(check_atomctl)(CPUXtensaState *env, uint32_t pc, uint32_t vaddr)
|
||||
{
|
||||
uint32_t paddr, page_size, access;
|
||||
uint32_t atomctl = env->sregs[ATOMCTL];
|
||||
int rc = xtensa_get_physical_addr(env, true, vaddr, 1,
|
||||
xtensa_get_cring(env), &paddr, &page_size, &access);
|
||||
|
||||
/*
|
||||
* s32c1i never causes LOAD_PROHIBITED_CAUSE exceptions,
|
||||
* see opcode description in the ISA
|
||||
*/
|
||||
if (rc == 0 &&
|
||||
(access & (PAGE_READ | PAGE_WRITE)) != (PAGE_READ | PAGE_WRITE)) {
|
||||
rc = STORE_PROHIBITED_CAUSE;
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
HELPER(exception_cause_vaddr)(env, pc, rc, vaddr);
|
||||
}
|
||||
|
||||
/*
|
||||
* When data cache is not configured use ATOMCTL bypass field.
|
||||
* See ISA, 4.3.12.4 The Atomic Operation Control Register (ATOMCTL)
|
||||
* under the Conditional Store Option.
|
||||
*/
|
||||
if (!xtensa_option_enabled(env->config, XTENSA_OPTION_DCACHE)) {
|
||||
access = PAGE_CACHE_BYPASS;
|
||||
}
|
||||
|
||||
switch (access & PAGE_CACHE_MASK) {
|
||||
case PAGE_CACHE_WB:
|
||||
atomctl >>= 2;
|
||||
/* fall through */
|
||||
case PAGE_CACHE_WT:
|
||||
atomctl >>= 2;
|
||||
/* fall through */
|
||||
case PAGE_CACHE_BYPASS:
|
||||
if ((atomctl & 0x3) == 0) {
|
||||
HELPER(exception_cause_vaddr)(env, pc,
|
||||
LOAD_STORE_ERROR_CAUSE, vaddr);
|
||||
}
|
||||
break;
|
||||
|
||||
case PAGE_CACHE_ISOLATE:
|
||||
HELPER(exception_cause_vaddr)(env, pc,
|
||||
LOAD_STORE_ERROR_CAUSE, vaddr);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(wsr_rasid)(CPUXtensaState *env, uint32_t v)
|
||||
{
|
||||
XtensaCPU *cpu = xtensa_env_get_cpu(env);
|
||||
|
||||
v = (v & 0xffffff00) | 0x1;
|
||||
if (v != env->sregs[RASID]) {
|
||||
env->sregs[RASID] = v;
|
||||
tlb_flush(CPU(cpu), 1);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t get_page_size(const CPUXtensaState *env, bool dtlb, uint32_t way)
|
||||
{
|
||||
uint32_t tlbcfg = env->sregs[dtlb ? DTLBCFG : ITLBCFG];
|
||||
|
||||
switch (way) {
|
||||
case 4:
|
||||
return (tlbcfg >> 16) & 0x3;
|
||||
|
||||
case 5:
|
||||
return (tlbcfg >> 20) & 0x1;
|
||||
|
||||
case 6:
|
||||
return (tlbcfg >> 24) & 0x1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Get bit mask for the virtual address bits translated by the TLB way
|
||||
*/
|
||||
uint32_t xtensa_tlb_get_addr_mask(const CPUXtensaState *env, bool dtlb, uint32_t way)
|
||||
{
|
||||
if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
|
||||
bool varway56 = dtlb ?
|
||||
env->config->dtlb.varway56 :
|
||||
env->config->itlb.varway56;
|
||||
|
||||
switch (way) {
|
||||
case 4:
|
||||
return 0xfff00000 << get_page_size(env, dtlb, way) * 2;
|
||||
|
||||
case 5:
|
||||
if (varway56) {
|
||||
return 0xf8000000 << get_page_size(env, dtlb, way);
|
||||
} else {
|
||||
return 0xf8000000;
|
||||
}
|
||||
|
||||
case 6:
|
||||
if (varway56) {
|
||||
return 0xf0000000 << (1 - get_page_size(env, dtlb, way));
|
||||
} else {
|
||||
return 0xf0000000;
|
||||
}
|
||||
|
||||
default:
|
||||
return 0xfffff000;
|
||||
}
|
||||
} else {
|
||||
return REGION_PAGE_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Get bit mask for the 'VPN without index' field.
|
||||
* See ISA, 4.6.5.6, data format for RxTLB0
|
||||
*/
|
||||
static uint32_t get_vpn_mask(const CPUXtensaState *env, bool dtlb, uint32_t way)
|
||||
{
|
||||
if (way < 4) {
|
||||
bool is32 = (dtlb ?
|
||||
env->config->dtlb.nrefillentries :
|
||||
env->config->itlb.nrefillentries) == 32;
|
||||
return is32 ? 0xffff8000 : 0xffffc000;
|
||||
} else if (way == 4) {
|
||||
return xtensa_tlb_get_addr_mask(env, dtlb, way) << 2;
|
||||
} else if (way <= 6) {
|
||||
uint32_t mask = xtensa_tlb_get_addr_mask(env, dtlb, way);
|
||||
bool varway56 = dtlb ?
|
||||
env->config->dtlb.varway56 :
|
||||
env->config->itlb.varway56;
|
||||
|
||||
if (varway56) {
|
||||
return mask << (way == 5 ? 2 : 3);
|
||||
} else {
|
||||
return mask << 1;
|
||||
}
|
||||
} else {
|
||||
return 0xfffff000;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Split virtual address into VPN (with index) and entry index
|
||||
* for the given TLB way
|
||||
*/
|
||||
void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, bool dtlb,
|
||||
uint32_t *vpn, uint32_t wi, uint32_t *ei)
|
||||
{
|
||||
bool varway56 = dtlb ?
|
||||
env->config->dtlb.varway56 :
|
||||
env->config->itlb.varway56;
|
||||
|
||||
if (!dtlb) {
|
||||
wi &= 7;
|
||||
}
|
||||
|
||||
if (wi < 4) {
|
||||
bool is32 = (dtlb ?
|
||||
env->config->dtlb.nrefillentries :
|
||||
env->config->itlb.nrefillentries) == 32;
|
||||
*ei = (v >> 12) & (is32 ? 0x7 : 0x3);
|
||||
} else {
|
||||
switch (wi) {
|
||||
case 4:
|
||||
{
|
||||
uint32_t eibase = 20 + get_page_size(env, dtlb, wi) * 2;
|
||||
*ei = (v >> eibase) & 0x3;
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
if (varway56) {
|
||||
uint32_t eibase = 27 + get_page_size(env, dtlb, wi);
|
||||
*ei = (v >> eibase) & 0x3;
|
||||
} else {
|
||||
*ei = (v >> 27) & 0x1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (varway56) {
|
||||
uint32_t eibase = 29 - get_page_size(env, dtlb, wi);
|
||||
*ei = (v >> eibase) & 0x7;
|
||||
} else {
|
||||
*ei = (v >> 28) & 0x1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
*ei = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*vpn = v & xtensa_tlb_get_addr_mask(env, dtlb, wi);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Split TLB address into TLB way, entry index and VPN (with index).
|
||||
* See ISA, 4.6.5.5 - 4.6.5.8 for the TLB addressing format
|
||||
*/
|
||||
static void split_tlb_entry_spec(CPUXtensaState *env, uint32_t v, bool dtlb,
|
||||
uint32_t *vpn, uint32_t *wi, uint32_t *ei)
|
||||
{
|
||||
if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
|
||||
*wi = v & (dtlb ? 0xf : 0x7);
|
||||
split_tlb_entry_spec_way(env, v, dtlb, vpn, *wi, ei);
|
||||
} else {
|
||||
*vpn = v & REGION_PAGE_MASK;
|
||||
*wi = 0;
|
||||
*ei = (v >> 29) & 0x7;
|
||||
}
|
||||
}
|
||||
|
||||
static xtensa_tlb_entry *get_tlb_entry(CPUXtensaState *env,
|
||||
uint32_t v, bool dtlb, uint32_t *pwi)
|
||||
{
|
||||
uint32_t vpn;
|
||||
uint32_t wi;
|
||||
uint32_t ei;
|
||||
|
||||
split_tlb_entry_spec(env, v, dtlb, &vpn, &wi, &ei);
|
||||
if (pwi) {
|
||||
*pwi = wi;
|
||||
}
|
||||
return xtensa_tlb_get_entry(env, dtlb, wi, ei);
|
||||
}
|
||||
|
||||
uint32_t HELPER(rtlb0)(CPUXtensaState *env, uint32_t v, uint32_t dtlb)
|
||||
{
|
||||
if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
|
||||
uint32_t wi;
|
||||
const xtensa_tlb_entry *entry = get_tlb_entry(env, v, dtlb, &wi);
|
||||
return (entry->vaddr & get_vpn_mask(env, dtlb, wi)) | entry->asid;
|
||||
} else {
|
||||
return v & REGION_PAGE_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t HELPER(rtlb1)(CPUXtensaState *env, uint32_t v, uint32_t dtlb)
|
||||
{
|
||||
const xtensa_tlb_entry *entry = get_tlb_entry(env, v, dtlb, NULL);
|
||||
return entry->paddr | entry->attr;
|
||||
}
|
||||
|
||||
void HELPER(itlb)(CPUXtensaState *env, uint32_t v, uint32_t dtlb)
|
||||
{
|
||||
if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
|
||||
uint32_t wi;
|
||||
xtensa_tlb_entry *entry = get_tlb_entry(env, v, dtlb, &wi);
|
||||
if (entry->variable && entry->asid) {
|
||||
tlb_flush_page(CPU(xtensa_env_get_cpu(env)), entry->vaddr);
|
||||
entry->asid = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t HELPER(ptlb)(CPUXtensaState *env, uint32_t v, uint32_t dtlb)
|
||||
{
|
||||
if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
|
||||
uint32_t wi;
|
||||
uint32_t ei;
|
||||
uint8_t ring;
|
||||
int res = xtensa_tlb_lookup(env, v, dtlb, &wi, &ei, &ring);
|
||||
|
||||
switch (res) {
|
||||
case 0:
|
||||
if (ring >= xtensa_get_ring(env)) {
|
||||
return (v & 0xfffff000) | wi | (dtlb ? 0x10 : 0x8);
|
||||
}
|
||||
break;
|
||||
|
||||
case INST_TLB_MULTI_HIT_CAUSE:
|
||||
case LOAD_STORE_TLB_MULTI_HIT_CAUSE:
|
||||
HELPER(exception_cause_vaddr)(env, env->pc, res, v);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return (v & REGION_PAGE_MASK) | 0x1;
|
||||
}
|
||||
}
|
||||
|
||||
void xtensa_tlb_set_entry_mmu(const CPUXtensaState *env,
|
||||
xtensa_tlb_entry *entry, bool dtlb,
|
||||
unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte)
|
||||
{
|
||||
entry->vaddr = vpn;
|
||||
entry->paddr = pte & xtensa_tlb_get_addr_mask(env, dtlb, wi);
|
||||
entry->asid = (env->sregs[RASID] >> ((pte >> 1) & 0x18)) & 0xff;
|
||||
entry->attr = pte & 0xf;
|
||||
}
|
||||
|
||||
void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb,
|
||||
unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte)
|
||||
{
|
||||
XtensaCPU *cpu = xtensa_env_get_cpu(env);
|
||||
CPUState *cs = CPU(cpu);
|
||||
xtensa_tlb_entry *entry = xtensa_tlb_get_entry(env, dtlb, wi, ei);
|
||||
|
||||
if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
|
||||
if (entry->variable) {
|
||||
if (entry->asid) {
|
||||
tlb_flush_page(cs, entry->vaddr);
|
||||
}
|
||||
xtensa_tlb_set_entry_mmu(env, entry, dtlb, wi, ei, vpn, pte);
|
||||
tlb_flush_page(cs, entry->vaddr);
|
||||
} else {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s %d, %d, %d trying to set immutable entry\n",
|
||||
__func__, dtlb, wi, ei);
|
||||
}
|
||||
} else {
|
||||
tlb_flush_page(cs, entry->vaddr);
|
||||
if (xtensa_option_enabled(env->config,
|
||||
XTENSA_OPTION_REGION_TRANSLATION)) {
|
||||
entry->paddr = pte & REGION_PAGE_MASK;
|
||||
}
|
||||
entry->attr = pte & 0xf;
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(wtlb)(CPUXtensaState *env, uint32_t p, uint32_t v, uint32_t dtlb)
|
||||
{
|
||||
uint32_t vpn;
|
||||
uint32_t wi;
|
||||
uint32_t ei;
|
||||
split_tlb_entry_spec(env, v, dtlb, &vpn, &wi, &ei);
|
||||
xtensa_tlb_set_entry(env, dtlb, wi, ei, vpn, p);
|
||||
}
|
||||
|
||||
|
||||
void HELPER(wsr_ibreakenable)(CPUXtensaState *env, uint32_t v)
|
||||
{
|
||||
uint32_t change = v ^ env->sregs[IBREAKENABLE];
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < env->config->nibreak; ++i) {
|
||||
if (change & (1 << i)) {
|
||||
tb_invalidate_virtual_addr(env, env->sregs[IBREAKA + i]);
|
||||
}
|
||||
}
|
||||
env->sregs[IBREAKENABLE] = v & ((1 << env->config->nibreak) - 1);
|
||||
}
|
||||
|
||||
void HELPER(wsr_ibreaka)(CPUXtensaState *env, uint32_t i, uint32_t v)
|
||||
{
|
||||
if (env->sregs[IBREAKENABLE] & (1 << i) && env->sregs[IBREAKA + i] != v) {
|
||||
tb_invalidate_virtual_addr(env, env->sregs[IBREAKA + i]);
|
||||
tb_invalidate_virtual_addr(env, v);
|
||||
}
|
||||
env->sregs[IBREAKA + i] = v;
|
||||
}
|
||||
|
||||
static void set_dbreak(CPUXtensaState *env, unsigned i, uint32_t dbreaka,
|
||||
uint32_t dbreakc)
|
||||
{
|
||||
CPUState *cs = CPU(xtensa_env_get_cpu(env));
|
||||
int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;
|
||||
uint32_t mask = dbreakc | ~DBREAKC_MASK;
|
||||
|
||||
if (env->cpu_watchpoint[i]) {
|
||||
cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[i]);
|
||||
}
|
||||
if (dbreakc & DBREAKC_SB) {
|
||||
flags |= BP_MEM_WRITE;
|
||||
}
|
||||
if (dbreakc & DBREAKC_LB) {
|
||||
flags |= BP_MEM_READ;
|
||||
}
|
||||
/* contiguous mask after inversion is one less than some power of 2 */
|
||||
if ((~mask + 1) & ~mask) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "DBREAKC mask is not contiguous: 0x%08x\n", dbreakc);
|
||||
/* cut mask after the first zero bit */
|
||||
mask = 0xffffffff << (32 - clo32(mask));
|
||||
}
|
||||
if (cpu_watchpoint_insert(cs, dbreaka & mask, ~mask + 1,
|
||||
flags, &env->cpu_watchpoint[i])) {
|
||||
env->cpu_watchpoint[i] = NULL;
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "Failed to set data breakpoint at 0x%08x/%d\n",
|
||||
dbreaka & mask, ~mask + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(wsr_dbreaka)(CPUXtensaState *env, uint32_t i, uint32_t v)
|
||||
{
|
||||
uint32_t dbreakc = env->sregs[DBREAKC + i];
|
||||
|
||||
if ((dbreakc & DBREAKC_SB_LB) &&
|
||||
env->sregs[DBREAKA + i] != v) {
|
||||
set_dbreak(env, i, v, dbreakc);
|
||||
}
|
||||
env->sregs[DBREAKA + i] = v;
|
||||
}
|
||||
|
||||
void HELPER(wsr_dbreakc)(CPUXtensaState *env, uint32_t i, uint32_t v)
|
||||
{
|
||||
if ((env->sregs[DBREAKC + i] ^ v) & (DBREAKC_SB_LB | DBREAKC_MASK)) {
|
||||
if (v & DBREAKC_SB_LB) {
|
||||
set_dbreak(env, i, env->sregs[DBREAKA + i], v);
|
||||
} else {
|
||||
if (env->cpu_watchpoint[i]) {
|
||||
CPUState *cs = CPU(xtensa_env_get_cpu(env));
|
||||
|
||||
cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[i]);
|
||||
env->cpu_watchpoint[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
env->sregs[DBREAKC + i] = v;
|
||||
}
|
||||
|
||||
void HELPER(wur_fcr)(CPUXtensaState *env, uint32_t v)
|
||||
{
|
||||
static const int rounding_mode[] = {
|
||||
float_round_nearest_even,
|
||||
float_round_to_zero,
|
||||
float_round_up,
|
||||
float_round_down,
|
||||
};
|
||||
|
||||
env->uregs[FCR] = v & 0xfffff07f;
|
||||
set_float_rounding_mode(rounding_mode[v & 3], &env->fp_status);
|
||||
}
|
||||
|
||||
float32 HELPER(abs_s)(float32 v)
|
||||
{
|
||||
return float32_abs(v);
|
||||
}
|
||||
|
||||
float32 HELPER(neg_s)(float32 v)
|
||||
{
|
||||
return float32_chs(v);
|
||||
}
|
||||
|
||||
float32 HELPER(add_s)(CPUXtensaState *env, float32 a, float32 b)
|
||||
{
|
||||
return float32_add(a, b, &env->fp_status);
|
||||
}
|
||||
|
||||
float32 HELPER(sub_s)(CPUXtensaState *env, float32 a, float32 b)
|
||||
{
|
||||
return float32_sub(a, b, &env->fp_status);
|
||||
}
|
||||
|
||||
float32 HELPER(mul_s)(CPUXtensaState *env, float32 a, float32 b)
|
||||
{
|
||||
return float32_mul(a, b, &env->fp_status);
|
||||
}
|
||||
|
||||
float32 HELPER(madd_s)(CPUXtensaState *env, float32 a, float32 b, float32 c)
|
||||
{
|
||||
return float32_muladd(b, c, a, 0,
|
||||
&env->fp_status);
|
||||
}
|
||||
|
||||
float32 HELPER(msub_s)(CPUXtensaState *env, float32 a, float32 b, float32 c)
|
||||
{
|
||||
return float32_muladd(b, c, a, float_muladd_negate_product,
|
||||
&env->fp_status);
|
||||
}
|
||||
|
||||
uint32_t HELPER(ftoi)(float32 v, uint32_t rounding_mode, uint32_t scale)
|
||||
{
|
||||
float_status fp_status = {0};
|
||||
|
||||
set_float_rounding_mode(rounding_mode, &fp_status);
|
||||
return float32_to_int32(
|
||||
float32_scalbn(v, scale, &fp_status), &fp_status);
|
||||
}
|
||||
|
||||
uint32_t HELPER(ftoui)(float32 v, uint32_t rounding_mode, uint32_t scale)
|
||||
{
|
||||
float_status fp_status = {0};
|
||||
float32 res;
|
||||
|
||||
set_float_rounding_mode(rounding_mode, &fp_status);
|
||||
|
||||
res = float32_scalbn(v, scale, &fp_status);
|
||||
|
||||
if (float32_is_neg(v) && !float32_is_any_nan(v)) {
|
||||
return float32_to_int32(res, &fp_status);
|
||||
} else {
|
||||
return float32_to_uint32(res, &fp_status);
|
||||
}
|
||||
}
|
||||
|
||||
float32 HELPER(itof)(CPUXtensaState *env, uint32_t v, uint32_t scale)
|
||||
{
|
||||
return float32_scalbn(int32_to_float32(v, &env->fp_status),
|
||||
(int32_t)scale, &env->fp_status);
|
||||
}
|
||||
|
||||
float32 HELPER(uitof)(CPUXtensaState *env, uint32_t v, uint32_t scale)
|
||||
{
|
||||
return float32_scalbn(uint32_to_float32(v, &env->fp_status),
|
||||
(int32_t)scale, &env->fp_status);
|
||||
}
|
||||
|
||||
static inline void set_br(CPUXtensaState *env, bool v, uint32_t br)
|
||||
{
|
||||
if (v) {
|
||||
env->sregs[BR] |= br;
|
||||
} else {
|
||||
env->sregs[BR] &= ~br;
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(un_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
|
||||
{
|
||||
set_br(env, float32_unordered_quiet(a, b, &env->fp_status), br);
|
||||
}
|
||||
|
||||
void HELPER(oeq_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
|
||||
{
|
||||
set_br(env, float32_eq_quiet(a, b, &env->fp_status), br);
|
||||
}
|
||||
|
||||
void HELPER(ueq_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
|
||||
{
|
||||
int v = float32_compare_quiet(a, b, &env->fp_status);
|
||||
set_br(env, v == float_relation_equal || v == float_relation_unordered, br);
|
||||
}
|
||||
|
||||
void HELPER(olt_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
|
||||
{
|
||||
set_br(env, float32_lt_quiet(a, b, &env->fp_status), br);
|
||||
}
|
||||
|
||||
void HELPER(ult_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
|
||||
{
|
||||
int v = float32_compare_quiet(a, b, &env->fp_status);
|
||||
set_br(env, v == float_relation_less || v == float_relation_unordered, br);
|
||||
}
|
||||
|
||||
void HELPER(ole_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
|
||||
{
|
||||
set_br(env, float32_le_quiet(a, b, &env->fp_status), br);
|
||||
}
|
||||
|
||||
void HELPER(ule_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
|
||||
{
|
||||
int v = float32_compare_quiet(a, b, &env->fp_status);
|
||||
set_br(env, v != float_relation_greater, br);
|
||||
}
|
602
target/xtensa/overlay_tool.h
Normal file
602
target/xtensa/overlay_tool.h
Normal file
|
@ -0,0 +1,602 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of the Open Source and Linux Lab 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 COPYRIGHT HOLDERS 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
#define XTREG(idx, ofs, bi, sz, al, no, flags, cp, typ, grp, name, \
|
||||
a1, a2, a3, a4, a5, a6) \
|
||||
{ .targno = (no), .type = (typ), .group = (grp), .size = (sz) },
|
||||
#define XTREG_END { .targno = -1 },
|
||||
|
||||
#ifndef XCHAL_HAVE_DEPBITS
|
||||
#define XCHAL_HAVE_DEPBITS 0
|
||||
#endif
|
||||
|
||||
#ifndef XCHAL_HAVE_DIV32
|
||||
#define XCHAL_HAVE_DIV32 0
|
||||
#endif
|
||||
|
||||
#ifndef XCHAL_UNALIGNED_LOAD_HW
|
||||
#define XCHAL_UNALIGNED_LOAD_HW 0
|
||||
#endif
|
||||
|
||||
#ifndef XCHAL_HAVE_VECBASE
|
||||
#define XCHAL_HAVE_VECBASE 0
|
||||
#define XCHAL_VECBASE_RESET_VADDR 0
|
||||
#endif
|
||||
|
||||
#ifndef XCHAL_HW_MIN_VERSION
|
||||
#define XCHAL_HW_MIN_VERSION 0
|
||||
#endif
|
||||
|
||||
#define XCHAL_OPTION(xchal, qemu) ((xchal) ? XTENSA_OPTION_BIT(qemu) : 0)
|
||||
|
||||
#define XTENSA_OPTIONS ( \
|
||||
XCHAL_OPTION(XCHAL_HAVE_DENSITY, XTENSA_OPTION_CODE_DENSITY) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_LOOPS, XTENSA_OPTION_LOOP) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_ABSOLUTE_LITERALS, XTENSA_OPTION_EXTENDED_L32R) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_MUL16, XTENSA_OPTION_16_BIT_IMUL) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_MUL32, XTENSA_OPTION_32_BIT_IMUL) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_MUL32_HIGH, XTENSA_OPTION_32_BIT_IMUL_HIGH) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_DIV32, XTENSA_OPTION_32_BIT_IDIV) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_MAC16, XTENSA_OPTION_MAC16) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_NSA, XTENSA_OPTION_MISC_OP_NSA) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_MINMAX, XTENSA_OPTION_MISC_OP_MINMAX) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_SEXT, XTENSA_OPTION_MISC_OP_SEXT) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_CLAMPS, XTENSA_OPTION_MISC_OP_CLAMPS) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_CP, XTENSA_OPTION_COPROCESSOR) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_BOOLEANS, XTENSA_OPTION_BOOLEAN) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_FP, XTENSA_OPTION_FP_COPROCESSOR) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_RELEASE_SYNC, XTENSA_OPTION_MP_SYNCHRO) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_S32C1I, XTENSA_OPTION_CONDITIONAL_STORE) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_S32C1I && XCHAL_HW_MIN_VERSION >= 230000, \
|
||||
XTENSA_OPTION_ATOMCTL) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_DEPBITS, XTENSA_OPTION_DEPBITS) | \
|
||||
/* Interrupts and exceptions */ \
|
||||
XCHAL_OPTION(XCHAL_HAVE_EXCEPTIONS, XTENSA_OPTION_EXCEPTION) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_VECBASE, XTENSA_OPTION_RELOCATABLE_VECTOR) | \
|
||||
XCHAL_OPTION(XCHAL_UNALIGNED_LOAD_EXCEPTION, \
|
||||
XTENSA_OPTION_UNALIGNED_EXCEPTION) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_INTERRUPTS, XTENSA_OPTION_INTERRUPT) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_HIGHPRI_INTERRUPTS, \
|
||||
XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_CCOUNT, XTENSA_OPTION_TIMER_INTERRUPT) | \
|
||||
/* Local memory, TODO */ \
|
||||
XCHAL_OPTION(XCHAL_ICACHE_WAYS, XTENSA_OPTION_ICACHE) | \
|
||||
XCHAL_OPTION(XCHAL_ICACHE_LINE_LOCKABLE, \
|
||||
XTENSA_OPTION_ICACHE_INDEX_LOCK) | \
|
||||
XCHAL_OPTION(XCHAL_DCACHE_WAYS, XTENSA_OPTION_DCACHE) | \
|
||||
XCHAL_OPTION(XCHAL_DCACHE_LINE_LOCKABLE, \
|
||||
XTENSA_OPTION_DCACHE_INDEX_LOCK) | \
|
||||
XCHAL_OPTION(XCHAL_UNALIGNED_LOAD_HW, XTENSA_OPTION_HW_ALIGNMENT) | \
|
||||
/* Memory protection and translation */ \
|
||||
XCHAL_OPTION(XCHAL_HAVE_MIMIC_CACHEATTR, \
|
||||
XTENSA_OPTION_REGION_PROTECTION) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_XLT_CACHEATTR, \
|
||||
XTENSA_OPTION_REGION_TRANSLATION) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_PTP_MMU, XTENSA_OPTION_MMU) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_CACHEATTR, XTENSA_OPTION_CACHEATTR) | \
|
||||
/* Other, TODO */ \
|
||||
XCHAL_OPTION(XCHAL_HAVE_WINDOWED, XTENSA_OPTION_WINDOWED_REGISTER) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_DEBUG, XTENSA_OPTION_DEBUG) |\
|
||||
XCHAL_OPTION(XCHAL_NUM_MISC_REGS > 0, XTENSA_OPTION_MISC_SR) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_THREADPTR, XTENSA_OPTION_THREAD_POINTER) | \
|
||||
XCHAL_OPTION(XCHAL_HAVE_PRID, XTENSA_OPTION_PROCESSOR_ID))
|
||||
|
||||
#ifndef XCHAL_WINDOW_OF4_VECOFS
|
||||
#define XCHAL_WINDOW_OF4_VECOFS 0x00000000
|
||||
#define XCHAL_WINDOW_UF4_VECOFS 0x00000040
|
||||
#define XCHAL_WINDOW_OF8_VECOFS 0x00000080
|
||||
#define XCHAL_WINDOW_UF8_VECOFS 0x000000C0
|
||||
#define XCHAL_WINDOW_OF12_VECOFS 0x00000100
|
||||
#define XCHAL_WINDOW_UF12_VECOFS 0x00000140
|
||||
#endif
|
||||
|
||||
#if XCHAL_HAVE_WINDOWED
|
||||
#define WINDOW_VECTORS \
|
||||
[EXC_WINDOW_OVERFLOW4] = XCHAL_WINDOW_OF4_VECOFS + \
|
||||
XCHAL_WINDOW_VECTORS_VADDR, \
|
||||
[EXC_WINDOW_UNDERFLOW4] = XCHAL_WINDOW_UF4_VECOFS + \
|
||||
XCHAL_WINDOW_VECTORS_VADDR, \
|
||||
[EXC_WINDOW_OVERFLOW8] = XCHAL_WINDOW_OF8_VECOFS + \
|
||||
XCHAL_WINDOW_VECTORS_VADDR, \
|
||||
[EXC_WINDOW_UNDERFLOW8] = XCHAL_WINDOW_UF8_VECOFS + \
|
||||
XCHAL_WINDOW_VECTORS_VADDR, \
|
||||
[EXC_WINDOW_OVERFLOW12] = XCHAL_WINDOW_OF12_VECOFS + \
|
||||
XCHAL_WINDOW_VECTORS_VADDR, \
|
||||
[EXC_WINDOW_UNDERFLOW12] = XCHAL_WINDOW_UF12_VECOFS + \
|
||||
XCHAL_WINDOW_VECTORS_VADDR,
|
||||
#else
|
||||
#define WINDOW_VECTORS
|
||||
#endif
|
||||
|
||||
#define EXCEPTION_VECTORS { \
|
||||
[EXC_RESET] = XCHAL_RESET_VECTOR_VADDR, \
|
||||
WINDOW_VECTORS \
|
||||
[EXC_KERNEL] = XCHAL_KERNEL_VECTOR_VADDR, \
|
||||
[EXC_USER] = XCHAL_USER_VECTOR_VADDR, \
|
||||
[EXC_DOUBLE] = XCHAL_DOUBLEEXC_VECTOR_VADDR, \
|
||||
[EXC_DEBUG] = XCHAL_DEBUG_VECTOR_VADDR, \
|
||||
}
|
||||
|
||||
#define INTERRUPT_VECTORS { \
|
||||
0, \
|
||||
0, \
|
||||
XCHAL_INTLEVEL2_VECTOR_VADDR, \
|
||||
XCHAL_INTLEVEL3_VECTOR_VADDR, \
|
||||
XCHAL_INTLEVEL4_VECTOR_VADDR, \
|
||||
XCHAL_INTLEVEL5_VECTOR_VADDR, \
|
||||
XCHAL_INTLEVEL6_VECTOR_VADDR, \
|
||||
XCHAL_INTLEVEL7_VECTOR_VADDR, \
|
||||
}
|
||||
|
||||
#define LEVEL_MASKS { \
|
||||
[1] = XCHAL_INTLEVEL1_MASK, \
|
||||
[2] = XCHAL_INTLEVEL2_MASK, \
|
||||
[3] = XCHAL_INTLEVEL3_MASK, \
|
||||
[4] = XCHAL_INTLEVEL4_MASK, \
|
||||
[5] = XCHAL_INTLEVEL5_MASK, \
|
||||
[6] = XCHAL_INTLEVEL6_MASK, \
|
||||
[7] = XCHAL_INTLEVEL7_MASK, \
|
||||
}
|
||||
|
||||
#define INTTYPE_MASKS { \
|
||||
[INTTYPE_EDGE] = XCHAL_INTTYPE_MASK_EXTERN_EDGE, \
|
||||
[INTTYPE_NMI] = XCHAL_INTTYPE_MASK_NMI, \
|
||||
[INTTYPE_SOFTWARE] = XCHAL_INTTYPE_MASK_SOFTWARE, \
|
||||
}
|
||||
|
||||
#define XTHAL_INTTYPE_EXTERN_LEVEL INTTYPE_LEVEL
|
||||
#define XTHAL_INTTYPE_EXTERN_EDGE INTTYPE_EDGE
|
||||
#define XTHAL_INTTYPE_NMI INTTYPE_NMI
|
||||
#define XTHAL_INTTYPE_SOFTWARE INTTYPE_SOFTWARE
|
||||
#define XTHAL_INTTYPE_TIMER INTTYPE_TIMER
|
||||
#define XTHAL_INTTYPE_TBD1 INTTYPE_DEBUG
|
||||
#define XTHAL_INTTYPE_TBD2 INTTYPE_WRITE_ERR
|
||||
#define XTHAL_INTTYPE_WRITE_ERROR INTTYPE_WRITE_ERR
|
||||
#define XTHAL_INTTYPE_PROFILING INTTYPE_PROFILING
|
||||
|
||||
|
||||
#define INTERRUPT(i) { \
|
||||
.level = XCHAL_INT ## i ## _LEVEL, \
|
||||
.inttype = XCHAL_INT ## i ## _TYPE, \
|
||||
}
|
||||
|
||||
#define INTERRUPTS { \
|
||||
[0] = INTERRUPT(0), \
|
||||
[1] = INTERRUPT(1), \
|
||||
[2] = INTERRUPT(2), \
|
||||
[3] = INTERRUPT(3), \
|
||||
[4] = INTERRUPT(4), \
|
||||
[5] = INTERRUPT(5), \
|
||||
[6] = INTERRUPT(6), \
|
||||
[7] = INTERRUPT(7), \
|
||||
[8] = INTERRUPT(8), \
|
||||
[9] = INTERRUPT(9), \
|
||||
[10] = INTERRUPT(10), \
|
||||
[11] = INTERRUPT(11), \
|
||||
[12] = INTERRUPT(12), \
|
||||
[13] = INTERRUPT(13), \
|
||||
[14] = INTERRUPT(14), \
|
||||
[15] = INTERRUPT(15), \
|
||||
[16] = INTERRUPT(16), \
|
||||
[17] = INTERRUPT(17), \
|
||||
[18] = INTERRUPT(18), \
|
||||
[19] = INTERRUPT(19), \
|
||||
[20] = INTERRUPT(20), \
|
||||
[21] = INTERRUPT(21), \
|
||||
[22] = INTERRUPT(22), \
|
||||
[23] = INTERRUPT(23), \
|
||||
[24] = INTERRUPT(24), \
|
||||
[25] = INTERRUPT(25), \
|
||||
[26] = INTERRUPT(26), \
|
||||
[27] = INTERRUPT(27), \
|
||||
[28] = INTERRUPT(28), \
|
||||
[29] = INTERRUPT(29), \
|
||||
[30] = INTERRUPT(30), \
|
||||
[31] = INTERRUPT(31), \
|
||||
}
|
||||
|
||||
#define TIMERINTS { \
|
||||
[0] = XCHAL_TIMER0_INTERRUPT, \
|
||||
[1] = XCHAL_TIMER1_INTERRUPT, \
|
||||
[2] = XCHAL_TIMER2_INTERRUPT, \
|
||||
}
|
||||
|
||||
#define EXTINTS { \
|
||||
[0] = XCHAL_EXTINT0_NUM, \
|
||||
[1] = XCHAL_EXTINT1_NUM, \
|
||||
[2] = XCHAL_EXTINT2_NUM, \
|
||||
[3] = XCHAL_EXTINT3_NUM, \
|
||||
[4] = XCHAL_EXTINT4_NUM, \
|
||||
[5] = XCHAL_EXTINT5_NUM, \
|
||||
[6] = XCHAL_EXTINT6_NUM, \
|
||||
[7] = XCHAL_EXTINT7_NUM, \
|
||||
[8] = XCHAL_EXTINT8_NUM, \
|
||||
[9] = XCHAL_EXTINT9_NUM, \
|
||||
[10] = XCHAL_EXTINT10_NUM, \
|
||||
[11] = XCHAL_EXTINT11_NUM, \
|
||||
[12] = XCHAL_EXTINT12_NUM, \
|
||||
[13] = XCHAL_EXTINT13_NUM, \
|
||||
[14] = XCHAL_EXTINT14_NUM, \
|
||||
[15] = XCHAL_EXTINT15_NUM, \
|
||||
[16] = XCHAL_EXTINT16_NUM, \
|
||||
[17] = XCHAL_EXTINT17_NUM, \
|
||||
[18] = XCHAL_EXTINT18_NUM, \
|
||||
[19] = XCHAL_EXTINT19_NUM, \
|
||||
[20] = XCHAL_EXTINT20_NUM, \
|
||||
[21] = XCHAL_EXTINT21_NUM, \
|
||||
[22] = XCHAL_EXTINT22_NUM, \
|
||||
[23] = XCHAL_EXTINT23_NUM, \
|
||||
[24] = XCHAL_EXTINT24_NUM, \
|
||||
[25] = XCHAL_EXTINT25_NUM, \
|
||||
[26] = XCHAL_EXTINT26_NUM, \
|
||||
[27] = XCHAL_EXTINT27_NUM, \
|
||||
[28] = XCHAL_EXTINT28_NUM, \
|
||||
[29] = XCHAL_EXTINT29_NUM, \
|
||||
[30] = XCHAL_EXTINT30_NUM, \
|
||||
[31] = XCHAL_EXTINT31_NUM, \
|
||||
}
|
||||
|
||||
#define EXCEPTIONS_SECTION \
|
||||
.excm_level = XCHAL_EXCM_LEVEL, \
|
||||
.vecbase = XCHAL_VECBASE_RESET_VADDR, \
|
||||
.exception_vector = EXCEPTION_VECTORS
|
||||
|
||||
#define INTERRUPTS_SECTION \
|
||||
.ninterrupt = XCHAL_NUM_INTERRUPTS, \
|
||||
.nlevel = XCHAL_NUM_INTLEVELS, \
|
||||
.interrupt_vector = INTERRUPT_VECTORS, \
|
||||
.level_mask = LEVEL_MASKS, \
|
||||
.inttype_mask = INTTYPE_MASKS, \
|
||||
.interrupt = INTERRUPTS, \
|
||||
.nccompare = XCHAL_NUM_TIMERS, \
|
||||
.timerint = TIMERINTS, \
|
||||
.nextint = XCHAL_NUM_EXTINTERRUPTS, \
|
||||
.extint = EXTINTS
|
||||
|
||||
#if XCHAL_HAVE_PTP_MMU
|
||||
|
||||
#define TLB_TEMPLATE(ways, refill_way_size, way56) { \
|
||||
.nways = ways, \
|
||||
.way_size = { \
|
||||
(refill_way_size), (refill_way_size), \
|
||||
(refill_way_size), (refill_way_size), \
|
||||
4, (way56) ? 4 : 2, (way56) ? 8 : 2, 1, 1, 1, \
|
||||
}, \
|
||||
.varway56 = (way56), \
|
||||
.nrefillentries = (refill_way_size) * 4, \
|
||||
}
|
||||
|
||||
#define ITLB(varway56) \
|
||||
TLB_TEMPLATE(7, 1 << XCHAL_ITLB_ARF_ENTRIES_LOG2, varway56)
|
||||
|
||||
#define DTLB(varway56) \
|
||||
TLB_TEMPLATE(10, 1 << XCHAL_DTLB_ARF_ENTRIES_LOG2, varway56)
|
||||
|
||||
#define TLB_SECTION \
|
||||
.itlb = ITLB(XCHAL_HAVE_SPANNING_WAY), \
|
||||
.dtlb = DTLB(XCHAL_HAVE_SPANNING_WAY)
|
||||
|
||||
#elif XCHAL_HAVE_XLT_CACHEATTR || XCHAL_HAVE_MIMIC_CACHEATTR
|
||||
|
||||
#define TLB_TEMPLATE { \
|
||||
.nways = 1, \
|
||||
.way_size = { \
|
||||
8, \
|
||||
} \
|
||||
}
|
||||
|
||||
#define TLB_SECTION \
|
||||
.itlb = TLB_TEMPLATE, \
|
||||
.dtlb = TLB_TEMPLATE
|
||||
|
||||
#endif
|
||||
|
||||
#if (defined(TARGET_WORDS_BIGENDIAN) != 0) == (XCHAL_HAVE_BE != 0)
|
||||
#define REGISTER_CORE(core) \
|
||||
static void __attribute__((constructor)) register_core(void) \
|
||||
{ \
|
||||
static XtensaConfigList node = { \
|
||||
.config = &core, \
|
||||
}; \
|
||||
xtensa_finalize_config(&core); \
|
||||
xtensa_register_core(&node); \
|
||||
}
|
||||
#else
|
||||
#define REGISTER_CORE(core)
|
||||
#endif
|
||||
|
||||
#define DEBUG_SECTION \
|
||||
.debug_level = XCHAL_DEBUGLEVEL, \
|
||||
.nibreak = XCHAL_NUM_IBREAK, \
|
||||
.ndbreak = XCHAL_NUM_DBREAK
|
||||
|
||||
#define CONFIG_SECTION \
|
||||
.configid = { \
|
||||
XCHAL_HW_CONFIGID0, \
|
||||
XCHAL_HW_CONFIGID1, \
|
||||
}
|
||||
|
||||
#define DEFAULT_SECTIONS \
|
||||
.options = XTENSA_OPTIONS, \
|
||||
.nareg = XCHAL_NUM_AREGS, \
|
||||
.ndepc = (XCHAL_XEA_VERSION >= 2), \
|
||||
EXCEPTIONS_SECTION, \
|
||||
INTERRUPTS_SECTION, \
|
||||
TLB_SECTION, \
|
||||
DEBUG_SECTION, \
|
||||
CONFIG_SECTION
|
||||
|
||||
|
||||
#if XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI + 1 <= 2
|
||||
#define XCHAL_INTLEVEL2_VECTOR_VADDR 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI + 1 <= 3
|
||||
#define XCHAL_INTLEVEL3_VECTOR_VADDR 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI + 1 <= 4
|
||||
#define XCHAL_INTLEVEL4_VECTOR_VADDR 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI + 1 <= 5
|
||||
#define XCHAL_INTLEVEL5_VECTOR_VADDR 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI + 1 <= 6
|
||||
#define XCHAL_INTLEVEL6_VECTOR_VADDR 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI + 1 <= 7
|
||||
#define XCHAL_INTLEVEL7_VECTOR_VADDR 0
|
||||
#endif
|
||||
|
||||
|
||||
#if XCHAL_NUM_INTERRUPTS <= 0
|
||||
#define XCHAL_INT0_LEVEL 0
|
||||
#define XCHAL_INT0_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 1
|
||||
#define XCHAL_INT1_LEVEL 0
|
||||
#define XCHAL_INT1_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 2
|
||||
#define XCHAL_INT2_LEVEL 0
|
||||
#define XCHAL_INT2_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 3
|
||||
#define XCHAL_INT3_LEVEL 0
|
||||
#define XCHAL_INT3_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 4
|
||||
#define XCHAL_INT4_LEVEL 0
|
||||
#define XCHAL_INT4_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 5
|
||||
#define XCHAL_INT5_LEVEL 0
|
||||
#define XCHAL_INT5_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 6
|
||||
#define XCHAL_INT6_LEVEL 0
|
||||
#define XCHAL_INT6_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 7
|
||||
#define XCHAL_INT7_LEVEL 0
|
||||
#define XCHAL_INT7_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 8
|
||||
#define XCHAL_INT8_LEVEL 0
|
||||
#define XCHAL_INT8_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 9
|
||||
#define XCHAL_INT9_LEVEL 0
|
||||
#define XCHAL_INT9_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 10
|
||||
#define XCHAL_INT10_LEVEL 0
|
||||
#define XCHAL_INT10_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 11
|
||||
#define XCHAL_INT11_LEVEL 0
|
||||
#define XCHAL_INT11_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 12
|
||||
#define XCHAL_INT12_LEVEL 0
|
||||
#define XCHAL_INT12_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 13
|
||||
#define XCHAL_INT13_LEVEL 0
|
||||
#define XCHAL_INT13_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 14
|
||||
#define XCHAL_INT14_LEVEL 0
|
||||
#define XCHAL_INT14_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 15
|
||||
#define XCHAL_INT15_LEVEL 0
|
||||
#define XCHAL_INT15_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 16
|
||||
#define XCHAL_INT16_LEVEL 0
|
||||
#define XCHAL_INT16_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 17
|
||||
#define XCHAL_INT17_LEVEL 0
|
||||
#define XCHAL_INT17_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 18
|
||||
#define XCHAL_INT18_LEVEL 0
|
||||
#define XCHAL_INT18_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 19
|
||||
#define XCHAL_INT19_LEVEL 0
|
||||
#define XCHAL_INT19_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 20
|
||||
#define XCHAL_INT20_LEVEL 0
|
||||
#define XCHAL_INT20_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 21
|
||||
#define XCHAL_INT21_LEVEL 0
|
||||
#define XCHAL_INT21_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 22
|
||||
#define XCHAL_INT22_LEVEL 0
|
||||
#define XCHAL_INT22_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 23
|
||||
#define XCHAL_INT23_LEVEL 0
|
||||
#define XCHAL_INT23_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 24
|
||||
#define XCHAL_INT24_LEVEL 0
|
||||
#define XCHAL_INT24_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 25
|
||||
#define XCHAL_INT25_LEVEL 0
|
||||
#define XCHAL_INT25_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 26
|
||||
#define XCHAL_INT26_LEVEL 0
|
||||
#define XCHAL_INT26_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 27
|
||||
#define XCHAL_INT27_LEVEL 0
|
||||
#define XCHAL_INT27_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 28
|
||||
#define XCHAL_INT28_LEVEL 0
|
||||
#define XCHAL_INT28_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 29
|
||||
#define XCHAL_INT29_LEVEL 0
|
||||
#define XCHAL_INT29_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 30
|
||||
#define XCHAL_INT30_LEVEL 0
|
||||
#define XCHAL_INT30_TYPE 0
|
||||
#endif
|
||||
#if XCHAL_NUM_INTERRUPTS <= 31
|
||||
#define XCHAL_INT31_LEVEL 0
|
||||
#define XCHAL_INT31_TYPE 0
|
||||
#endif
|
||||
|
||||
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 0
|
||||
#define XCHAL_EXTINT0_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 1
|
||||
#define XCHAL_EXTINT1_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 2
|
||||
#define XCHAL_EXTINT2_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 3
|
||||
#define XCHAL_EXTINT3_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 4
|
||||
#define XCHAL_EXTINT4_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 5
|
||||
#define XCHAL_EXTINT5_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 6
|
||||
#define XCHAL_EXTINT6_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 7
|
||||
#define XCHAL_EXTINT7_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 8
|
||||
#define XCHAL_EXTINT8_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 9
|
||||
#define XCHAL_EXTINT9_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 10
|
||||
#define XCHAL_EXTINT10_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 11
|
||||
#define XCHAL_EXTINT11_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 12
|
||||
#define XCHAL_EXTINT12_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 13
|
||||
#define XCHAL_EXTINT13_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 14
|
||||
#define XCHAL_EXTINT14_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 15
|
||||
#define XCHAL_EXTINT15_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 16
|
||||
#define XCHAL_EXTINT16_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 17
|
||||
#define XCHAL_EXTINT17_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 18
|
||||
#define XCHAL_EXTINT18_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 19
|
||||
#define XCHAL_EXTINT19_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 20
|
||||
#define XCHAL_EXTINT20_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 21
|
||||
#define XCHAL_EXTINT21_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 22
|
||||
#define XCHAL_EXTINT22_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 23
|
||||
#define XCHAL_EXTINT23_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 24
|
||||
#define XCHAL_EXTINT24_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 25
|
||||
#define XCHAL_EXTINT25_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 26
|
||||
#define XCHAL_EXTINT26_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 27
|
||||
#define XCHAL_EXTINT27_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 28
|
||||
#define XCHAL_EXTINT28_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 29
|
||||
#define XCHAL_EXTINT29_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 30
|
||||
#define XCHAL_EXTINT30_NUM 0
|
||||
#endif
|
||||
#if XCHAL_NUM_EXTINTERRUPTS <= 31
|
||||
#define XCHAL_EXTINT31_NUM 0
|
||||
#endif
|
||||
|
||||
|
||||
#define XTHAL_TIMER_UNCONFIGURED 0
|
3225
target/xtensa/translate.c
Normal file
3225
target/xtensa/translate.c
Normal file
File diff suppressed because it is too large
Load diff
318
target/xtensa/xtensa-semi.c
Normal file
318
target/xtensa/xtensa-semi.c
Normal file
|
@ -0,0 +1,318 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of the Open Source and Linux Lab 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 COPYRIGHT HOLDERS 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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
#include "exec/helper-proto.h"
|
||||
#include "qemu/log.h"
|
||||
|
||||
enum {
|
||||
TARGET_SYS_exit = 1,
|
||||
TARGET_SYS_read = 3,
|
||||
TARGET_SYS_write = 4,
|
||||
TARGET_SYS_open = 5,
|
||||
TARGET_SYS_close = 6,
|
||||
TARGET_SYS_lseek = 19,
|
||||
TARGET_SYS_select_one = 29,
|
||||
|
||||
TARGET_SYS_argc = 1000,
|
||||
TARGET_SYS_argv_sz = 1001,
|
||||
TARGET_SYS_argv = 1002,
|
||||
TARGET_SYS_memset = 1004,
|
||||
};
|
||||
|
||||
enum {
|
||||
SELECT_ONE_READ = 1,
|
||||
SELECT_ONE_WRITE = 2,
|
||||
SELECT_ONE_EXCEPT = 3,
|
||||
};
|
||||
|
||||
enum {
|
||||
TARGET_EPERM = 1,
|
||||
TARGET_ENOENT = 2,
|
||||
TARGET_ESRCH = 3,
|
||||
TARGET_EINTR = 4,
|
||||
TARGET_EIO = 5,
|
||||
TARGET_ENXIO = 6,
|
||||
TARGET_E2BIG = 7,
|
||||
TARGET_ENOEXEC = 8,
|
||||
TARGET_EBADF = 9,
|
||||
TARGET_ECHILD = 10,
|
||||
TARGET_EAGAIN = 11,
|
||||
TARGET_ENOMEM = 12,
|
||||
TARGET_EACCES = 13,
|
||||
TARGET_EFAULT = 14,
|
||||
TARGET_ENOTBLK = 15,
|
||||
TARGET_EBUSY = 16,
|
||||
TARGET_EEXIST = 17,
|
||||
TARGET_EXDEV = 18,
|
||||
TARGET_ENODEV = 19,
|
||||
TARGET_ENOTDIR = 20,
|
||||
TARGET_EISDIR = 21,
|
||||
TARGET_EINVAL = 22,
|
||||
TARGET_ENFILE = 23,
|
||||
TARGET_EMFILE = 24,
|
||||
TARGET_ENOTTY = 25,
|
||||
TARGET_ETXTBSY = 26,
|
||||
TARGET_EFBIG = 27,
|
||||
TARGET_ENOSPC = 28,
|
||||
TARGET_ESPIPE = 29,
|
||||
TARGET_EROFS = 30,
|
||||
TARGET_EMLINK = 31,
|
||||
TARGET_EPIPE = 32,
|
||||
TARGET_EDOM = 33,
|
||||
TARGET_ERANGE = 34,
|
||||
TARGET_ENOSYS = 88,
|
||||
TARGET_ELOOP = 92,
|
||||
};
|
||||
|
||||
static uint32_t errno_h2g(int host_errno)
|
||||
{
|
||||
static const uint32_t guest_errno[] = {
|
||||
[EPERM] = TARGET_EPERM,
|
||||
[ENOENT] = TARGET_ENOENT,
|
||||
[ESRCH] = TARGET_ESRCH,
|
||||
[EINTR] = TARGET_EINTR,
|
||||
[EIO] = TARGET_EIO,
|
||||
[ENXIO] = TARGET_ENXIO,
|
||||
[E2BIG] = TARGET_E2BIG,
|
||||
[ENOEXEC] = TARGET_ENOEXEC,
|
||||
[EBADF] = TARGET_EBADF,
|
||||
[ECHILD] = TARGET_ECHILD,
|
||||
[EAGAIN] = TARGET_EAGAIN,
|
||||
[ENOMEM] = TARGET_ENOMEM,
|
||||
[EACCES] = TARGET_EACCES,
|
||||
[EFAULT] = TARGET_EFAULT,
|
||||
#ifdef ENOTBLK
|
||||
[ENOTBLK] = TARGET_ENOTBLK,
|
||||
#endif
|
||||
[EBUSY] = TARGET_EBUSY,
|
||||
[EEXIST] = TARGET_EEXIST,
|
||||
[EXDEV] = TARGET_EXDEV,
|
||||
[ENODEV] = TARGET_ENODEV,
|
||||
[ENOTDIR] = TARGET_ENOTDIR,
|
||||
[EISDIR] = TARGET_EISDIR,
|
||||
[EINVAL] = TARGET_EINVAL,
|
||||
[ENFILE] = TARGET_ENFILE,
|
||||
[EMFILE] = TARGET_EMFILE,
|
||||
[ENOTTY] = TARGET_ENOTTY,
|
||||
#ifdef ETXTBSY
|
||||
[ETXTBSY] = TARGET_ETXTBSY,
|
||||
#endif
|
||||
[EFBIG] = TARGET_EFBIG,
|
||||
[ENOSPC] = TARGET_ENOSPC,
|
||||
[ESPIPE] = TARGET_ESPIPE,
|
||||
[EROFS] = TARGET_EROFS,
|
||||
[EMLINK] = TARGET_EMLINK,
|
||||
[EPIPE] = TARGET_EPIPE,
|
||||
[EDOM] = TARGET_EDOM,
|
||||
[ERANGE] = TARGET_ERANGE,
|
||||
[ENOSYS] = TARGET_ENOSYS,
|
||||
#ifdef ELOOP
|
||||
[ELOOP] = TARGET_ELOOP,
|
||||
#endif
|
||||
};
|
||||
|
||||
if (host_errno == 0) {
|
||||
return 0;
|
||||
} else if (host_errno > 0 && host_errno < ARRAY_SIZE(guest_errno) &&
|
||||
guest_errno[host_errno]) {
|
||||
return guest_errno[host_errno];
|
||||
} else {
|
||||
return TARGET_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(simcall)(CPUXtensaState *env)
|
||||
{
|
||||
CPUState *cs = CPU(xtensa_env_get_cpu(env));
|
||||
uint32_t *regs = env->regs;
|
||||
|
||||
switch (regs[2]) {
|
||||
case TARGET_SYS_exit:
|
||||
qemu_log("exit(%d) simcall\n", regs[3]);
|
||||
exit(regs[3]);
|
||||
break;
|
||||
|
||||
case TARGET_SYS_read:
|
||||
case TARGET_SYS_write:
|
||||
{
|
||||
bool is_write = regs[2] == TARGET_SYS_write;
|
||||
uint32_t fd = regs[3];
|
||||
uint32_t vaddr = regs[4];
|
||||
uint32_t len = regs[5];
|
||||
|
||||
while (len > 0) {
|
||||
hwaddr paddr = cpu_get_phys_page_debug(cs, vaddr);
|
||||
uint32_t page_left =
|
||||
TARGET_PAGE_SIZE - (vaddr & (TARGET_PAGE_SIZE - 1));
|
||||
uint32_t io_sz = page_left < len ? page_left : len;
|
||||
hwaddr sz = io_sz;
|
||||
void *buf = cpu_physical_memory_map(paddr, &sz, is_write);
|
||||
|
||||
if (buf) {
|
||||
vaddr += io_sz;
|
||||
len -= io_sz;
|
||||
regs[2] = is_write ?
|
||||
write(fd, buf, io_sz) :
|
||||
read(fd, buf, io_sz);
|
||||
regs[3] = errno_h2g(errno);
|
||||
cpu_physical_memory_unmap(buf, sz, is_write, sz);
|
||||
if (regs[2] == -1) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
regs[2] = -1;
|
||||
regs[3] = TARGET_EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TARGET_SYS_open:
|
||||
{
|
||||
char name[1024];
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(name); ++i) {
|
||||
rc = cpu_memory_rw_debug(cs, regs[3] + i,
|
||||
(uint8_t *)name + i, 1, 0);
|
||||
if (rc != 0 || name[i] == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc == 0 && i < ARRAY_SIZE(name)) {
|
||||
regs[2] = open(name, regs[4], regs[5]);
|
||||
regs[3] = errno_h2g(errno);
|
||||
} else {
|
||||
regs[2] = -1;
|
||||
regs[3] = TARGET_EINVAL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TARGET_SYS_close:
|
||||
if (regs[3] < 3) {
|
||||
regs[2] = regs[3] = 0;
|
||||
} else {
|
||||
regs[2] = close(regs[3]);
|
||||
regs[3] = errno_h2g(errno);
|
||||
}
|
||||
break;
|
||||
|
||||
case TARGET_SYS_lseek:
|
||||
regs[2] = lseek(regs[3], (off_t)(int32_t)regs[4], regs[5]);
|
||||
regs[3] = errno_h2g(errno);
|
||||
break;
|
||||
|
||||
case TARGET_SYS_select_one:
|
||||
{
|
||||
uint32_t fd = regs[3];
|
||||
uint32_t rq = regs[4];
|
||||
uint32_t target_tv = regs[5];
|
||||
uint32_t target_tvv[2];
|
||||
|
||||
struct timeval tv = {0};
|
||||
fd_set fdset;
|
||||
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(fd, &fdset);
|
||||
|
||||
if (target_tv) {
|
||||
cpu_memory_rw_debug(cs, target_tv,
|
||||
(uint8_t *)target_tvv, sizeof(target_tvv), 0);
|
||||
tv.tv_sec = (int32_t)tswap32(target_tvv[0]);
|
||||
tv.tv_usec = (int32_t)tswap32(target_tvv[1]);
|
||||
}
|
||||
regs[2] = select(fd + 1,
|
||||
rq == SELECT_ONE_READ ? &fdset : NULL,
|
||||
rq == SELECT_ONE_WRITE ? &fdset : NULL,
|
||||
rq == SELECT_ONE_EXCEPT ? &fdset : NULL,
|
||||
target_tv ? &tv : NULL);
|
||||
regs[3] = errno_h2g(errno);
|
||||
}
|
||||
break;
|
||||
|
||||
case TARGET_SYS_argc:
|
||||
regs[2] = 1;
|
||||
regs[3] = 0;
|
||||
break;
|
||||
|
||||
case TARGET_SYS_argv_sz:
|
||||
regs[2] = 128;
|
||||
regs[3] = 0;
|
||||
break;
|
||||
|
||||
case TARGET_SYS_argv:
|
||||
{
|
||||
struct Argv {
|
||||
uint32_t argptr[2];
|
||||
char text[120];
|
||||
} argv = {
|
||||
{0, 0},
|
||||
"test"
|
||||
};
|
||||
|
||||
argv.argptr[0] = tswap32(regs[3] + offsetof(struct Argv, text));
|
||||
cpu_memory_rw_debug(cs,
|
||||
regs[3], (uint8_t *)&argv, sizeof(argv), 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case TARGET_SYS_memset:
|
||||
{
|
||||
uint32_t base = regs[3];
|
||||
uint32_t sz = regs[5];
|
||||
|
||||
while (sz) {
|
||||
hwaddr len = sz;
|
||||
void *buf = cpu_physical_memory_map(base, &len, 1);
|
||||
|
||||
if (buf && len) {
|
||||
memset(buf, regs[4], len);
|
||||
cpu_physical_memory_unmap(buf, len, 1, len);
|
||||
} else {
|
||||
len = 1;
|
||||
}
|
||||
base += len;
|
||||
sz -= len;
|
||||
}
|
||||
regs[2] = regs[3];
|
||||
regs[3] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s(%d): not implemented\n", __func__, regs[2]);
|
||||
regs[2] = -1;
|
||||
regs[3] = TARGET_ENOSYS;
|
||||
break;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue