xtensa: add support for dc233c SoC for QEMU

This adds SoC and board configs to support the dc233c core
that is available on QEMU. This core has more features than
sample_controller, such as MMU support.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
Daniel Leung 2023-08-24 10:05:02 -07:00 committed by Anas Nashif
commit 169f505226
15 changed files with 1029 additions and 7 deletions

View file

@ -1,9 +1,14 @@
# XTENSA board configuration
# Copyright (c) 2017 Intel Corporation
# Copyright (c) 2017, 2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
config BOARD_QEMU_XTENSA
bool "Xtensa emulation using QEMU"
depends on SOC_XTENSA_SAMPLE_CONTROLLER
select QEMU_TARGET
config BOARD_QEMU_XTENSA_DC233C
bool "Xtensa emulation using QEMU (dc233c core)"
depends on SOC_XTENSA_DC233C
select QEMU_TARGET

View file

@ -1,4 +1,4 @@
# Copyright (c) 2017 Intel Corporation
# Copyright (c) 2017, 2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
if BOARD_QEMU_XTENSA
@ -13,3 +13,16 @@ config IPM_CONSOLE_STACK_SIZE
default 2048 if IPM_CONSOLE_RECEIVER
endif # BOARD_QEMU_XTENSA
if BOARD_QEMU_XTENSA_DC233C
config BUILD_OUTPUT_BIN
default n
config BOARD
default "qemu_xtensa_dc233c"
config IPM_CONSOLE_STACK_SIZE
default 2048 if IPM_CONSOLE_RECEIVER
endif # BOARD_QEMU_XTENSA

View file

@ -2,11 +2,19 @@
set(SUPPORTED_EMU_PLATFORMS qemu)
set(QEMU_CPU_TYPE_${ARCH} sample_controller)
if(CONFIG_BOARD_QEMU_XTENSA)
set(QEMU_CPU_TYPE_${ARCH} sample_controller)
set(QEMU_FLAGS_${ARCH}
-machine sim -semihosting -nographic -cpu sample_controller
set(QEMU_FLAGS_${ARCH}
-machine sim -semihosting -nographic -cpu sample_controller
)
elseif(CONFIG_BOARD_QEMU_XTENSA_DC233C)
set(QEMU_CPU_TYPE_${ARCH} dc233c)
set(QEMU_FLAGS_${ARCH}
-machine sim -semihosting -nographic -cpu dc233c
)
endif()
# TODO: Support debug
# board_set_debugger_ifnset(qemu)

View file

@ -0,0 +1,22 @@
/*
* Copyright (c) 2019, 2023 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
/dts-v1/;
#include "dc233c.dtsi"
/ {
model = "qemu_xtensa_dc233c";
compatible = "cdns,xtensa-dc233c";
chosen {
zephyr,sram = &sram0;
};
};
&cpu0 {
clock-frequency = <10000000>;
};

View file

@ -0,0 +1,11 @@
identifier: qemu_xtensa_dc233c
name: QEMU Emulation for Xtensa (dc233c core)
type: qemu
simulation: qemu
arch: xtensa
toolchain:
- xtools
testing:
ignore_tags:
- net
- bluetooth

View file

@ -0,0 +1,12 @@
# SPDX-License-Identifier: Apache-2.0
CONFIG_MAIN_STACK_SIZE=2048
CONFIG_BOARD_QEMU_XTENSA_DC233C=y
CONFIG_CONSOLE=y
CONFIG_SOC_XTENSA_DC233C=y
CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=10000000
CONFIG_STACK_SENTINEL=y
CONFIG_GEN_ISR_TABLES=y
CONFIG_GEN_IRQ_VECTOR_TABLE=n
CONFIG_SIMULATOR_XTENSA=y
CONFIG_QEMU_ICOUNT_SHIFT=6

48
dts/xtensa/dc233c.dtsi Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2023 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "skeleton.dtsi"
/ {
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
device_type = "cpu";
compatible = "cdns,tensilica-xtensa-lx3";
reg = <0>;
};
};
/*
* Although RAM is of size 128MB (0x08000000), limit this to 16MB so
* fewer L2 page table entries are needed when MMU is enabled.
*/
sram0: memory@00000000 {
device_type = "memory";
compatible = "mmio-sram";
reg = <0x00000000 0x01000000>;
};
/*
* Although ROM is of size 32MB (0x02000000), limit this to 8KB so
* fewer L2 page table entries are needed when MMU is enabled.
*/
rom0: memory@fe000000 {
device_type = "memory";
compatible = "mmio-sram";
reg = <0xfe000000 0x00002000>;
};
soc {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
ranges;
};
};

View file

@ -0,0 +1,3 @@
# SPDX-License-Identifier: Apache-2.0
zephyr_library_sources_ifdef(CONFIG_XTENSA_MMU mmu.c)

View file

@ -0,0 +1,31 @@
# Copyright (c) 2016 Open-RnD Sp. z o.o.
# Copyright (c) 2016 Cadence Design Systems, Inc.
# Copyright (c) 2023 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
if SOC_XTENSA_DC233C
config SOC
default "dc233c"
config SOC_TOOLCHAIN_NAME
string
default "dc233c"
config XTENSA_MMU_NUM_L2_TABLES
int
default 48 if XTENSA_MMU
# Both SRAM_OFFSET and KERNEL_VM_OFFSET are set at 1MB.
# This is to allow VECBASE to be mapped permanently
# via TLB way 4 (which covers 1MB).
config SRAM_OFFSET
hex
default 0x100000
config KERNEL_VM_OFFSET
hex
default 0x100000
endif

View file

@ -0,0 +1,11 @@
# Copyright (c) 2017, 2023 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
config SOC_XTENSA_DC233C
bool "Xtensa dc233c core"
select XTENSA
select XTENSA_HAL
select CPU_HAS_MMU
imply XTENSA_MMU
select ARCH_HAS_RESERVED_PAGE_FRAMES if XTENSA_MMU

View file

@ -0,0 +1,279 @@
/*
* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT.
*
* Functions here are designed to produce efficient code to
* search an Xtensa bitmask of interrupts, inspecting only those bits
* declared to be associated with a given interrupt level. Each
* dispatcher will handle exactly one flagged interrupt, in numerical
* order (low bits first) and will return a mask of that bit that can
* then be cleared by the calling code. Unrecognized bits for the
* level will invoke an error handler.
*/
#include <xtensa/config/core-isa.h>
#include <zephyr/sys/util.h>
#include <zephyr/sw_isr_table.h>
#if !defined(XCHAL_INT0_LEVEL) || XCHAL_INT0_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT1_LEVEL) || XCHAL_INT1_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT2_LEVEL) || XCHAL_INT2_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT3_LEVEL) || XCHAL_INT3_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT4_LEVEL) || XCHAL_INT4_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT5_LEVEL) || XCHAL_INT5_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT6_LEVEL) || XCHAL_INT6_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT7_LEVEL) || XCHAL_INT7_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT15_LEVEL) || XCHAL_INT15_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT16_LEVEL) || XCHAL_INT16_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT17_LEVEL) || XCHAL_INT17_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT18_LEVEL) || XCHAL_INT18_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT19_LEVEL) || XCHAL_INT19_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT20_LEVEL) || XCHAL_INT20_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT8_LEVEL) || XCHAL_INT8_LEVEL != 2
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT9_LEVEL) || XCHAL_INT9_LEVEL != 3
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT10_LEVEL) || XCHAL_INT10_LEVEL != 3
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT11_LEVEL) || XCHAL_INT11_LEVEL != 3
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT21_LEVEL) || XCHAL_INT21_LEVEL != 3
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT12_LEVEL) || XCHAL_INT12_LEVEL != 4
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT13_LEVEL) || XCHAL_INT13_LEVEL != 5
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT14_LEVEL) || XCHAL_INT14_LEVEL != 7
#error core-isa.h interrupt level does not match dispatcher!
#endif
static inline int _xtensa_handle_one_int1(unsigned int mask)
{
int irq;
if (mask & 0x7f) {
if (mask & 0x7) {
if (mask & BIT(0)) {
mask = BIT(0);
irq = 0;
goto handle_irq;
}
if (mask & BIT(1)) {
mask = BIT(1);
irq = 1;
goto handle_irq;
}
if (mask & BIT(2)) {
mask = BIT(2);
irq = 2;
goto handle_irq;
}
} else {
if (mask & 0x18) {
if (mask & BIT(3)) {
mask = BIT(3);
irq = 3;
goto handle_irq;
}
if (mask & BIT(4)) {
mask = BIT(4);
irq = 4;
goto handle_irq;
}
} else {
if (mask & BIT(5)) {
mask = BIT(5);
irq = 5;
goto handle_irq;
}
if (mask & BIT(6)) {
mask = BIT(6);
irq = 6;
goto handle_irq;
}
}
}
} else {
if (mask & 0x18080) {
if (mask & BIT(7)) {
mask = BIT(7);
irq = 7;
goto handle_irq;
}
if (mask & BIT(15)) {
mask = BIT(15);
irq = 15;
goto handle_irq;
}
if (mask & BIT(16)) {
mask = BIT(16);
irq = 16;
goto handle_irq;
}
} else {
if (mask & 0x60000) {
if (mask & BIT(17)) {
mask = BIT(17);
irq = 17;
goto handle_irq;
}
if (mask & BIT(18)) {
mask = BIT(18);
irq = 18;
goto handle_irq;
}
} else {
if (mask & BIT(19)) {
mask = BIT(19);
irq = 19;
goto handle_irq;
}
if (mask & BIT(20)) {
mask = BIT(20);
irq = 20;
goto handle_irq;
}
}
}
}
return 0;
handle_irq:
_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
return mask;
}
static inline int _xtensa_handle_one_int2(unsigned int mask)
{
int irq;
if (mask & BIT(8)) {
mask = BIT(8);
irq = 8;
goto handle_irq;
}
return 0;
handle_irq:
_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
return mask;
}
static inline int _xtensa_handle_one_int3(unsigned int mask)
{
int irq;
if (mask & 0x600) {
if (mask & BIT(9)) {
mask = BIT(9);
irq = 9;
goto handle_irq;
}
if (mask & BIT(10)) {
mask = BIT(10);
irq = 10;
goto handle_irq;
}
} else {
if (mask & BIT(11)) {
mask = BIT(11);
irq = 11;
goto handle_irq;
}
if (mask & BIT(21)) {
mask = BIT(21);
irq = 21;
goto handle_irq;
}
}
return 0;
handle_irq:
_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
return mask;
}
static inline int _xtensa_handle_one_int4(unsigned int mask)
{
int irq;
if (mask & BIT(12)) {
mask = BIT(12);
irq = 12;
goto handle_irq;
}
return 0;
handle_irq:
_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
return mask;
}
static inline int _xtensa_handle_one_int5(unsigned int mask)
{
int irq;
if (mask & BIT(13)) {
mask = BIT(13);
irq = 13;
goto handle_irq;
}
return 0;
handle_irq:
_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
return mask;
}
static inline int _xtensa_handle_one_int7(unsigned int mask)
{
int irq;
if (mask & BIT(14)) {
mask = BIT(14);
irq = 14;
goto handle_irq;
}
return 0;
handle_irq:
_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
return mask;
}
static inline int _xtensa_handle_one_int0(unsigned int mask)
{
return 0;
}
static inline int _xtensa_handle_one_int6(unsigned int mask)
{
return 0;
}

View file

@ -0,0 +1,501 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Xtensa platform.
*/
#include <xtensa/config/core-isa.h>
#include <zephyr/linker/sections.h>
#include <zephyr/devicetree.h>
#include <zephyr/linker/linker-defs.h>
#include <zephyr/linker/linker-tool.h>
#define RAMABLE_REGION RAM :sram0_phdr
#define ROMABLE_REGION rom0_seg :rom0_phdr
#ifdef CONFIG_MMU
#define MMU_PAGE_ALIGN . = ALIGN(CONFIG_MMU_PAGE_SIZE);
#define HDR_MMU_PAGE_ALIGN ALIGN(CONFIG_MMU_PAGE_SIZE)
#define HDR_4K_OR_MMU_PAGE_ALIGN ALIGN(CONFIG_MMU_PAGE_SIZE)
#define LAST_RAM_ALIGN MMU_PAGE_ALIGN
#else
#define MMU_PAGE_ALIGN . = ALIGN(4);
#define HDR_MMU_PAGE_ALIGN ALIGN(4)
#define HDR_4K_OR_MMU_PAGE_ALIGN ALIGN(4096)
#endif
#define PHYS_SRAM0_ADDR (DT_REG_ADDR(DT_NODELABEL(sram0)))
#define PHYS_SRAM0_SIZE (DT_REG_SIZE(DT_NODELABEL(sram0)))
#define PHYS_ROM0_ADDR (DT_REG_ADDR(DT_NODELABEL(rom0)))
#define PHYS_ROM0_SIZE (DT_REG_SIZE(DT_NODELABEL(rom0)))
/* Usable RAM is after the exception vectors and page-aligned. */
#define PHYS_RAM_ADDR (PHYS_SRAM0_ADDR + CONFIG_SRAM_OFFSET)
#define PHYS_RAM_SIZE (PHYS_SRAM0_SIZE - CONFIG_SRAM_OFFSET)
MEMORY
{
sram0_0_seg : org = 0x00002000, len = 0x178
sram0_1_seg : org = 0x00002178, len = 0x8
sram0_2_seg : org = 0x00002180, len = 0x38
sram0_3_seg : org = 0x000021B8, len = 0x8
sram0_4_seg : org = 0x000021C0, len = 0x38
sram0_5_seg : org = 0x000021F8, len = 0x8
sram0_6_seg : org = 0x00002200, len = 0x38
sram0_7_seg : org = 0x00002238, len = 0x8
sram0_8_seg : org = 0x00002240, len = 0x38
sram0_9_seg : org = 0x00002278, len = 0x8
sram0_10_seg : org = 0x00002280, len = 0x38
sram0_11_seg : org = 0x000022B8, len = 0x8
sram0_12_seg : org = 0x000022C0, len = 0x38
sram0_13_seg : org = 0x000022F8, len = 0x8
sram0_14_seg : org = 0x00002300, len = 0x38
sram0_15_seg : org = 0x00002338, len = 0x8
sram0_16_seg : org = 0x00002340, len = 0x38
sram0_17_seg : org = 0x00002378, len = 0x48
sram0_18_seg : org = 0x000023C0, len = 0x40
#ifdef CONFIG_XTENSA_MMU
vec_helpers : org = 0x00002400, len = (PHYS_RAM_ADDR - 0x00002400)
#endif
RAM : org = PHYS_RAM_ADDR, len = PHYS_RAM_SIZE
/* Although ROM is of size 0x02000000, we limit it to 8KB so
* fewer L2 page table entries are needed.
*/
rom0_seg : org = PHYS_ROM0_ADDR, len = PHYS_ROM0_SIZE
#ifdef CONFIG_GEN_ISR_TABLES
/* The space before exception vectors is not being used.
* So we stuff the temporary IDT_LIST there to avoid
* some linker issues which would balloon the size of
* the intermediate files (like zephyr_pre0.elf, to
* couple hundred MBs or even GBs).
*/
IDT_LIST : org = 0x00000000, len = 0x2000
#endif
}
PHDRS
{
sram0_0_phdr PT_LOAD;
sram0_1_phdr PT_LOAD;
sram0_2_phdr PT_LOAD;
sram0_3_phdr PT_LOAD;
sram0_4_phdr PT_LOAD;
sram0_5_phdr PT_LOAD;
sram0_6_phdr PT_LOAD;
sram0_7_phdr PT_LOAD;
sram0_8_phdr PT_LOAD;
sram0_9_phdr PT_LOAD;
sram0_10_phdr PT_LOAD;
sram0_11_phdr PT_LOAD;
sram0_12_phdr PT_LOAD;
sram0_13_phdr PT_LOAD;
sram0_14_phdr PT_LOAD;
sram0_15_phdr PT_LOAD;
sram0_16_phdr PT_LOAD;
sram0_17_phdr PT_LOAD;
sram0_18_phdr PT_LOAD;
#ifdef CONFIG_XTENSA_MMU
vec_helpers_phdr PT_LOAD;
#endif
rom0_phdr PT_LOAD;
sram0_phdr PT_LOAD;
sram0_bss_phdr PT_LOAD;
}
/* Default entry point: */
ENTRY(CONFIG_KERNEL_ENTRY)
_rom_store_table = 0;
PROVIDE(_memmap_vecbase_reset = 0x00002000);
PROVIDE(_memmap_reset_vector = 0xFE000000);
/* Various memory-map dependent cache attribute settings:
*
* Note that there is no cacheattr register which means thah
* cacheattr is emulated through TLB way 6 (8x 512MB regions).
* So the attributes here are the MMU memory attributes:
* 0x3 - rwx, bypass cache
* 0x7 - rwx, cache write back
* 0xB - wrx, cache write through
* Refer to the ISA manual for other attributes.
*/
_memmap_cacheattr_wb_base = 0x70000007;
_memmap_cacheattr_wt_base = 0xB000000B;
_memmap_cacheattr_bp_base = 0x30000003;
_memmap_cacheattr_unused_mask = 0x0FFFFFF0;
_memmap_cacheattr_wb_strict = 0x7FFFFFF7;
_memmap_cacheattr_wt_strict = 0xBFFFFFFB;
_memmap_cacheattr_bp_strict = 0x3FFFFFF3;
_memmap_cacheattr_wb_allvalid = 0x73333337;
_memmap_cacheattr_wt_allvalid = 0xB333333B;
_memmap_cacheattr_bp_allvalid = 0x33333333;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_allvalid);
SECTIONS
{
#include <zephyr/linker/rel-sections.ld>
#ifdef CONFIG_GEN_ISR_TABLES
#include <zephyr/linker/intlist.ld>
#endif
.WindowVectors.text : ALIGN(4)
{
_WindowVectors_text_start = ABSOLUTE(.);
KEEP (*(.WindowVectors.text))
_WindowVectors_text_end = ABSOLUTE(.);
} >sram0_0_seg :sram0_0_phdr
.Level2InterruptVector.literal : ALIGN(4)
{
_Level2InterruptVector_literal_start = ABSOLUTE(.);
*(.Level2InterruptVector.literal)
_Level2InterruptVector_literal_end = ABSOLUTE(.);
} >sram0_1_seg :sram0_1_phdr
.Level2InterruptVector.text : ALIGN(4)
{
_Level2InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level2InterruptVector.text))
_Level2InterruptVector_text_end = ABSOLUTE(.);
} >sram0_2_seg :sram0_2_phdr
.Level3InterruptVector.literal : ALIGN(4)
{
_Level3InterruptVector_literal_start = ABSOLUTE(.);
*(.Level3InterruptVector.literal)
_Level3InterruptVector_literal_end = ABSOLUTE(.);
} >sram0_3_seg :sram0_3_phdr
.Level3InterruptVector.text : ALIGN(4)
{
_Level3InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level3InterruptVector.text))
_Level3InterruptVector_text_end = ABSOLUTE(.);
} >sram0_4_seg :sram0_4_phdr
.Level4InterruptVector.literal : ALIGN(4)
{
_Level4InterruptVector_literal_start = ABSOLUTE(.);
*(.Level4InterruptVector.literal)
_Level4InterruptVector_literal_end = ABSOLUTE(.);
} >sram0_5_seg :sram0_5_phdr
.Level4InterruptVector.text : ALIGN(4)
{
_Level4InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level4InterruptVector.text))
_Level4InterruptVector_text_end = ABSOLUTE(.);
} >sram0_6_seg :sram0_6_phdr
.Level5InterruptVector.literal : ALIGN(4)
{
_Level5InterruptVector_literal_start = ABSOLUTE(.);
*(.Level5InterruptVector.literal)
_Level5InterruptVector_literal_end = ABSOLUTE(.);
} >sram0_7_seg :sram0_7_phdr
.Level5InterruptVector.text : ALIGN(4)
{
_Level5InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level5InterruptVector.text))
_Level5InterruptVector_text_end = ABSOLUTE(.);
} >sram0_8_seg :sram0_8_phdr
.DebugExceptionVector.literal : ALIGN(4)
{
_DebugExceptionVector_literal_start = ABSOLUTE(.);
*(.DebugExceptionVector.literal)
_DebugExceptionVector_literal_end = ABSOLUTE(.);
} >sram0_9_seg :sram0_9_phdr
.DebugExceptionVector.text : ALIGN(4)
{
_DebugExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DebugExceptionVector.text))
_DebugExceptionVector_text_end = ABSOLUTE(.);
} >sram0_10_seg :sram0_10_phdr
.NMIExceptionVector.literal : ALIGN(4)
{
_NMIExceptionVector_literal_start = ABSOLUTE(.);
*(.NMIExceptionVector.literal)
_NMIExceptionVector_literal_end = ABSOLUTE(.);
} >sram0_11_seg :sram0_11_phdr
.NMIExceptionVector.text : ALIGN(4)
{
_NMIExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.NMIExceptionVector.text))
_NMIExceptionVector_text_end = ABSOLUTE(.);
} >sram0_12_seg :sram0_12_phdr
.KernelExceptionVector.literal : ALIGN(4)
{
_KernelExceptionVector_literal_start = ABSOLUTE(.);
*(.KernelExceptionVector.literal)
_KernelExceptionVector_literal_end = ABSOLUTE(.);
} >sram0_13_seg :sram0_13_phdr
.KernelExceptionVector.text : ALIGN(4)
{
_KernelExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.KernelExceptionVector.text))
_KernelExceptionVector_text_end = ABSOLUTE(.);
} >sram0_14_seg :sram0_14_phdr
.UserExceptionVector.literal : ALIGN(4)
{
_UserExceptionVector_literal_start = ABSOLUTE(.);
*(.UserExceptionVector.literal)
_UserExceptionVector_literal_end = ABSOLUTE(.);
} >sram0_15_seg :sram0_15_phdr
.UserExceptionVector.text : ALIGN(4)
{
_UserExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.UserExceptionVector.text))
_UserExceptionVector_text_end = ABSOLUTE(.);
} >sram0_16_seg :sram0_16_phdr
.DoubleExceptionVector.literal : ALIGN(4)
{
_DoubleExceptionVector_literal_start = ABSOLUTE(.);
*(.DoubleExceptionVector.literal)
_DoubleExceptionVector_literal_end = ABSOLUTE(.);
} >sram0_17_seg :sram0_17_phdr
.DoubleExceptionVector.text : ALIGN(4)
{
_DoubleExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DoubleExceptionVector.text))
_DoubleExceptionVector_text_end = ABSOLUTE(.);
} >sram0_18_seg :sram0_18_phdr
#ifdef CONFIG_XTENSA_MMU
.vec_helpers :
{
/* There is quite some space between .DoubleExceptionVector
* and the beginning of .text. We can put exception handling
* code here to avoid TLB misses, thus speed up exception
* handling a little bit.
*
* Note: DO NOT PUT MMU init code here as this will be
* mapped in TLB manually. This manual entry will
* conflict with auto-refill TLB resulting in
* TLB multi-hit exception.
*/
*libarch__xtensa__core.a:xtensa-asm2-util.S.obj(.literal)
*libarch__xtensa__core.a:xtensa-asm2-util.S.obj(.text)
*libarch__xtensa__core.a:xtensa-asm2-util.S.obj(.iram.text)
*libarch__xtensa__core.a:xtensa-asm2-util.S.obj(.iram0.text)
*libarch__xtensa__core.a:window_vectors.S.obj(.iram.text)
*libarch__xtensa__core.a:xtensa-asm2.c.obj(.literal.*)
*libarch__xtensa__core.a:xtensa-asm2.c.obj(.text.*)
*libarch__xtensa__core.a:fatal.c.obj(.literal.*)
*libarch__xtensa__core.a:fatal.c.obj(.text.*)
*libarch__xtensa__core.a:crt1.S.obj(.literal)
*libarch__xtensa__core.a:crt1.S.obj(.text)
*libarch__xtensa__core.a:cpu_idle.c.obj(.literal.*)
*libarch__xtensa__core.a:cpu_idle.c.obj(.text.*)
*(.text.arch_is_in_isr)
*libkernel.a:fatal.c.obj(.literal.*)
*libkernel.a:fatal.c.obj(.text.*)
/* Below are to speed up execution by avoiding TLB misses
* on frequently used functions.
*/
*libkernel.a:sched.c.obj(.literal.*)
*libkernel.a:sched.c.obj(.text.*)
*libkernel.a:timeout.c.obj(.literal.*)
*libkernel.a:timeout.c.obj(.text.*)
*libdrivers__console.a:(.literal.*)
*libdrivers__console.a:(.text.*)
*libdrivers__timer.a:(.literal.*)
*libdrivers__timer.a:(.text.*)
} >vec_helpers :vec_helpers_phdr
#endif /* CONFIG_XTENSA_MMU */
.ResetVector.text : ALIGN(4)
{
__rom_region_start = ABSOLUTE(.);
_ResetVector_text_start = ABSOLUTE(.);
KEEP (*(.ResetVector.text))
_ResetVector_text_end = ABSOLUTE(.);
} >rom0_seg :rom0_phdr
.text : HDR_MMU_PAGE_ALIGN
{
_stext = .;
__text_region_start = .;
z_mapped_start = .;
_text_start = ABSOLUTE(.);
*(.entry.text)
*(.init.literal)
*(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text)
KEEP(*(.init))
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal)
KEEP(*(.fini))
*(.gnu.version)
#include <zephyr/linker/kobject-text.ld>
MMU_PAGE_ALIGN
_text_end = ABSOLUTE(.);
_etext = .;
} >RAM :sram0_phdr
__text_region_end = .;
.rodata : HDR_MMU_PAGE_ALIGN
{
__rodata_region_start = ABSOLUTE(.);
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
*(.rodata1)
. = ALIGN(4);
#include <snippets-rodata.ld>
#include <zephyr/linker/kobject-rom.ld>
. = ALIGN(4); /* this table MUST be 4-byte aligned */
_bss_table_start = ABSOLUTE(.);
LONG(_bss_start)
LONG(_bss_end)
_bss_table_end = ABSOLUTE(.);
MMU_PAGE_ALIGN
__rodata_region_end = ABSOLUTE(.);
} >RAM :sram0_phdr
#include <zephyr/linker/common-rom.ld>
#include <zephyr/linker/cplusplus-rom.ld>
#include <snippets-sections.ld>
.data : HDR_MMU_PAGE_ALIGN
{
_image_ram_start = ABSOLUTE(.);
__data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
KEEP(*(.gnu.linkonce.d.*personality*))
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
. = ALIGN(4);
#include <snippets-rwdata.ld>
. = ALIGN(4);
MMU_PAGE_ALIGN
__data_end = ABSOLUTE(.);
} >RAM :sram0_phdr
#include <snippets-data-sections.ld>
#include <zephyr/linker/common-ram.ld>
#include <zephyr/linker/cplusplus-ram.ld>
#include <snippets-ram-sections.ld>
.bss (NOLOAD) : HDR_MMU_PAGE_ALIGN
{
. = ALIGN (8);
_bss_start = ABSOLUTE(.);
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
*(.sram.bss)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
MMU_PAGE_ALIGN
} >RAM :sram0_bss_phdr
#include <zephyr/linker/common-noinit.ld>
/* Must be last in RAM */
#include <zephyr/linker/kobject-data.ld>
#include <zephyr/linker/ram-end.ld>
_heap_start = .;
PROVIDE(_heap_sentry = ORIGIN(RAM) + LENGTH(RAM));
PROVIDE(_heap_end = ORIGIN(RAM) + LENGTH(RAM));
PROVIDE(__stack = z_interrupt_stacks + CONFIG_ISR_STACK_SIZE);
#include <zephyr/linker/debug-sections.ld>
.xtensa.info 0 : { *(.xtensa.info) }
.xt.insn 0 :
{
KEEP (*(.xt.insn))
KEEP (*(.gnu.linkonce.x.*))
}
.xt.prop 0 :
{
KEEP (*(.xt.prop))
KEEP (*(.xt.prop.*))
KEEP (*(.gnu.linkonce.prop.*))
}
.xt.lit 0 :
{
KEEP (*(.xt.lit))
KEEP (*(.xt.lit.*))
KEEP (*(.gnu.linkonce.p.*))
}
.debug.xt.callgraph 0 :
{
KEEP (*(.debug.xt.callgraph .debug.xt.callgraph.* .gnu.linkonce.xt.callgraph.*))
}
}

View file

@ -0,0 +1,12 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Xtensa platform.
*/
#include <xtensa-dc233c.ld>

66
soc/xtensa/dc233c/mmu.c Normal file
View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2023 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <xtensa/config/core-isa.h>
#include <zephyr/devicetree.h>
#include <zephyr/arch/xtensa/xtensa_mmu.h>
#include <zephyr/sys/util.h>
#include "../../arch/xtensa/core/include/xtensa_mmu_priv.h"
const struct xtensa_mmu_range xtensa_soc_mmu_ranges[] = {
{
.start = (uint32_t)XCHAL_VECBASE_RESET_VADDR,
.end = (uint32_t)CONFIG_SRAM_OFFSET,
.attrs = Z_XTENSA_MMU_X | Z_XTENSA_MMU_CACHED_WB,
.name = "vecbase",
},
{
/* The ROM is 32MB but the address wraps around back to 0x00000000.
* So just skip the last page so we don't have to deal with integer
* overflow.
*/
.start = (uint32_t)DT_REG_ADDR(DT_NODELABEL(rom0)),
.end = (uint32_t)DT_REG_ADDR(DT_NODELABEL(rom0)) +
(uint32_t)DT_REG_SIZE(DT_NODELABEL(rom0)),
.attrs = Z_XTENSA_MMU_X | Z_XTENSA_MMU_CACHED_WB,
.name = "rom",
},
};
int xtensa_soc_mmu_ranges_num = ARRAY_SIZE(xtensa_soc_mmu_ranges);
void arch_xtensa_mmu_post_init(bool is_core0)
{
uint32_t vecbase;
ARG_UNUSED(is_core0);
__asm__ volatile("rsr.vecbase %0" : "=r"(vecbase));
/* Invalidate any autorefill instr TLBs of VECBASE so we can map it
* permanently below.
*/
xtensa_itlb_vaddr_invalidate((void *)vecbase);
/* Map VECBASE permanently in instr TLB way 4 so we will always have
* access to exception handlers. Each way 4 TLB covers 1MB (unless
* ITLBCFG has been changed before this, which should not have
* happened).
*
* Note that we don't want to map the first 1MB in data TLB as
* we want to keep page 0 (0x00000000) unmapped to catch null pointer
* de-references.
*/
vecbase = ROUND_DOWN(vecbase, MB(1));
xtensa_itlb_entry_write_sync(
Z_XTENSA_PTE(vecbase, Z_XTENSA_KERNEL_RING,
Z_XTENSA_MMU_X | Z_XTENSA_MMU_CACHED_WT),
Z_XTENSA_TLB_ENTRY((uint32_t)vecbase, 4));
}

View file

@ -3,8 +3,8 @@
config LOG_BACKEND_XTENSA_SIM
bool "Xtensa simulator backend"
depends on SOC_XTENSA_SAMPLE_CONTROLLER || SOC_FAMILY_INTEL_ADSP
default y if SOC_XTENSA_SAMPLE_CONTROLLER
depends on SOC_XTENSA_SAMPLE_CONTROLLER || SOC_XTENSA_DC233C || SOC_FAMILY_INTEL_ADSP
default y if SOC_XTENSA_SAMPLE_CONTROLLER || SOC_XTENSA_DC233C
select LOG_OUTPUT
help
Enable backend in xtensa simulator