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&microblaze 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:
Thomas Huth 2016-10-11 08:56:52 +02:00
parent 82ecffa8c0
commit fcf5ef2ab5
369 changed files with 78 additions and 80 deletions

View 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

View 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)

View 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 */

View 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)

View 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)

View 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 */

View 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
View 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)

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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);
}

View 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

File diff suppressed because it is too large Load diff

318
target/xtensa/xtensa-semi.c Normal file
View 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;
}
}