├── .clang-format ├── .git-blame-ignore-revs ├── .gitignore ├── .gitmodules ├── .pre-commit-config.yaml ├── CMakeLists.txt ├── LICENSE ├── address-translation.c ├── arch ├── arm │ ├── arch_callbacks.c │ ├── arch_callbacks.h │ ├── arch_exports.c │ ├── arch_exports.h │ ├── configuration_signals.c │ ├── configuration_signals.h │ ├── cpu.h │ ├── cpu_registers.c │ ├── cpu_registers.h │ ├── helper.c │ ├── helper.h │ ├── iwmmxt_helper.c │ ├── neon_helper.c │ ├── op_helper.c │ ├── pmu.c │ ├── pmu.h │ ├── system_registers.c │ ├── system_registers.h │ ├── translate.c │ ├── translate_lob.h │ └── translate_mve.h ├── arm64 │ ├── arch_callbacks.c │ ├── arch_callbacks.h │ ├── arch_exports.c │ ├── arch_exports.h │ ├── arm_ldst.h │ ├── cpu-param.h │ ├── cpu.h │ ├── cpu_h_epilogue.h │ ├── cpu_names.h │ ├── cpu_registers.c │ ├── cpu_registers.h │ ├── crc32.c │ ├── crypto_helper.c │ ├── decode-a32-uncond.c.inc │ ├── decode-a32.c.inc │ ├── decode-neon-dp.c.inc │ ├── decode-neon-ls.c.inc │ ├── decode-neon-shared.c.inc │ ├── decode-sme-fa64.c.inc │ ├── decode-sve.c.inc │ ├── decode-t16.c.inc │ ├── decode-t32.c.inc │ ├── decode-vfp-uncond.c.inc │ ├── decode-vfp.c.inc │ ├── helper-a64.c │ ├── helper-a64.h │ ├── helper-sve.h │ ├── helper.c │ ├── helper.h │ ├── helper_v7.c │ ├── iwmmxt_helper.c │ ├── mmu.c │ ├── mmu.h │ ├── mte_helper.c │ ├── neon_helper.c │ ├── op_helper.c │ ├── stubs.h │ ├── sve_helper.c │ ├── sve_ldst_internal.h │ ├── syndrome.h │ ├── system_registers.c │ ├── system_registers.h │ ├── translate-a32.h │ ├── translate-a64.c │ ├── translate-a64.h │ ├── translate-neon.c │ ├── translate-sve.c │ ├── translate-vfp.c │ ├── translate.c │ ├── translate.h │ ├── vec_helper.c │ ├── vec_internal.h │ └── vfp_helper.c ├── arm_common │ ├── arch_exports_common.c │ ├── arch_exports_common.h │ ├── cpu_common.h │ ├── helper_common.c │ ├── helper_common.h │ ├── op_addsub.h │ ├── system_registers_common.h │ ├── tightly_coupled_memory.c │ └── tightly_coupled_memory.h ├── i386 │ ├── arch_callbacks.c │ ├── arch_callbacks.h │ ├── arch_exports.c │ ├── arch_exports.h │ ├── cpu.h │ ├── cpu_registers.c │ ├── cpu_registers.h │ ├── cpuid.c │ ├── helper.c │ ├── helper.h │ ├── helper_template.h │ ├── op_helper.c │ ├── ops_sse.h │ ├── ops_sse_header.h │ ├── svm.h │ ├── translate.c │ └── x86.c ├── ppc │ ├── arch_callbacks.c │ ├── arch_callbacks.h │ ├── arch_exports.c │ ├── arch_exports.h │ ├── cpu.h │ ├── cpu_registers.c │ ├── cpu_registers.h │ ├── helper.c │ ├── helper.h │ ├── helper_regs.h │ ├── mfrom_table.inc │ ├── op_helper.c │ ├── translate.c │ └── translate_init.inc ├── riscv │ ├── arch_callbacks.c │ ├── arch_callbacks.h │ ├── arch_exports.c │ ├── arch_exports.h │ ├── cpu.h │ ├── cpu_bits.h │ ├── cpu_registers.c │ ├── cpu_registers.h │ ├── fpu_helper.c │ ├── fpu_vector_helper_template.h │ ├── helper.c │ ├── helper.h │ ├── instmap.h │ ├── op_helper.c │ ├── pmp.c │ ├── pmp.h │ ├── translate.c │ ├── vector_helper.c │ └── vector_helper_template.h ├── sparc │ ├── arch_callbacks.c │ ├── arch_callbacks.h │ ├── arch_exports.c │ ├── arch_exports.h │ ├── cpu.h │ ├── cpu_registers.c │ ├── cpu_registers.h │ ├── helper.c │ ├── helper.h │ ├── op_helper.c │ └── translate.c ├── translate-all.c └── xtensa │ ├── arch_callbacks.c │ ├── arch_callbacks.h │ ├── arch_exports.c │ ├── arch_exports.h │ ├── core-apollolake.c │ ├── core-apollolake │ ├── core-isa.h │ └── xtensa-modules.c.inc │ ├── core-baytrail.c │ ├── core-baytrail │ ├── core-isa.h │ └── xtensa-modules.c.inc │ ├── core-cannonlake.c │ ├── core-cannonlake │ ├── core-isa.h │ └── xtensa-modules.c.inc │ ├── core-dc233c.c │ ├── core-dc233c │ ├── core-isa.h │ └── xtensa-modules.c.inc │ ├── core-de212.c │ ├── core-de212 │ ├── core-isa.h │ └── xtensa-modules.c.inc │ ├── core-de233_fpu.c │ ├── core-de233_fpu │ ├── core-isa.h │ ├── core-matmap.h │ └── xtensa-modules.c.inc │ ├── core-dsp3400.c │ ├── core-dsp3400 │ ├── core-isa.h │ ├── core-matmap.h │ └── xtensa-modules.c.inc │ ├── core-esp32.c │ ├── core-esp32 │ ├── core-isa.h │ └── xtensa-modules.c.inc │ ├── core-esp32s2.c │ ├── core-esp32s2 │ └── core-isa.h │ ├── core-esp32s3.c │ ├── core-esp32s3 │ └── core-isa.h │ ├── core-haswell.c │ ├── core-haswell │ ├── core-isa.h │ └── xtensa-modules.c.inc │ ├── core-icelake.c │ ├── core-icelake │ ├── core-isa.h │ └── xtensa-modules.c.inc │ ├── core-imx8.c │ ├── core-imx8 │ ├── core-isa.h │ └── xtensa-modules.c.inc │ ├── core-imx8m.c │ ├── core-imx8m │ ├── core-isa.h │ └── xtensa-modules.c.inc │ ├── core-sample_controller.c │ ├── core-sample_controller │ ├── core-isa.h │ └── xtensa-modules.c.inc │ ├── core-test_kc705_be.c │ ├── core-test_kc705_be │ ├── core-isa.h │ └── xtensa-modules.c.inc │ ├── core-test_mmuhifi_c3.c │ ├── core-test_mmuhifi_c3 │ ├── core-isa.h │ └── xtensa-modules.c.inc │ ├── core-tigerlake.c │ ├── core-tigerlake │ ├── core-isa.h │ └── xtensa-modules.c.inc │ ├── cpu.c │ ├── cpu.h │ ├── cpu_registers.c │ ├── cpu_registers.h │ ├── dbg_helper.c │ ├── exc_helper.c │ ├── fpu_helper.c │ ├── helper.c │ ├── helper.h │ ├── mmu_helper.c │ ├── op_helper.c │ ├── overlay_tool.h │ ├── translate.c │ ├── win_helper.c │ ├── xtensa-isa-internal.h │ ├── xtensa-isa.c │ └── xtensa-isa.h ├── atomic-intrinsics.c ├── atomic.c ├── callbacks.c ├── cpu-exec.c ├── debug.c ├── exec.c ├── exports.c ├── helper.c ├── include ├── address-translation.h ├── atomic-intrinsics.h ├── atomic.h ├── bit_helper.h ├── callbacks.h ├── compiler.h ├── cpu-all.h ├── cpu-common.h ├── cpu-defs.h ├── debug.h ├── def-helper.h ├── disas_context_base.h ├── exec-all.h ├── exports.h ├── global_helper.h ├── infrastructure.h ├── int128.h ├── osdep.h ├── softmmu_defs.h ├── softmmu_exec.h ├── softmmu_header.h ├── softmmu_template.h ├── targphys.h ├── tb-helper.h ├── tlib-alloc.h ├── tlib-queue.h ├── ttable.h └── unwind.h ├── infrastructure.c ├── profile-helper.c ├── softfloat-2 ├── softfloat-2-macros.h ├── softfloat-2-specialize.h ├── softfloat-2.c └── softfloat-2.h ├── tcg ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README ├── aarch64 │ ├── tcg-target.c │ └── tcg-target.h ├── additional.c ├── additional.h ├── arm │ ├── tcg-target.c │ └── tcg-target.h ├── bswap.h ├── host-utils.c ├── host-utils.h ├── i386 │ ├── tcg-target.c │ └── tcg-target.h ├── optimize.c ├── tcg-additional.h ├── tcg-gvec-desc.h ├── tcg-memop.h ├── tcg-mo.h ├── tcg-op-atomic.h ├── tcg-op-gvec.c ├── tcg-op-gvec.h ├── tcg-op-vec.c ├── tcg-op.h ├── tcg-opc.h ├── tcg-runtime-gvec.c ├── tcg-runtime.c ├── tcg-runtime.h ├── tcg.c └── tcg.h └── tlib-alloc.c /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Uncrustify reformat 2 | 4b3832b6899877b3dde300e299dc4fe0e40a1d09 3 | # ClangFormat reformat 4 | 78bcb71570e72d24c641c444db00c2dab4cda85e 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | build/ 4 | .cache/ 5 | tags 6 | *.swp 7 | compile_commands.json 8 | CMakeCache.txt 9 | CMakeFiles/ 10 | *.so 11 | *.a 12 | Makefile 13 | .idea/ 14 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "softfloat-3"] 2 | path = softfloat-3 3 | url = https://github.com/antmicro/berkeley-softfloat-3.git 4 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/mirrors-clang-format 3 | rev: v19.1.0 4 | hooks: 5 | - id: clang-format 6 | types_or: [c] 7 | -------------------------------------------------------------------------------- /address-translation.c: -------------------------------------------------------------------------------- 1 | #include "cpu.h" 2 | 3 | uintptr_t REGPARM translate_page_aligned_address_and_fill_tlb(target_ulong addr, uint32_t mmu_idx, uint16_t dataSize, 4 | void *return_address) 5 | { 6 | int index; 7 | target_ulong tlb_addr; 8 | uintptr_t addend; 9 | 10 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 11 | 12 | redo: 13 | tlb_addr = cpu->tlb_table[mmu_idx][index].addr_read & ~TLB_ONE_SHOT; 14 | 15 | bool addresses_match = (addr & TARGET_PAGE_MASK) == (tlb_addr & TARGET_PAGE_MASK); 16 | bool is_invalid = tlb_addr & TLB_INVALID_MASK; 17 | if(likely(addresses_match && !is_invalid)) { 18 | if(unlikely((tlb_addr & TLB_MMIO) == TLB_MMIO)) { 19 | /* IO access */ 20 | tlib_printf(LOG_LEVEL_WARNING, "%s: Atomically accessing MMIO addr 0x%llx mmu_idx %d", __func__, addr, mmu_idx); 21 | return addr; 22 | } 23 | 24 | #if DEBUG 25 | if(unlikely(((addr & ~TARGET_PAGE_MASK) + dataSize - 1) >= TARGET_PAGE_SIZE)) { 26 | /* slow unaligned access (it spans two pages) */ 27 | tcg_abortf("%s: Spanning two pages not supported on addr 0x%llx mmu_idx %d", __func__, addr, mmu_idx); 28 | } 29 | #endif 30 | 31 | /* unaligned/aligned access in the same page */ 32 | addend = cpu->tlb_table[mmu_idx][index].addend; 33 | 34 | #if DEBUG 35 | // Safeguard the assumption that addend == 0 iff the access is MMIO. 36 | tlib_assert(addend != 0); 37 | #endif 38 | 39 | return addr + addend; 40 | } else { 41 | /* the page is not in the TLB : fill it */ 42 | if(!tlb_fill(cpu, addr, PAGE_READ, mmu_idx, return_address, 0, dataSize)) { 43 | goto redo; 44 | } 45 | } 46 | tlib_printf(LOG_LEVEL_DEBUG, "%s: Failed to fill TLB", __func__); 47 | return (uintptr_t)NULL; 48 | } 49 | 50 | uintptr_t translate_page_aligned_address_and_fill_tlb_u32(target_ulong addr, uint32_t mmu_idx, void *return_address) 51 | { 52 | return translate_page_aligned_address_and_fill_tlb(addr, mmu_idx, sizeof(uint32_t), return_address); 53 | } 54 | 55 | uintptr_t translate_page_aligned_address_and_fill_tlb_u64(target_ulong addr, uint32_t mmu_idx, void *return_address) 56 | { 57 | return translate_page_aligned_address_and_fill_tlb(addr, mmu_idx, sizeof(uint64_t), return_address); 58 | } 59 | 60 | uintptr_t translate_page_aligned_address_and_fill_tlb_u128(target_ulong addr, uint32_t mmu_idx, void *return_address) 61 | { 62 | return translate_page_aligned_address_and_fill_tlb(addr, mmu_idx, 2 * sizeof(uint64_t), return_address); 63 | } 64 | -------------------------------------------------------------------------------- /arch/arm/arch_callbacks.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ARM callbacks. 3 | * 4 | * Copyright (c) Antmicro 5 | * Copyright (c) Realtime Embedded 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, see . 19 | */ 20 | #include "callbacks.h" 21 | #include "arch_callbacks.h" 22 | 23 | #ifdef TARGET_PROTO_ARM_M 24 | int32_t tlib_nvic_acknowledge_irq(void) __attribute__((weak)); 25 | 26 | int32_t tlib_nvic_acknowledge_irq(void) 27 | { 28 | return -1; 29 | } 30 | 31 | DEFAULT_VOID_HANDLER1(void tlib_nvic_complete_irq, int32_t number) 32 | 33 | DEFAULT_VOID_HANDLER2(void tlib_nvic_write_basepri, int32_t number, uint32_t secure) 34 | 35 | DEFAULT_INT_HANDLER1(int32_t tlib_nvic_find_pending_irq, void) 36 | 37 | DEFAULT_INT_HANDLER1(int32_t tlib_nvic_get_pending_masked_irq, void) 38 | 39 | DEFAULT_VOID_HANDLER1(void tlib_nvic_set_pending_irq, int32_t number) 40 | 41 | DEFAULT_INT_HANDLER1(uint32_t tlib_has_enabled_trustzone, void) 42 | 43 | DEFAULT_INT_HANDLER1(uint32_t tlib_nvic_interrupt_targets_secure, int32_t number) 44 | 45 | #endif 46 | 47 | DEFAULT_INT_HANDLER1(uint32_t tlib_read_cp15_32, uint32_t instruction) 48 | 49 | DEFAULT_VOID_HANDLER2(void tlib_write_cp15_32, uint32_t instruction, uint32_t value) 50 | 51 | DEFAULT_INT_HANDLER1(uint64_t tlib_read_cp15_64, uint32_t instruction) 52 | 53 | DEFAULT_VOID_HANDLER2(void tlib_write_cp15_64, uint32_t instruction, uint64_t value) 54 | 55 | DEFAULT_INT_HANDLER1(uint32_t tlib_is_wfi_as_nop, void) 56 | 57 | DEFAULT_INT_HANDLER1(uint32_t tlib_is_wfe_and_sev_as_nop, void) 58 | 59 | DEFAULT_INT_HANDLER1(uint32_t tlib_do_semihosting, void) 60 | 61 | DEFAULT_VOID_HANDLER1(void tlib_set_system_event, int32_t value) 62 | 63 | DEFAULT_VOID_HANDLER1(void tlib_report_pmu_overflow, int32_t value) 64 | 65 | #include "configuration_signals.h" 66 | DEFAULT_VOID_HANDLER1(void tlib_fill_configuration_signals_state, void *state_pointer) 67 | -------------------------------------------------------------------------------- /arch/arm/arch_callbacks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifdef TARGET_PROTO_ARM_M 6 | int32_t tlib_nvic_acknowledge_irq(void); 7 | void tlib_nvic_complete_irq(int32_t number); 8 | void tlib_nvic_write_basepri(int32_t number, uint32_t secure); 9 | int32_t tlib_nvic_find_pending_irq(void); 10 | int32_t tlib_nvic_get_pending_masked_irq(void); 11 | void tlib_nvic_set_pending_irq(int32_t no); 12 | uint32_t tlib_has_enabled_trustzone(void); 13 | uint32_t tlib_nvic_interrupt_targets_secure(int32_t no); 14 | int32_t tlib_custom_idau_handler(void *external_idau_request, void *attribution, void *region); 15 | 16 | typedef struct { 17 | uint32_t address; 18 | int32_t secure; 19 | int32_t access_type; 20 | int32_t access_width; 21 | } ExternalIDAURequest; 22 | #endif 23 | 24 | uint32_t tlib_read_cp15_32(uint32_t instruction); 25 | void tlib_write_cp15_32(uint32_t instruction, uint32_t value); 26 | uint64_t tlib_read_cp15_64(uint32_t instruction); 27 | void tlib_write_cp15_64(uint32_t instruction, uint64_t value); 28 | uint32_t tlib_is_wfi_as_nop(void); 29 | uint32_t tlib_is_wfe_and_sev_as_nop(void); 30 | uint32_t tlib_do_semihosting(void); 31 | void tlib_set_system_event(int32_t value); 32 | void tlib_report_pmu_overflow(int32_t counter); 33 | 34 | #include "configuration_signals.h" 35 | void tlib_fill_configuration_signals_state(void *state_pointer); 36 | -------------------------------------------------------------------------------- /arch/arm/arch_exports.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "arch_exports_common.h" 5 | 6 | uint32_t tlib_get_cpu_model_id(void); 7 | uint32_t tlib_get_it_state(void); 8 | uint32_t tlib_evaluate_condition_code(uint32_t); 9 | 10 | void tlib_set_cpu_model_id(uint32_t value); 11 | void tlib_toggle_fpu(int32_t enabled); 12 | void tlib_set_sev_on_pending(int32_t); 13 | void tlib_set_event_flag(int value); 14 | void tlib_set_number_of_mpu_regions(uint32_t value); 15 | uint32_t tlib_get_number_of_mpu_regions(); 16 | void tlib_register_tcm_region(uint32_t address, uint64_t size, uint64_t index); 17 | 18 | void tlib_update_pmu_counters(int event_id, uint32_t amount); 19 | void tlib_pmu_set_debug(uint32_t debug); 20 | 21 | uint32_t tlib_get_exception_vector_address(void); 22 | void tlib_set_exception_vector_address(uint32_t address); 23 | 24 | #ifdef TARGET_PROTO_ARM_M 25 | void tlib_set_sleep_on_exception_exit(int32_t); 26 | 27 | void tlib_set_interrupt_vector_base(uint32_t address, bool secure); 28 | uint32_t tlib_get_interrupt_vector_base(bool secure); 29 | void tlib_set_fpu_interrupt_number(int32_t enabled); 30 | 31 | uint32_t tlib_get_primask(bool secure); 32 | uint32_t tlib_get_faultmask(bool secure); 33 | 34 | uint32_t tlib_get_xpsr(void); 35 | uint32_t tlib_get_fault_status(bool secure); 36 | void tlib_set_fault_status(uint32_t value, bool secure); 37 | uint32_t tlib_get_memory_fault_address(bool secure); 38 | uint32_t tlib_get_secure_fault_status(); 39 | void tlib_set_secure_fault_status(uint32_t value); 40 | uint32_t tlib_get_secure_fault_address(void); 41 | void tlib_enable_mpu(int32_t enabled); 42 | void tlib_set_mpu_region_base_address(uint32_t value); 43 | void tlib_set_mpu_region_size_and_enable(uint32_t value); 44 | void tlib_set_mpu_region_access_control(uint32_t value); 45 | void tlib_set_mpu_region_number(uint32_t value); 46 | uint32_t tlib_is_mpu_enabled(); 47 | uint32_t tlib_get_mpu_region_base_address(); 48 | uint32_t tlib_get_mpu_region_size_and_enable(); 49 | uint32_t tlib_get_mpu_region_access_control(); 50 | uint32_t tlib_get_mpu_region_number(); 51 | 52 | uint32_t tlib_is_v8(); 53 | 54 | void tlib_set_pmsav8_ctrl(uint32_t value, bool secure); 55 | void tlib_set_pmsav8_rnr(uint32_t value, bool secure); 56 | void tlib_set_pmsav8_rbar(uint32_t value, uint32_t region_offset, bool secure); 57 | void tlib_set_pmsav8_rlar(uint32_t value, uint32_t region_offset, bool secure); 58 | void tlib_set_pmsav8_mair(uint32_t index, uint32_t value, bool secure); 59 | uint32_t tlib_get_pmsav8_type(bool secure); 60 | uint32_t tlib_get_pmsav8_ctrl(bool secure); 61 | uint32_t tlib_get_pmsav8_rnr(bool secure); 62 | uint32_t tlib_get_pmsav8_rbar(uint32_t region_offset, bool secure); 63 | uint32_t tlib_get_pmsav8_rlar(uint32_t region_offset, bool secure); 64 | uint32_t tlib_get_pmsav8_mair(uint32_t index, bool secure); 65 | 66 | void tlib_set_idau_enabled(bool value); 67 | void tlib_set_custom_idau_handler_enabled(bool value); 68 | void tlib_set_number_of_idau_regions(uint32_t value); 69 | void tlib_set_idau_region_base_address_register(uint32_t index, uint32_t value); 70 | void tlib_set_idau_region_limit_address_register(uint32_t index, uint32_t value); 71 | uint32_t tlib_get_idau_enabled(); 72 | uint32_t tlib_get_number_of_idau_regions(); 73 | uint32_t tlib_get_idau_region_base_address_register(uint32_t index); 74 | uint32_t tlib_get_idau_region_limit_address_register(uint32_t index); 75 | #endif 76 | -------------------------------------------------------------------------------- /arch/arm/configuration_signals.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Antmicro 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | 9 | #include "arch_callbacks.h" 10 | #include "configuration_signals.h" 11 | #include "cpu.h" 12 | #include "tightly_coupled_memory.h" 13 | 14 | static inline void handle_configuration_signal(CPUState *env, ConfigurationSignals signal_id, ConfigurationSignalsState state) 15 | { 16 | uint32_t new_value, old_value; 17 | switch(signal_id) { 18 | case IN_DEBUG_ROM_ADDRESS: 19 | old_value = env->cp14.c1_dbgdrar; 20 | new_value = FIELD_DP32(old_value, DBGDRAR, ROMADDR, state.debug_rom_address); 21 | new_value = FIELD_DP32(new_value, DBGDRAR, Valid, DEBUG_ADDRESS_VALID_VALUE); 22 | env->cp14.c1_dbgdrar = new_value; 23 | break; 24 | case IN_DEBUG_SELF_ADDRESS: { 25 | // The signal sets top 15 bits. 26 | uint32_t address_expanded_to_20bits = state.debug_self_address << 5; 27 | 28 | old_value = env->cp14.c2_dbgdsar; 29 | new_value = FIELD_DP32(old_value, DBGDSAR, SELFOFFSET, address_expanded_to_20bits); 30 | new_value = FIELD_DP32(new_value, DBGDSAR, Valid, DEBUG_ADDRESS_VALID_VALUE); 31 | env->cp14.c2_dbgdsar = new_value; 32 | break; 33 | } 34 | case IN_INITIALIZE_INSTRUCTION_TCM: { 35 | // Cortex-R8 doesn't have any TCM selection register. 36 | int tcm_region = 0; 37 | int tcm_op2 = TCM_CP15_OP2_INSTRUCTION_OR_UNIFIED; 38 | 39 | uint32_t base_address = state.high_exception_vectors ? 0xFFFF0 : 0x0; 40 | // TRM says the ITCM size is *maximum* 64KB if INITRAM and VINITHI are set. 41 | // There's no default value but 0 seems invalid. Let's use 64KB. 42 | uint32_t size = TCM_SIZE_64KB; 43 | 44 | old_value = env->cp15.c9_tcmregion[tcm_op2][tcm_region]; 45 | new_value = FIELD_DP32(old_value, ITCMRR, ENABLE_BIT, 1); 46 | new_value = FIELD_DP32(new_value, ITCMRR, SIZE, size); 47 | new_value = FIELD_DP32(new_value, ITCMRR, BASE_ADDRESS, base_address); 48 | env->cp15.c9_tcmregion[tcm_op2][tcm_region] = new_value; 49 | break; 50 | } 51 | case IN_HIGH_EXCEPTION_VECTORS: 52 | env->cp15.c1_sys = FIELD_DP32(env->cp15.c1_sys, SCTLR, V, state.high_exception_vectors); 53 | break; 54 | case IN_PERIPHERALS_BASE: 55 | env->cp15.c15_cbar = state.peripherals_base << 13; 56 | break; 57 | case IN_AHB_REGION_REGISTER: 58 | env->cp15.c15_ahb_region = state.ahb_region_register; 59 | break; 60 | case IN_AXI_REGION_REGISTER: 61 | env->cp15.c15_axi_region = state.axi_region_register; 62 | break; 63 | case IN_VIRTUAL_AXI_REGION_REGISTER: 64 | env->cp15.c15_virtual_axi_region = state.virtual_axi_region_register; 65 | break; 66 | default: 67 | tlib_abortf("Unknown configuration signal: %d", signal_id); 68 | } 69 | } 70 | 71 | static inline ConfigurationSignalsState get_state(void) 72 | { 73 | ConfigurationSignalsState state = { 0 }; 74 | tlib_fill_configuration_signals_state(&state); 75 | return state; 76 | } 77 | 78 | void configuration_signals_apply(CPUState *env) 79 | { 80 | ConfigurationSignalsState state = get_state(); 81 | 82 | uint32_t signal_id; 83 | for(signal_id = 0; signal_id < CONFIGURATION_SIGNALS_COUNT; signal_id++) { 84 | if(state.included_signals_mask & (UINT64_C(1) << signal_id)) { 85 | handle_configuration_signal(env, signal_id, state); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /arch/arm/configuration_signals.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | // That's currently because of using 'uint64_t included_signals_mask' in ConfigurationSignalsState. 7 | #define CONFIGURATION_SIGNALS_MAX 64 8 | 9 | // Remember to update CONFIGURATION_SIGNALS_COUNT when modifying the enum. Don't assign any values. 10 | #define CONFIGURATION_SIGNALS_COUNT 8 11 | typedef enum { 12 | IN_DEBUG_ROM_ADDRESS, // DBGROMADDR 13 | IN_DEBUG_SELF_ADDRESS, // DBGSELFADDR 14 | IN_HIGH_EXCEPTION_VECTORS, // VINITHI 15 | IN_INITIALIZE_INSTRUCTION_TCM, // INITRAM 16 | IN_PERIPHERALS_BASE, // PERIPHBASE 17 | 18 | IN_AHB_REGION_REGISTER, // Based on PPHBASE, INITPPH and PPHSIZE 19 | IN_AXI_REGION_REGISTER, // Based on PPXBASE, INITPPX and PPXSIZE 20 | IN_VIRTUAL_AXI_REGION_REGISTER, // Based on PPVBASE, PPVSIZE 21 | } ConfigurationSignals; 22 | 23 | #if CONFIGURATION_SIGNALS_COUNT > CONFIGURATION_SIGNALS_MAX 24 | #error Number of configuration signals is too large. 25 | #endif 26 | 27 | typedef struct CPUState CPUState; 28 | void configuration_signals_apply(CPUState *env); 29 | 30 | // Will be gathered through a callback. 31 | typedef struct { 32 | // Each bit says whether to apply the signal's effect. 33 | // Bit positions are based on the ConfigurationSignals enum. 34 | uint64_t included_signals_mask; 35 | 36 | uint32_t debug_rom_address; 37 | uint32_t debug_self_address; 38 | uint32_t high_exception_vectors; 39 | uint32_t initialize_instruction_tcm; 40 | uint32_t peripherals_base; 41 | 42 | uint32_t ahb_region_register; 43 | uint32_t axi_region_register; 44 | uint32_t virtual_axi_region_register; 45 | } ConfigurationSignalsState; 46 | -------------------------------------------------------------------------------- /arch/arm/cpu_registers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cpu-defs.h" 4 | 5 | // this is a trick to make the registers parser simpler 6 | #if defined(TARGET_ARM32) && defined(TARGET_PROTO_ARM_M) 7 | #define TARGET_PROTO_ARM32_M 8 | #endif 9 | 10 | typedef enum { 11 | #ifdef TARGET_ARM32 12 | R_0_32 = 0, 13 | R_1_32 = 1, 14 | R_2_32 = 2, 15 | R_3_32 = 3, 16 | R_4_32 = 4, 17 | R_5_32 = 5, 18 | R_6_32 = 6, 19 | R_7_32 = 7, 20 | R_8_32 = 8, 21 | R_9_32 = 9, 22 | R_10_32 = 10, 23 | R_11_32 = 11, 24 | R_12_32 = 12, 25 | R_13_32 = 13, 26 | SP_32 = 13, 27 | R_14_32 = 14, 28 | LR_32 = 14, 29 | R_15_32 = 15, 30 | PC_32 = 15, 31 | CPSR_32 = 25, 32 | #endif 33 | #ifdef TARGET_PROTO_ARM32_M 34 | Control_32 = 18, 35 | BasePri_32 = 19, 36 | VecBase_32 = 20, 37 | CurrentSP_32 = 21, 38 | OtherSP_32 = 22, 39 | FPCCR_32 = 23, 40 | FPCAR_32 = 24, 41 | FPDSCR_32 = 26, 42 | CPACR_32 = 27, 43 | PRIMASK_32 = 28, 44 | FAULTMASK_32 = 30, 45 | #endif 46 | #ifdef TARGET_ARM64 47 | R_0_32 = 0, 48 | R_1_32 = 1, 49 | R_2_32 = 2, 50 | R_3_32 = 3, 51 | R_4_32 = 4, 52 | R_5_32 = 5, 53 | R_6_32 = 6, 54 | R_7_32 = 7, 55 | R_8_32 = 8, 56 | R_9_32 = 9, 57 | R_10_32 = 10, 58 | R_11_32 = 11, 59 | R_12_32 = 12, 60 | R_13_32 = 13, 61 | SP_32 = 13, 62 | R_14_32 = 14, 63 | LR_32 = 14, 64 | R_15_32 = 15, 65 | PC_32 = 15, 66 | CPSR_32 = 25, 67 | PC_64 = 28, 68 | X_0_64 = 32, 69 | X_1_64 = 33, 70 | X_2_64 = 34, 71 | X_3_64 = 35, 72 | X_4_64 = 36, 73 | X_5_64 = 37, 74 | X_6_64 = 38, 75 | X_7_64 = 39, 76 | X_8_64 = 40, 77 | X_9_64 = 41, 78 | X_10_64 = 42, 79 | X_11_64 = 43, 80 | X_12_64 = 44, 81 | X_13_64 = 45, 82 | X_14_64 = 46, 83 | X_15_64 = 47, 84 | X_16_64 = 48, 85 | X_17_64 = 49, 86 | X_18_64 = 50, 87 | X_19_64 = 51, 88 | X_20_64 = 52, 89 | X_21_64 = 53, 90 | X_22_64 = 54, 91 | X_23_64 = 55, 92 | X_24_64 = 56, 93 | X_25_64 = 57, 94 | X_26_64 = 58, 95 | X_27_64 = 59, 96 | X_28_64 = 60, 97 | X_29_64 = 61, 98 | X_30_64 = 62, 99 | X_31_64 = 63 100 | #endif 101 | } Registers; 102 | 103 | /* The return address is stored here */ 104 | #if TARGET_LONG_BITS == 64 105 | #define RA X_30_64 106 | #endif 107 | #if TARGET_LONG_BITS == 32 108 | #define RA R_14_32 109 | #endif 110 | -------------------------------------------------------------------------------- /arch/arm/pmu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Antmicro 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | struct CPUState; 13 | enum arm_cpu_mode; 14 | 15 | // PMU (Performance Monitoring Unit) 16 | 17 | #define PMU_MAX_PROGRAMMABLE_COUNTERS 31 18 | #define PMU_EVENTS_NUMBER 3 19 | 20 | // Supported event types 21 | #define PMU_EVENT_SOFTWARE_INCREMENT 0x00 22 | #define PMU_EVENT_INSTRUCTIONS_EXECUTED 0x08 23 | #define PMU_EVENT_CYCLES 0x11 24 | 25 | #define PMU_CYCLE_COUNTER_ID 31 26 | 27 | #define PMCR_E (1 << 0) 28 | #define PMCR_P (1 << 1) 29 | #define PMCR_C (1 << 2) 30 | #define PMCR_D (1 << 3) 31 | #define PMCR_X (1 << 4) 32 | #define PMCR_DP (1 << 5) 33 | 34 | #define PMCR_IMPL (0xFF << 24) 35 | #define PMCR_NO_COUNTERS_OFFSET 11 36 | #define PMCR_NO_COUNTERS_MASK 0x1F 37 | 38 | #define PMUSERENR_EN (1 << 0) 39 | 40 | #define PMXEVTYPER_EVT 0xFF 41 | #define PMXEVTYPER_P (1 << 31) 42 | #define PMXEVTYPER_U (1 << 30) 43 | 44 | // Implemented PMU events 45 | typedef struct pmu_event { 46 | char *name; 47 | uint32_t identifier; 48 | } pmu_event; 49 | 50 | typedef struct pmu_counter { 51 | // Counter id, which should be the same as its position in pmu.counters array 52 | int id; 53 | bool enabled; 54 | bool enabled_overflow_interrupt; 55 | // ID of measured event (`pm_event`) 56 | int measured_event_id; 57 | 58 | /* These are PMUv2 specific. Note, that setting to 0/false means that they will count. */ 59 | bool ignore_count_at_pl0; 60 | bool ignore_count_at_pl1; 61 | // Analogously would be counts in Secure/Non-Secure mode, which we don't support at this moment 62 | 63 | // === These fields should not be directly modified === 64 | // Instead `helper_pmu_update_event_counters` (recommended) or `pmu_update_counter` should be called 65 | uint32_t val; 66 | // Counter value is not always updated per-tick - we need to explicitly calculate it's value somehow 67 | // Currently only for cycles and instructions, this could be extended to be more generic in the future 68 | uint64_t snapshot; // Snapshot taken of external event source - used to compute return val lazily 69 | // Note that snapshots can only be taken when the counter is capable of counting events (both PMU and the counter are 70 | // enabled) If the counter changes state in any way (is disabled or changes event) the value MUST be calculated and snapshot 71 | // reset 72 | bool has_snapshot; 73 | 74 | bool overflowed; 75 | } pmu_counter; 76 | 77 | // Is the counter a `Cycle` or `Executed instructions` counter 78 | static inline bool pmu_is_insns_or_cycles_counter(const pmu_counter *const counter) 79 | { 80 | return counter->measured_event_id == PMU_EVENT_INSTRUCTIONS_EXECUTED || counter->measured_event_id == PMU_EVENT_CYCLES; 81 | } 82 | 83 | void pmu_recalculate_cycles_instruction_limit_custom_mode(enum arm_cpu_mode mode); 84 | void pmu_recalculate_cycles_instruction_limit(); 85 | void pmu_update_cycles_instruction_limit(const pmu_counter *const cnt); 86 | uint32_t pmu_get_insn_cycle_value(const pmu_counter *const counter); 87 | void pmu_init_reset(struct CPUState *env); 88 | void pmu_switch_mode_user(enum arm_cpu_mode new_mode); 89 | 90 | void set_c9_pmcntenset(struct CPUState *env, uint64_t val); 91 | void set_c9_pmcntenclr(struct CPUState *env, uint64_t val); 92 | void set_c9_pmcr(struct CPUState *env, uint64_t val); 93 | void set_c9_pmovsr(struct CPUState *env, uint64_t val); 94 | void set_c9_pmuserenr(struct CPUState *env, uint64_t val); 95 | void set_c9_pmintenset(struct CPUState *env, uint64_t val); 96 | void set_c9_pmintenclr(struct CPUState *env, uint64_t val); 97 | uint64_t get_c9_pmccntr(struct CPUState *env); 98 | void set_c9_pmselr(struct CPUState *env, uint64_t val); 99 | void set_c9_pmxevtyper(struct CPUState *env, uint64_t val); 100 | uint32_t get_c9_pmxevcntr(struct CPUState *env); 101 | void set_c9_pmxevcntr(struct CPUState *env, uint64_t val); 102 | void set_c9_pmswinc(struct CPUState *env, uint64_t val); 103 | 104 | void helper_pmu_count_instructions_cycles(uint32_t icount); 105 | 106 | void pmu_update_counter(struct CPUState *env, pmu_counter *const counter, uint64_t amount); 107 | void helper_pmu_update_event_counters(struct CPUState *env, int event_id, uint32_t amount); 108 | 109 | void pmu_recalculate_all_lazy(void); 110 | void pmu_take_all_snapshots(void); 111 | -------------------------------------------------------------------------------- /arch/arm/system_registers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Antmicro 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "system_registers_common.h" 10 | 11 | /* To enable banking of coprocessor registers depending on ns-bit we 12 | * add a bit to distinguish between secure and non-secure cpregs in the 13 | * hashtable. 14 | */ 15 | #define CP_REG_NS_SHIFT 29 16 | #define CP_REG_NS_MASK (1 << CP_REG_NS_SHIFT) 17 | 18 | #define ENCODE_CP_REG(cp, is64, ns, crn, crm, opc1, opc2) \ 19 | ((ns) << CP_REG_NS_SHIFT | ((cp) << 16) | ((is64) << 15) | ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2)) 20 | 21 | // Cover the entire register width, when used on an instruction address field (crm, opc1, opc2) 22 | #define ANY 0xFF 23 | -------------------------------------------------------------------------------- /arch/arm64/arch_callbacks.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Antmicro 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include "callbacks.h" 8 | #include "arch_callbacks.h" 9 | 10 | DEFAULT_INT_HANDLER1(uint64_t tlib_read_system_register_generic_timer_64, uint32_t offset) 11 | DEFAULT_VOID_HANDLER2(void tlib_write_system_register_generic_timer_64, uint32_t offset, uint64_t value) 12 | 13 | DEFAULT_INT_HANDLER1(uint32_t tlib_read_system_register_generic_timer_32, uint32_t offset) 14 | DEFAULT_VOID_HANDLER2(void tlib_write_system_register_generic_timer_32, uint32_t offset, uint32_t value) 15 | 16 | DEFAULT_INT_HANDLER1(uint64_t tlib_read_system_register_interrupt_cpu_interface, uint32_t offset) 17 | DEFAULT_VOID_HANDLER2(void tlib_write_system_register_interrupt_cpu_interface, uint32_t offset, uint64_t value) 18 | 19 | DEFAULT_VOID_HANDLER2(void tlib_on_execution_mode_changed, uint32_t el, uint32_t is_secure) 20 | 21 | DEFAULT_VOID_HANDLER0(void tlib_handle_psci_call) 22 | -------------------------------------------------------------------------------- /arch/arm64/arch_callbacks.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Antmicro 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | uint64_t tlib_read_system_register_interrupt_cpu_interface(uint32_t offset); 12 | void tlib_write_system_register_interrupt_cpu_interface(uint32_t offset, uint64_t value); 13 | 14 | uint64_t tlib_read_system_register_generic_timer_64(uint32_t offset); 15 | void tlib_write_system_register_generic_timer_64(uint32_t offset, uint64_t value); 16 | 17 | uint32_t tlib_read_system_register_generic_timer_32(uint32_t offset); 18 | void tlib_write_system_register_generic_timer_32(uint32_t offset, uint32_t value); 19 | 20 | void tlib_on_execution_mode_changed(uint32_t el, uint32_t is_secure); 21 | void tlib_handle_psci_call(void); 22 | -------------------------------------------------------------------------------- /arch/arm64/arch_exports.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Antmicro 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include "cpu.h" 9 | #include "system_registers.h" 10 | #include "tightly_coupled_memory.h" 11 | #include "unwind.h" 12 | 13 | uint32_t tlib_has_el3() 14 | { 15 | return arm_feature(cpu, ARM_FEATURE_EL3); 16 | } 17 | EXC_INT_0(uint32_t, tlib_has_el3) 18 | 19 | // Clang, at least Apple clang version 13.0.0 (clang-1300.0.29.30; x86_64-apple-darwin20.5.0), 20 | // improperly optimizes the functions below (EXC_INT_1 generates a wrapper function). 21 | // 22 | // If 'is_generic_timer_register(ri) == true' then the return value read through the wrapper 23 | // is correct but if 'is_gic_register(ri) == true' then the return value is invalid (false). 24 | // 25 | // Disabling optimization for either of these functions fixes the issue. 26 | // 27 | // The functions are also problematic with GCC 12+ when compiled with '-ftree-pre'. 28 | // A value read through the wrapper is always false even if any of 'is_gic_*' is true. 29 | #ifdef __clang__ 30 | #pragma clang optimize off 31 | #elif __GNUC__ 32 | // Disable GCC's Partial Redundancy Elimination for this function. 33 | __attribute__((optimize("-fno-tree-pre"))) 34 | #endif 35 | bool tlib_is_gic_or_generic_timer_system_register(char *name) 36 | { 37 | const ARMCPRegInfo *ri = sysreg_find_by_name(env, name); 38 | return ri != NULL && (is_gic_register(ri) || is_generic_timer_register(ri)); 39 | } 40 | EXC_INT_1(bool, tlib_is_gic_or_generic_timer_system_register, char *, name) 41 | 42 | #ifdef __clang__ 43 | #pragma clang optimize on 44 | #endif 45 | 46 | uint32_t tlib_set_available_els(bool el2_enabled, bool el3_enabled) 47 | { 48 | enum { 49 | SIMULATION_ALREADY_STARTED = 1, 50 | SUCCESS = 3, 51 | }; 52 | 53 | if(cpu->instructions_count_total_value != 0) { 54 | return SIMULATION_ALREADY_STARTED; 55 | } 56 | 57 | set_el_features(cpu, el2_enabled, el3_enabled); 58 | 59 | if(is_a64(env)) { 60 | // Reset the Exception Level a CPU starts in. 61 | uint32_t reset_el = arm_highest_el(cpu); 62 | cpu->pstate = deposit32(cpu->pstate, 2, 2, reset_el); 63 | } else { 64 | uint32_t reset_mode = arm_get_highest_cpu_mode(env); 65 | cpsr_write(env, reset_mode, CPSR_M, CPSRWriteRaw); 66 | } 67 | 68 | arm_rebuild_hflags(cpu); 69 | 70 | tlib_on_execution_mode_changed(arm_current_el(env), arm_is_secure(env)); 71 | 72 | return SUCCESS; 73 | } 74 | EXC_INT_2(uint32_t, tlib_set_available_els, bool, el2_enabled, bool, el3_enabled) 75 | 76 | void tlib_psci_handler_enable(uint32_t mode) 77 | { 78 | // Options are mutually exclusive 79 | env->emulate_smc_calls = false; 80 | env->emulate_hvc_calls = false; 81 | 82 | switch(mode) { 83 | case 0: 84 | // We have already disabled the handlers 85 | break; 86 | case 1: 87 | env->emulate_smc_calls = true; 88 | break; 89 | case 2: 90 | env->emulate_hvc_calls = true; 91 | break; 92 | default: 93 | tlib_abortf("Unknown PSCI handler mode %d", mode); 94 | } 95 | } 96 | EXC_VOID_1(tlib_psci_handler_enable, uint32_t, mode) 97 | 98 | void tlib_set_current_el(uint32_t el) 99 | { 100 | pstate_set_el(cpu, el); 101 | } 102 | EXC_VOID_1(tlib_set_current_el, uint32_t, el) 103 | 104 | void tlib_set_mpu_regions_count(uint32_t el1_regions_count, uint32_t el2_regions_count) 105 | { 106 | if(el1_regions_count > MAX_MPU_REGIONS || el2_regions_count > MAX_MPU_REGIONS) { 107 | tlib_abortf("Unable to set MPU regions count to %d. Maximum value for this core is %d", 108 | el1_regions_count > el2_regions_count ? el1_regions_count : el2_regions_count, MAX_MPU_REGIONS); 109 | } 110 | 111 | set_pmsav8_regions_count(cpu, el1_regions_count, el2_regions_count); 112 | } 113 | EXC_VOID_2(tlib_set_mpu_regions_count, uint32_t, count, uint32_t, hyp_count) 114 | 115 | /* Based on the documentation for Cortex-R52 */ 116 | void tlib_register_tcm_region(uint32_t address, uint64_t size, uint64_t region_index) 117 | { 118 | if(size == 0) { 119 | // Disable this region in the TCMTR 120 | cpu->cp15.tcm_type &= ~(1 << region_index); 121 | cpu->cp15.tcm_region[region_index] = 0; 122 | } else { 123 | validate_tcm_region(address, size, region_index, TARGET_PAGE_SIZE); 124 | 125 | // Set this region as enabled 126 | cpu->cp15.tcm_type |= 1 << region_index; 127 | cpu->cp15.tcm_region[region_index] = address | (ctz64(size / TCM_UNIT_SIZE) << 2) | 3; // enable in all modes 128 | } 129 | 130 | // Set TCMS bit - one or more TCMS implemented 131 | if(cpu->cp15.tcm_type & 0x7) { 132 | cpu->cp15.tcm_type |= 1u << 31; 133 | } else { 134 | cpu->cp15.tcm_type &= ~(1u << 31); 135 | } 136 | } 137 | 138 | EXC_VOID_3(tlib_register_tcm_region, uint32_t, address, uint64_t, size, uint64_t, index) 139 | 140 | void tlib_set_gic_cpu_register_interface_version(uint32_t iface_version) 141 | { 142 | env->arm_core_config.gic_cpu_interface_version = iface_version; 143 | env->arm_core_config.isar.id_aa64pfr0 = FIELD_DP64(env->arm_core_config.isar.id_aa64pfr0, ID_AA64PFR0, GIC, iface_version); 144 | env->arm_core_config.isar.id_pfr1 = FIELD_DP64(env->arm_core_config.isar.id_pfr1, ID_PFR1, GIC, iface_version); 145 | } 146 | 147 | EXC_VOID_1(tlib_set_gic_cpu_register_interface_version, uint32_t, iface_version) 148 | -------------------------------------------------------------------------------- /arch/arm64/arch_exports.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Antmicro 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include "arch_exports_common.h" 11 | 12 | uint32_t tlib_has_el3(); 13 | bool tlib_is_gic_or_generic_timer_system_register(char *name); 14 | void tlib_register_tcm_region(uint32_t address, uint64_t size, uint64_t region_index); 15 | void tlib_set_available_els(bool el2_enabled, bool el3_enabled); 16 | void tlib_set_current_el(uint32_t el); 17 | void tlib_set_mpu_regions_count(uint32_t count); 18 | void tlib_psci_handler_enable(uint32_t mode); 19 | void tlib_set_gic_cpu_register_interface_version(uint32_t iface_version); 20 | -------------------------------------------------------------------------------- /arch/arm64/arm_ldst.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ARM load/store instructions for code (armeb-user support) 3 | * 4 | * Copyright (c) 2012 CodeSourcery, LLC 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include "bswap.h" 23 | 24 | /* Load an instruction and return it in the standard little-endian order */ 25 | static inline uint32_t arm_ldl_code(CPUARMState *env, DisasContextBase *s, target_ulong addr, bool sctlr_b) 26 | { 27 | // TODO: Uncomment after implementing properly translator_ldl_swap() 28 | // Until that use a direct call to ldl_code() 29 | // return translator_ldl_swap(env, s, addr, bswap_code(sctlr_b)); 30 | 31 | return ldl_code(addr); 32 | } 33 | 34 | /* Ditto, for a halfword (Thumb) instruction */ 35 | static inline uint16_t arm_lduw_code(CPUARMState *env, DisasContextBase *s, target_ulong addr, bool sctlr_b) 36 | { 37 | 38 | // TODO: Uncomment after implementing properly translator_lduw_swap() 39 | // Until that use direct call to lduw_code() 40 | // /* In big-endian (BE32) mode, adjacent Thumb instructions have been swapped 41 | // within each word. Undo that now. */ 42 | // if (sctlr_b) { 43 | // addr ^= 2; 44 | // } 45 | // return translator_lduw_swap(env, s, addr, bswap_code(sctlr_b)); 46 | 47 | return lduw_code(addr); 48 | } 49 | -------------------------------------------------------------------------------- /arch/arm64/cpu-param.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ARM cpu parameters. 3 | * 4 | * Copyright (c) 2003 Fabrice Bellard 5 | * SPDX-License-Identifier: LGPL-2.0+ 6 | */ 7 | 8 | #pragma once 9 | 10 | #ifdef TARGET_AARCH64 11 | #define TARGET_PHYS_ADDR_SPACE_BITS 52 12 | #define TARGET_VIRT_ADDR_SPACE_BITS 52 13 | #else 14 | #define TARGET_PHYS_ADDR_SPACE_BITS 40 15 | #define TARGET_VIRT_ADDR_SPACE_BITS 32 16 | #endif 17 | 18 | #define TARGET_PAGE_BITS 12 // 4k 19 | 20 | #define NB_MMU_MODES 15 21 | -------------------------------------------------------------------------------- /arch/arm64/cpu_names.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Antmicro 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | // From the core's "Main ID Register", i.e., MIDR_EL1. 13 | #define ARM_CPUID_CORTEXA53 0x410fd034 14 | #define ARM_CPUID_CORTEXA55 0x411fd050 15 | #define ARM_CPUID_CORTEXA75 0x413fd0a1 16 | #define ARM_CPUID_CORTEXA76 0x414fd0b1 17 | #define ARM_CPUID_CORTEXA78 0x411fd412 18 | #define ARM_CPUID_CORTEXR52 0x411fd132 19 | #define ARM_CPUID_NOT_FOUND 0x0 20 | 21 | static const struct arm_cpu_t arm_cpu_names[] = { 22 | { ARM_CPUID_CORTEXA53, "cortex-a53" }, 23 | { ARM_CPUID_CORTEXA55, "cortex-a55" }, 24 | { ARM_CPUID_CORTEXA75, "cortex-a75" }, 25 | { ARM_CPUID_CORTEXA76, "cortex-a76" }, 26 | { ARM_CPUID_CORTEXA78, "cortex-a78" }, 27 | { ARM_CPUID_CORTEXR52, "cortex-r52" }, 28 | { ARM_CPUID_NOT_FOUND, NULL }, 29 | }; 30 | 31 | uint32_t cpu_arm_find_by_name(const char *name); 32 | -------------------------------------------------------------------------------- /arch/arm64/cpu_registers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Antmicro 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | 9 | #include "cpu.h" 10 | #include "cpu_registers.h" 11 | #include "unwind.h" 12 | 13 | uint64_t tlib_get_register_value_64(int reg_number) 14 | { 15 | // TODO: AArch64 to AArch32 mappings (R8_fiq == W24, SP_irq == W17 etc.): 16 | // https://developer.arm.com/documentation/den0024/a/ARMv8-Registers/Changing-execution-state--again-/Registers-at-AArch32 17 | switch(reg_number) { 18 | case CPSR_32: 19 | return cpsr_read(cpu); 20 | case PSTATE_32: 21 | return pstate_read(cpu); 22 | case FPCR_32: 23 | return vfp_get_fpcr(cpu); 24 | case FPSR_32: 25 | return vfp_get_fpsr(cpu); 26 | case R_0_32 ... R_15_32: 27 | return cpu->regs[reg_number - R_0_32]; 28 | case PC_64: 29 | // The PC register's index is the same for both AArch32 and AArch64. 30 | return is_a64(cpu) ? cpu->pc : cpu->regs[15]; 31 | case SP_64: 32 | // The SP register's index is the same for both AArch32 and AArch64. 33 | return is_a64(cpu) ? cpu->xregs[31] : cpu->regs[13]; 34 | case X_0_64 ... X_30_64: 35 | return cpu->xregs[reg_number - X_0_64]; 36 | } 37 | 38 | tlib_abortf("Read from undefined CPU register number %d detected", reg_number); 39 | __builtin_unreachable(); 40 | } 41 | 42 | EXC_INT_1(uint64_t, tlib_get_register_value_64, int, reg_number) 43 | 44 | void tlib_set_register_value_64(int reg_number, uint64_t value) 45 | { 46 | switch(reg_number) { 47 | case CPSR_32: 48 | cpsr_write(cpu, (uint32_t)value, 0xFFFFFFFF, CPSRWriteRaw); 49 | arm_rebuild_hflags(cpu); 50 | return; 51 | case PSTATE_32: 52 | pstate_write(cpu, (uint32_t)value); 53 | arm_rebuild_hflags(cpu); 54 | return; 55 | case FPCR_32: 56 | vfp_set_fpcr(cpu, (uint32_t)value); 57 | return; 58 | case FPSR_32: 59 | vfp_set_fpsr(cpu, (uint32_t)value); 60 | return; 61 | case R_0_32 ... R_15_32: 62 | cpu->regs[reg_number - R_0_32] = (uint32_t)value; 63 | return; 64 | case PC_64: 65 | // The PC register's index is the same for both AArch32 and AArch64. 66 | if(is_a64(cpu)) { 67 | cpu->pc = value; 68 | } else { 69 | cpu->regs[15] = (uint32_t)value; 70 | } 71 | return; 72 | case SP_64: 73 | // The SP register's index is the same for both AArch32 and AArch64. 74 | if(is_a64(cpu)) { 75 | cpu->xregs[31] = value; 76 | } else { 77 | cpu->regs[13] = (uint32_t)value; 78 | } 79 | return; 80 | case X_0_64 ... X_30_64: 81 | cpu->xregs[reg_number - X_0_64] = value; 82 | return; 83 | } 84 | 85 | tlib_abortf("Write to undefined CPU register number %d detected", reg_number); 86 | } 87 | 88 | EXC_VOID_2(tlib_set_register_value_64, int, reg_number, uint64_t, value) 89 | 90 | uint32_t tlib_get_register_value_32(int reg_number) 91 | { 92 | return (uint32_t)tlib_get_register_value_64(reg_number); 93 | } 94 | 95 | EXC_INT_1(uint32_t, tlib_get_register_value_32, int, reg_number) 96 | 97 | void tlib_set_register_value_32(int reg_number, uint32_t value) 98 | { 99 | tlib_set_register_value_64(reg_number, value); 100 | } 101 | 102 | EXC_VOID_2(tlib_set_register_value_32, int, reg_number, uint32_t, value) 103 | -------------------------------------------------------------------------------- /arch/arm64/cpu_registers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cpu-defs.h" 4 | 5 | // Indexes for AArch64 registers are in line with GDB's 'arch/aarch64.h'. 6 | typedef enum { 7 | X_0_64 = 0, 8 | X_1_64 = 1, 9 | X_2_64 = 2, 10 | X_3_64 = 3, 11 | X_4_64 = 4, 12 | X_5_64 = 5, 13 | X_6_64 = 6, 14 | X_7_64 = 7, 15 | X_8_64 = 8, 16 | X_9_64 = 9, 17 | X_10_64 = 10, 18 | X_11_64 = 11, 19 | X_12_64 = 12, 20 | X_13_64 = 13, 21 | X_14_64 = 14, 22 | X_15_64 = 15, 23 | X_16_64 = 16, 24 | X_17_64 = 17, 25 | X_18_64 = 18, 26 | X_19_64 = 19, 27 | X_20_64 = 20, 28 | X_21_64 = 21, 29 | X_22_64 = 22, 30 | X_23_64 = 23, 31 | X_24_64 = 24, 32 | X_25_64 = 25, 33 | X_26_64 = 26, 34 | X_27_64 = 27, 35 | X_28_64 = 28, 36 | X_29_64 = 29, 37 | X_30_64 = 30, 38 | // There's no X31 register even though Stack Pointer is often represented with 39 | // 31 in the instruction encoding (but it can also mean Zero Register: XZR/WZR). 40 | SP_64 = 31, 41 | PC_64 = 32, 42 | PSTATE_32 = 33, 43 | FPSR_32 = 66, 44 | FPCR_32 = 67, 45 | 46 | R_0_32 = 100, 47 | R_1_32 = 101, 48 | R_2_32 = 102, 49 | R_3_32 = 103, 50 | R_4_32 = 104, 51 | R_5_32 = 105, 52 | R_6_32 = 106, 53 | R_7_32 = 107, 54 | R_8_32 = 108, 55 | R_9_32 = 109, 56 | R_10_32 = 110, 57 | R_11_32 = 111, 58 | R_12_32 = 112, 59 | // If AArch32 it can be also accessed with SP_64. 60 | R_13_32 = 113, 61 | R_14_32 = 114, 62 | // If AArch32 it can be also accessed with PC_64. 63 | R_15_32 = 115, 64 | CPSR_32 = 125, 65 | } Registers; 66 | 67 | /* The return address is stored here */ 68 | #define RA (is_a64(cpu) ? X_30_64 : R_14_32) 69 | -------------------------------------------------------------------------------- /arch/arm64/decode-neon-ls.c.inc: -------------------------------------------------------------------------------- 1 | /* This file is autogenerated by scripts/decodetree.py. */ 2 | 3 | typedef struct { 4 | int l; 5 | int rn; 6 | int itype; 7 | int size; 8 | int align; 9 | int rm; 10 | int vd; 11 | } arg_disas_neon_ls0; 12 | 13 | typedef struct { 14 | int rn; 15 | int n; 16 | int size; 17 | int t; 18 | int a; 19 | int rm; 20 | int vd; 21 | } arg_disas_neon_ls1; 22 | 23 | typedef struct { 24 | int l; 25 | int rn; 26 | int n; 27 | int reg_idx; 28 | int align; 29 | int rm; 30 | int vd; 31 | int size; 32 | int stride; 33 | } arg_disas_neon_ls2; 34 | 35 | typedef arg_disas_neon_ls0 arg_VLDST_multiple; 36 | static bool trans_VLDST_multiple(DisasContext *ctx, arg_VLDST_multiple *a); 37 | typedef arg_disas_neon_ls1 arg_VLD_all_lanes; 38 | static bool trans_VLD_all_lanes(DisasContext *ctx, arg_VLD_all_lanes *a); 39 | typedef arg_disas_neon_ls2 arg_VLDST_single; 40 | static bool trans_VLDST_single(DisasContext *ctx, arg_VLDST_single *a); 41 | 42 | static void disas_neon_ls_extract_disas_neon_ls_Fmt_0(DisasContext *ctx, arg_disas_neon_ls0 *a, uint32_t insn) 43 | { 44 | a->l = extract32(insn, 21, 1); 45 | a->rn = extract32(insn, 16, 4); 46 | a->itype = extract32(insn, 8, 4); 47 | a->size = extract32(insn, 6, 2); 48 | a->align = extract32(insn, 4, 2); 49 | a->rm = extract32(insn, 0, 4); 50 | a->vd = deposit32(extract32(insn, 12, 4), 4, 28, extract32(insn, 22, 1)); 51 | } 52 | 53 | static void disas_neon_ls_extract_disas_neon_ls_Fmt_1(DisasContext *ctx, arg_disas_neon_ls1 *a, uint32_t insn) 54 | { 55 | a->rn = extract32(insn, 16, 4); 56 | a->n = extract32(insn, 8, 2); 57 | a->size = extract32(insn, 6, 2); 58 | a->t = extract32(insn, 5, 1); 59 | a->a = extract32(insn, 4, 1); 60 | a->rm = extract32(insn, 0, 4); 61 | a->vd = deposit32(extract32(insn, 12, 4), 4, 28, extract32(insn, 22, 1)); 62 | } 63 | 64 | static void disas_neon_ls_extract_disas_neon_ls_Fmt_2(DisasContext *ctx, arg_disas_neon_ls2 *a, uint32_t insn) 65 | { 66 | a->l = extract32(insn, 21, 1); 67 | a->rn = extract32(insn, 16, 4); 68 | a->n = extract32(insn, 8, 2); 69 | a->reg_idx = extract32(insn, 5, 3); 70 | a->align = extract32(insn, 4, 1); 71 | a->rm = extract32(insn, 0, 4); 72 | a->vd = deposit32(extract32(insn, 12, 4), 4, 28, extract32(insn, 22, 1)); 73 | a->size = 0; 74 | a->stride = 1; 75 | } 76 | 77 | static void disas_neon_ls_extract_disas_neon_ls_Fmt_3(DisasContext *ctx, arg_disas_neon_ls2 *a, uint32_t insn) 78 | { 79 | a->l = extract32(insn, 21, 1); 80 | a->rn = extract32(insn, 16, 4); 81 | a->n = extract32(insn, 8, 2); 82 | a->reg_idx = extract32(insn, 6, 2); 83 | a->align = extract32(insn, 4, 1); 84 | a->rm = extract32(insn, 0, 4); 85 | a->vd = deposit32(extract32(insn, 12, 4), 4, 28, extract32(insn, 22, 1)); 86 | a->size = 1; 87 | a->stride = plus_1(ctx, extract32(insn, 5, 1)); 88 | } 89 | 90 | static void disas_neon_ls_extract_disas_neon_ls_Fmt_4(DisasContext *ctx, arg_disas_neon_ls2 *a, uint32_t insn) 91 | { 92 | a->l = extract32(insn, 21, 1); 93 | a->rn = extract32(insn, 16, 4); 94 | a->n = extract32(insn, 8, 2); 95 | a->reg_idx = extract32(insn, 7, 1); 96 | a->align = extract32(insn, 4, 2); 97 | a->rm = extract32(insn, 0, 4); 98 | a->vd = deposit32(extract32(insn, 12, 4), 4, 28, extract32(insn, 22, 1)); 99 | a->size = 2; 100 | a->stride = plus_1(ctx, extract32(insn, 6, 1)); 101 | } 102 | 103 | bool disas_neon_ls(DisasContext *ctx, uint32_t insn) 104 | { 105 | union { 106 | arg_disas_neon_ls0 f_disas_neon_ls0; 107 | arg_disas_neon_ls1 f_disas_neon_ls1; 108 | arg_disas_neon_ls2 f_disas_neon_ls2; 109 | } u; 110 | 111 | switch (insn & 0xff900000u) { 112 | case 0xf4000000u: 113 | /* 11110100 0..0.... ........ ........ */ 114 | /* arch/arm64/neon-ls.decode:35 */ 115 | disas_neon_ls_extract_disas_neon_ls_Fmt_0(ctx, &u.f_disas_neon_ls0, insn); 116 | if (trans_VLDST_multiple(ctx, &u.f_disas_neon_ls0)) return true; 117 | break; 118 | case 0xf4800000u: 119 | /* 11110100 1..0.... ........ ........ */ 120 | switch ((insn >> 10) & 0x3) { 121 | case 0x0: 122 | /* 11110100 1..0.... ....00.. ........ */ 123 | /* arch/arm64/neon-ls.decode:47 */ 124 | disas_neon_ls_extract_disas_neon_ls_Fmt_2(ctx, &u.f_disas_neon_ls2, insn); 125 | if (trans_VLDST_single(ctx, &u.f_disas_neon_ls2)) return true; 126 | break; 127 | case 0x1: 128 | /* 11110100 1..0.... ....01.. ........ */ 129 | /* arch/arm64/neon-ls.decode:49 */ 130 | disas_neon_ls_extract_disas_neon_ls_Fmt_3(ctx, &u.f_disas_neon_ls2, insn); 131 | if (trans_VLDST_single(ctx, &u.f_disas_neon_ls2)) return true; 132 | break; 133 | case 0x2: 134 | /* 11110100 1..0.... ....10.. ........ */ 135 | /* arch/arm64/neon-ls.decode:51 */ 136 | disas_neon_ls_extract_disas_neon_ls_Fmt_4(ctx, &u.f_disas_neon_ls2, insn); 137 | if (trans_VLDST_single(ctx, &u.f_disas_neon_ls2)) return true; 138 | break; 139 | case 0x3: 140 | /* 11110100 1..0.... ....11.. ........ */ 141 | disas_neon_ls_extract_disas_neon_ls_Fmt_1(ctx, &u.f_disas_neon_ls1, insn); 142 | switch ((insn >> 21) & 0x1) { 143 | case 0x1: 144 | /* 11110100 1.10.... ....11.. ........ */ 145 | /* arch/arm64/neon-ls.decode:40 */ 146 | if (trans_VLD_all_lanes(ctx, &u.f_disas_neon_ls1)) return true; 147 | break; 148 | } 149 | break; 150 | } 151 | break; 152 | } 153 | return false; 154 | } 155 | -------------------------------------------------------------------------------- /arch/arm64/mmu.h: -------------------------------------------------------------------------------- 1 | // Header based on Zephyr ARM64 MMU implementation: 2 | // https://github.com/zephyrproject-rtos/zephyr/blob/zephyr-v3.2.0/arch/arm64/core/mmu.h 3 | 4 | #pragma once 5 | 6 | #define MMU_XLAT_LAST_LEVEL 3U 7 | 8 | #define MMU_Ln_XLAT_VA_SIZE_SHIFT(page_size_shift) (page_size_shift - 3) 9 | #define MMU_L3_XLAT_VA_SIZE_SHIFT(page_size_shift) page_size_shift 10 | #define MMU_L2_XLAT_VA_SIZE_SHIFT(page_size_shift) \ 11 | (MMU_L3_XLAT_VA_SIZE_SHIFT(page_size_shift) + MMU_Ln_XLAT_VA_SIZE_SHIFT(page_size_shift)) 12 | #define MMU_L1_XLAT_VA_SIZE_SHIFT(page_size_shift) \ 13 | (MMU_L2_XLAT_VA_SIZE_SHIFT(page_size_shift) + MMU_Ln_XLAT_VA_SIZE_SHIFT(page_size_shift)) 14 | #define MMU_L0_XLAT_VA_SIZE_SHIFT(page_size_shift) \ 15 | (MMU_L1_XLAT_VA_SIZE_SHIFT(page_size_shift) + MMU_Ln_XLAT_VA_SIZE_SHIFT(page_size_shift)) 16 | 17 | // The MMU_GET_XLAT_VA_SIZE_SHIFT macro returns VA size shift for given level/page size 18 | // as per the table in https://developer.arm.com/documentation/101811/0102/Translation-granule 19 | #define MMU_GET_XLAT_VA_SIZE_SHIFT(level, page_size_shift) \ 20 | ((level == 3) ? MMU_L3_XLAT_VA_SIZE_SHIFT(page_size_shift) \ 21 | : (level == 2) ? MMU_L2_XLAT_VA_SIZE_SHIFT(page_size_shift) \ 22 | : (level == 1) ? MMU_L1_XLAT_VA_SIZE_SHIFT(page_size_shift) \ 23 | : MMU_L0_XLAT_VA_SIZE_SHIFT(page_size_shift)) 24 | 25 | #define MMU_GET_BASE_XLAT_LEVEL(va_bits, page_size_shift) \ 26 | ((va_bits > MMU_L0_XLAT_VA_SIZE_SHIFT(page_size_shift)) ? 0U \ 27 | : (va_bits > MMU_L1_XLAT_VA_SIZE_SHIFT(page_size_shift)) ? 1U \ 28 | : (va_bits > MMU_L2_XLAT_VA_SIZE_SHIFT(page_size_shift)) ? 2U \ 29 | : 3U) 30 | 31 | #define MMU_LEVEL_TO_VA_SIZE_SHIFT(level, page_size_shift) \ 32 | (page_size_shift + (MMU_Ln_XLAT_VA_SIZE_SHIFT(page_size_shift) * (MMU_XLAT_LAST_LEVEL - (level)))) 33 | 34 | #define TTBR_CNP 1ULL 35 | 36 | enum { 37 | DESCRIPTOR_TYPE_INVALID_0, 38 | DESCRIPTOR_TYPE_BLOCK_ENTRY, 39 | DESCRIPTOR_TYPE_INVALID_2, 40 | DESCRIPTOR_TYPE_TABLE_DESCRIPTOR_OR_ENTRY, 41 | }; 42 | 43 | ARMMMUIdx get_current_arm_mmu_idx(CPUState *env); 44 | -------------------------------------------------------------------------------- /arch/arm64/system_registers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Antmicro 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include "cpu.h" 11 | #include "system_registers_common.h" 12 | 13 | // This doesn't seem to be of any real use. It's passed to ENCODE_AA64_CP_REG in 'translate-a64.c:handle_sys' 14 | // as 'cp' so it seems to be a coprocessor ID. However, there's no information about coprocessor for AArch64 15 | // registers and instructions in the manual. There's only an information that some instruction type encodings 16 | // are "equivalent to the registers in the AArch32 (coproc == XX) encoding space" (XX=15 for op0=(1 or 3) and 17 | // XX=14 for op0=2). Perhaps let's use 16 to distinguish it from CP15 used for AArch32 and ARMv7 encodings. 18 | #define CP_REG_ARM64_SYSREG_CP 16 19 | 20 | // From C5.1.2 21 | #define CP_REG_ARM64_SYSREG_OP2_SHIFT 0 22 | #define CP_REG_ARM64_SYSREG_CRM_SHIFT (CP_REG_ARM64_SYSREG_OP2_SHIFT + 3) 23 | #define CP_REG_ARM64_SYSREG_CRN_SHIFT (CP_REG_ARM64_SYSREG_CRM_SHIFT + 4) 24 | #define CP_REG_ARM64_SYSREG_OP1_SHIFT (CP_REG_ARM64_SYSREG_CRN_SHIFT + 4) 25 | #define CP_REG_ARM64_SYSREG_OP0_SHIFT (CP_REG_ARM64_SYSREG_OP1_SHIFT + 3) 26 | // op0 is a 2-bit field 27 | #define CP_REG_ARM_COPROC_SHIFT (CP_REG_ARM64_SYSREG_OP0_SHIFT + 2) 28 | 29 | void system_instructions_and_registers_reset(CPUState *env); 30 | void system_instructions_and_registers_init(CPUState *env, uint32_t cpu_model_id); 31 | -------------------------------------------------------------------------------- /arch/arm_common/arch_exports_common.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Antmicro 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include "cpu.h" 9 | #include "system_registers_common.h" 10 | 11 | uint32_t tlib_check_system_register_access(const char *name, bool is_write) 12 | { 13 | enum { 14 | REGISTER_NOT_FOUND = 1, 15 | ACCESSOR_NOT_FOUND = 2, 16 | ACCESS_VALID = 3, 17 | }; 18 | 19 | const ARMCPRegInfo *ri = sysreg_find_by_name(env, name); 20 | if(ri == NULL) { 21 | return REGISTER_NOT_FOUND; 22 | } 23 | 24 | if(ri->fieldoffset) { 25 | return ACCESS_VALID; 26 | } 27 | 28 | if(is_write) { 29 | bool write_possible = ri->writefn != NULL; 30 | return write_possible ? ACCESS_VALID : ACCESSOR_NOT_FOUND; 31 | } else { 32 | bool read_possible = (ri->readfn != NULL) || (ri->type & ARM_CP_CONST); 33 | return read_possible ? ACCESS_VALID : ACCESSOR_NOT_FOUND; 34 | } 35 | } 36 | EXC_INT_2(uint32_t, tlib_check_system_register_access, const char *, name, bool, is_write) 37 | 38 | uint32_t tlib_create_system_registers_array(char ***array) 39 | { 40 | return ttable_create_values_array(cpu->cp_regs, (void ***)array, try_set_array_entry_to_system_register); 41 | } 42 | EXC_INT_1(uint32_t, tlib_create_system_registers_array, char ***, array) 43 | 44 | uint64_t tlib_get_system_register(const char *name, bool log_unhandled_access) 45 | { 46 | return sysreg_get_by_name(cpu, name, log_unhandled_access); 47 | } 48 | EXC_INT_2(uint64_t, tlib_get_system_register, const char *, name, bool, log_unhandled_access) 49 | 50 | void tlib_set_system_register(const char *name, uint64_t value, bool log_unhandled_access) 51 | { 52 | sysreg_set_by_name(cpu, name, value, log_unhandled_access); 53 | } 54 | EXC_VOID_3(tlib_set_system_register, const char *, name, uint64_t, value, bool, log_unhandled_access) 55 | -------------------------------------------------------------------------------- /arch/arm_common/arch_exports_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Antmicro 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | uint32_t tlib_check_system_register_access(const char *name, bool is_write); 12 | uint32_t tlib_create_system_registers_array(char ***array); 13 | uint64_t tlib_get_system_register(const char *name); 14 | void tlib_set_system_register(const char *name, uint64_t value); 15 | -------------------------------------------------------------------------------- /arch/arm_common/cpu_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Antmicro 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | /* For M profile, some registers are banked secure vs non-secure; 10 | * these are represented as a 2-element array where the first element 11 | * is the non-secure copy and the second is the secure copy. 12 | * When the CPU does not have implement the security extension then 13 | * only the first element is used. 14 | * This means that the copy for the current security state can be 15 | * accessed via env->registerfield[env->v7m.secure] (whether the security 16 | * extension is implemented or not). 17 | */ 18 | enum { 19 | M_REG_NS = 0, 20 | M_REG_S = 1, 21 | M_REG_NUM_BANKS = 2, 22 | }; 23 | -------------------------------------------------------------------------------- /arch/arm_common/helper_common.c: -------------------------------------------------------------------------------- 1 | #include "helper_common.h" 2 | #include "system_registers_common.h" 3 | #include "infrastructure.h" 4 | 5 | #if TARGET_LONG_BITS == 64 6 | #define PC_FMT PRIx64 7 | #else 8 | #define PC_FMT PRIx32 9 | #endif 10 | 11 | void HELPER(warn_cp_invalid_el)(CPUState *env, void *reg_info, uint32_t current_el) 12 | { 13 | tlib_printf(LOG_LEVEL_WARNING, "[PC=0x%" PC_FMT "] The '%s' register shouldn't be accessed on EL%d", CPU_PC(env), 14 | ((ARMCPRegInfo *)reg_info)->name, current_el); 15 | } 16 | 17 | void HELPER(warn_cp_invalid_access)(CPUState *env, void *reg_info, uint32_t isread) 18 | { 19 | tlib_printf(LOG_LEVEL_WARNING, "[PC=0x%" PC_FMT "] The '%s' register shouldn't be %s", CPU_PC(env), 20 | ((ARMCPRegInfo *)reg_info)->name, isread ? "read from" : "written to"); 21 | } 22 | -------------------------------------------------------------------------------- /arch/arm_common/helper_common.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include "cpu.h" 3 | 4 | #include "def-helper.h" 5 | 6 | DEF_HELPER_3(warn_cp_invalid_el, void, env, ptr, i32); 7 | DEF_HELPER_3(warn_cp_invalid_access, void, env, ptr, i32); 8 | 9 | #include "def-helper.h" 10 | -------------------------------------------------------------------------------- /arch/arm_common/tightly_coupled_memory.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Antmicro 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include "bit_helper.h" 8 | #include "cpu-defs.h" 9 | #include "infrastructure.h" 10 | #include "tightly_coupled_memory.h" 11 | 12 | /* Check if the paramters meet the requirements from the spec. Otherwise abort core */ 13 | void validate_tcm_region(target_ulong base_address, target_ulong size, int region_index, target_ulong memory_granularity) 14 | { 15 | if(region_index >= MAX_TCM_REGIONS) { 16 | tlib_abortf("Attempted to register TCM region #%u, maximal supported value is %u", region_index, MAX_TCM_REGIONS); 17 | } 18 | // TODO: this should be configurable 19 | if(region_index >= 3) { 20 | tlib_abortf("Attempted to register TCM region #%u. This core supports only %u", region_index, 3); 21 | } 22 | 23 | if((size < TCM_UNIT_SIZE) || size > TCM_MAX_SIZE || !is_power_of_2(size)) { 24 | tlib_abortf("Attempted to register TCM region #%u with incorrect size 0x%x", region_index, size); 25 | } 26 | 27 | if((base_address % memory_granularity) || (base_address & TCM_CONFIGURATION_FIELDS_MASK) || (base_address % size)) { 28 | tlib_abortf("Attempted to set illegal TCM region base address (0x%llx)", base_address); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /arch/arm_common/tightly_coupled_memory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Antmicro 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | // Required for target_ulong. 10 | #include "cpu-defs.h" 11 | 12 | #if defined(TARGET_ARM64) 13 | #define MAX_TCM_REGIONS 3 14 | #else 15 | #define MAX_TCM_REGIONS 4 16 | #endif 17 | 18 | #define TCM_UNIT_SIZE 0x200 19 | #define TCM_MAX_SIZE (TCM_UNIT_SIZE << 0b01110) // Maximum configurable value 20 | #define TCM_CONFIGURATION_FIELDS_MASK 0xFFF 21 | 22 | #define TCM_CP15_OP2_DATA 0 23 | #define TCM_CP15_OP2_INSTRUCTION_OR_UNIFIED 1 24 | 25 | #define TCM_SIZE_64KB 0b111 26 | 27 | /* Check if the paramters meet the requirements from the spec. Otherwise abort core */ 28 | void validate_tcm_region(target_ulong base_address, target_ulong size, int region_index, target_ulong memory_granularity); 29 | -------------------------------------------------------------------------------- /arch/i386/arch_callbacks.c: -------------------------------------------------------------------------------- 1 | /* 2 | * x86 callbacks. 3 | * 4 | * Copyright (c) Antmicro 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, see . 18 | */ 19 | #include "callbacks.h" 20 | #include "arch_callbacks.h" 21 | 22 | DEFAULT_INT_HANDLER1(uint8_t tlib_read_byte_from_port, uint16_t address) 23 | 24 | DEFAULT_INT_HANDLER1(uint16_t tlib_read_word_from_port, uint16_t address) 25 | 26 | DEFAULT_INT_HANDLER1(uint32_t tlib_read_double_word_from_port, uint16_t address) 27 | 28 | DEFAULT_VOID_HANDLER2(void tlib_write_byte_to_port, uint16_t address, uint8_t value) 29 | 30 | DEFAULT_VOID_HANDLER2(void tlib_write_word_to_port, uint16_t address, uint16_t value) 31 | 32 | DEFAULT_VOID_HANDLER2(void tlib_write_double_word_to_port, uint16_t address, uint32_t value) 33 | 34 | DEFAULT_INT_HANDLER1(int32_t tlib_get_pending_interrupt, void) 35 | 36 | DEFAULT_INT_HANDLER1(uint64_t tlib_get_instruction_count, void) 37 | -------------------------------------------------------------------------------- /arch/i386/arch_callbacks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | uint8_t tlib_read_byte_from_port(uint16_t address); 6 | uint16_t tlib_read_word_from_port(uint16_t address); 7 | uint32_t tlib_read_double_word_from_port(uint16_t address); 8 | void tlib_write_byte_to_port(uint16_t address, uint8_t value); 9 | void tlib_write_word_to_port(uint16_t address, uint16_t value); 10 | void tlib_write_double_word_to_port(uint16_t address, uint32_t value); 11 | int32_t tlib_get_pending_interrupt(void); 12 | uint64_t tlib_get_instruction_count(void); 13 | -------------------------------------------------------------------------------- /arch/i386/arch_exports.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Antmicro 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include "arch_exports.h" 8 | #include "cpu.h" 9 | #include "unwind.h" 10 | 11 | void tlib_set_cs_descriptor(uint32_t selector, uint32_t base, uint32_t limit, uint32_t flags) 12 | { 13 | cpu_x86_load_seg_cache(env, R_CS, selector, base, limit, flags); 14 | } 15 | 16 | EXC_VOID_4(tlib_set_cs_descriptor, uint32_t, selector, uint32_t, base, uint32_t, limit, uint32_t, flags) 17 | -------------------------------------------------------------------------------- /arch/i386/arch_exports.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | void tlib_set_cs_descriptor(uint32_t selector, uint32_t base, uint32_t limit, uint32_t flags); 6 | -------------------------------------------------------------------------------- /arch/i386/cpu_registers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * X86 registers interface. 3 | * 4 | * Copyright (c) Antmicro 5 | * Copyright (c) Realtime Embedded 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, see . 19 | */ 20 | #include 21 | 22 | #include "cpu.h" 23 | #include "cpu_registers.h" 24 | 25 | #ifdef TARGET_X86_64 26 | uint64_t *get_reg_pointer_64(int reg) 27 | { 28 | switch(reg) { 29 | case RIP_64: 30 | return &(cpu->eip); 31 | case EFLAGS_64: 32 | return &(cpu->eflags); 33 | case CS_64: 34 | return &(cpu->segs[R_CS].base); 35 | case SS_64: 36 | return &(cpu->segs[R_SS].base); 37 | case DS_64: 38 | return &(cpu->segs[R_DS].base); 39 | case ES_64: 40 | return &(cpu->segs[R_ES].base); 41 | case FS_64: 42 | return &(cpu->segs[R_FS].base); 43 | case GS_64: 44 | return &(cpu->segs[R_GS].base); 45 | case RAX_64 ... R15_64: 46 | return &(cpu->regs[reg]); 47 | case CR0_64 ... CR4_64: 48 | return &(cpu->cr[reg - CR0_64]); 49 | case ST0_64 ... ST7_64: 50 | return &ST(reg - ST7_64).low; 51 | default: 52 | return NULL; 53 | } 54 | } 55 | 56 | CPU_REGISTER_ACCESSOR(64) 57 | #else 58 | uint32_t *get_reg_pointer_32(int reg) 59 | { 60 | switch(reg) { 61 | case EIP_32: 62 | return &(cpu->eip); 63 | case EFLAGS_32: 64 | return &(cpu->eflags); 65 | case CS_32: 66 | return &(cpu->segs[R_CS].base); 67 | case SS_32: 68 | return &(cpu->segs[R_SS].base); 69 | case DS_32: 70 | return &(cpu->segs[R_DS].base); 71 | case ES_32: 72 | return &(cpu->segs[R_ES].base); 73 | case FS_32: 74 | return &(cpu->segs[R_FS].base); 75 | case GS_32: 76 | return &(cpu->segs[R_GS].base); 77 | default: 78 | if(reg >= EAX_32 && reg <= EDI_32) { 79 | return &(cpu->regs[reg]); 80 | } 81 | if(reg >= CR0_32 && reg <= CR4_32) { 82 | return &(cpu->cr[reg - CR0_32]); 83 | } 84 | return NULL; 85 | } 86 | } 87 | 88 | CPU_REGISTER_ACCESSOR(32) 89 | #endif 90 | -------------------------------------------------------------------------------- /arch/i386/cpu_registers.h: -------------------------------------------------------------------------------- 1 | #include "cpu-defs.h" 2 | 3 | typedef enum { 4 | #ifdef TARGET_X86_64 5 | RAX_64 = 0, 6 | RCX_64 = 2, 7 | RDX_64 = 3, 8 | RBX_64 = 1, 9 | RSP_64 = 4, 10 | RBP_64 = 5, 11 | RSI_64 = 6, 12 | RDI_64 = 7, 13 | R8_64 = 8, 14 | R9_64 = 9, 15 | R10_64 = 10, 16 | R11_64 = 11, 17 | R12_64 = 12, 18 | R13_64 = 13, 19 | R14_64 = 14, 20 | R15_64 = 15, 21 | RIP_64 = 16, 22 | EFLAGS_64 = 17, 23 | CS_64 = 18, 24 | SS_64 = 19, 25 | DS_64 = 20, 26 | ES_64 = 21, 27 | FS_64 = 22, 28 | GS_64 = 23, 29 | ST0_64 = 24, 30 | ST1_64 = 25, 31 | ST2_64 = 26, 32 | ST3_64 = 27, 33 | ST4_64 = 28, 34 | ST5_64 = 29, 35 | ST6_64 = 30, 36 | ST7_64 = 31, 37 | CR0_64 = 32, 38 | CR1_64 = 33, 39 | CR2_64 = 34, 40 | CR3_64 = 35, 41 | CR4_64 = 36, 42 | #else 43 | EAX_32 = 0, 44 | ECX_32 = 1, 45 | EDX_32 = 2, 46 | EBX_32 = 3, 47 | ESP_32 = 4, 48 | EBP_32 = 5, 49 | ESI_32 = 6, 50 | EDI_32 = 7, 51 | EIP_32 = 8, 52 | EFLAGS_32 = 9, 53 | CS_32 = 10, 54 | SS_32 = 11, 55 | DS_32 = 12, 56 | ES_32 = 13, 57 | FS_32 = 14, 58 | GS_32 = 15, 59 | CR0_32 = 16, 60 | CR1_32 = 17, 61 | CR2_32 = 18, 62 | CR3_32 = 19, 63 | CR4_32 = 20 64 | #endif 65 | } Registers; 66 | -------------------------------------------------------------------------------- /arch/i386/x86.c: -------------------------------------------------------------------------------- 1 | /* 2 | * X86-specific interface functions. 3 | * 4 | * Copyright (c) Antmicro 5 | * Copyright (c) Realtime Embedded 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, see . 19 | */ 20 | #include 21 | #include "infrastructure.h" 22 | #include "arch_callbacks.h" 23 | 24 | #ifdef TARGET_I386 25 | 26 | int cpu_is_bsp(void *env) 27 | { 28 | tlib_printf(LOG_LEVEL_WARNING, "%s(...)", __FUNCTION__); 29 | return 0; 30 | } 31 | 32 | uint64_t cpu_get_apic_base(void *s) 33 | { 34 | tlib_printf(LOG_LEVEL_WARNING, "%s(...)", __FUNCTION__); 35 | return 0; 36 | } 37 | 38 | void apic_init_reset(void *s) 39 | { 40 | tlib_printf(LOG_LEVEL_WARNING, "%s(...)", __FUNCTION__); 41 | } 42 | 43 | void cpu_smm_update(void *env) 44 | { 45 | tlib_printf(LOG_LEVEL_WARNING, "%s(...)", __FUNCTION__); 46 | } 47 | 48 | void cpu_set_ferr(void *s) 49 | { 50 | tlib_printf(LOG_LEVEL_WARNING, "%s(...)", __FUNCTION__); 51 | } 52 | 53 | // task priority register 54 | void cpu_set_apic_tpr(void *s, uint8_t val) 55 | { 56 | tlib_printf(LOG_LEVEL_WARNING, "%s(%X)", __FUNCTION__, val); 57 | } 58 | 59 | void cpu_set_apic_base(void *d, uint64_t val) 60 | { 61 | tlib_printf(LOG_LEVEL_WARNING, "%s(%X) is currently not supported", __FUNCTION__, val); 62 | } 63 | 64 | int cpu_get_pic_interrupt(void *env) 65 | { 66 | return tlib_get_pending_interrupt(); 67 | } 68 | 69 | // task priority register 70 | uint8_t cpu_get_apic_tpr(void *d) 71 | { 72 | tlib_printf(LOG_LEVEL_WARNING, "%s(...)", __FUNCTION__); 73 | return 0; 74 | } 75 | 76 | void apic_sipi(void *s) 77 | { 78 | tlib_printf(LOG_LEVEL_WARNING, "%s(...)", __FUNCTION__); 79 | } 80 | 81 | uint64_t cpu_get_tsc(void *env) 82 | { 83 | return tlib_get_instruction_count(); 84 | } 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /arch/ppc/arch_callbacks.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PPC callbacks. 3 | * 4 | * Copyright (c) Antmicro 5 | * Copyright (c) Realtime Embedded 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, see . 19 | */ 20 | #include "callbacks.h" 21 | #include "arch_callbacks.h" 22 | 23 | DEFAULT_INT_HANDLER1(uint32_t tlib_read_tbl, void) 24 | 25 | DEFAULT_INT_HANDLER1(uint32_t tlib_read_tbu, void) 26 | 27 | DEFAULT_INT_HANDLER1(uint64_t tlib_read_decrementer, void) 28 | 29 | DEFAULT_VOID_HANDLER1(void tlib_write_decrementer, uint64_t value) 30 | 31 | DEFAULT_INT_HANDLER1(uint32_t tlib_is_vle_enabled, void) 32 | -------------------------------------------------------------------------------- /arch/ppc/arch_callbacks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | uint32_t tlib_read_tbl(void); 6 | uint32_t tlib_read_tbu(void); 7 | uint64_t tlib_read_decrementer(void); 8 | uint32_t tlib_is_vle_enabled(void); 9 | void tlib_write_decrementer(uint64_t value); 10 | -------------------------------------------------------------------------------- /arch/ppc/arch_exports.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PPC interface functions. 3 | * 4 | * Copyright (c) Antmicro 5 | * Copyright (c) Realtime Embedded 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, see . 19 | */ 20 | #include 21 | #include "cpu.h" 22 | #include "unwind.h" 23 | 24 | int32_t tlib_set_pending_interrupt(int32_t interruptNo, int32_t level) 25 | { 26 | if(level) { 27 | cpu->pending_interrupts |= 1 << interruptNo; 28 | } else { 29 | cpu->pending_interrupts &= ~(1 << interruptNo); 30 | if(cpu->pending_interrupts == 0) { 31 | return 1; 32 | } 33 | } 34 | return 0; 35 | } 36 | 37 | EXC_INT_2(int32_t, tlib_set_pending_interrupt, int32_t, interruptNo, int32_t, level) 38 | 39 | void tlib_set_little_endian_mode(bool mode) 40 | { 41 | if(mode) { 42 | cpu->hflags |= 1 << MSR_LE; 43 | cpu->msr |= 1 << MSR_LE; 44 | } else { 45 | cpu->hflags &= ~(1 << MSR_LE); 46 | cpu->msr &= ~(1 << MSR_LE); 47 | } 48 | } 49 | 50 | EXC_VOID_1(tlib_set_little_endian_mode, bool, mode) 51 | -------------------------------------------------------------------------------- /arch/ppc/arch_exports.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | int32_t tlib_set_pending_interrupt(int32_t interruptNo, int32_t level); 6 | void tlib_set_little_endian_mode(bool mode); 7 | -------------------------------------------------------------------------------- /arch/ppc/cpu_registers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PPC registers interface. 3 | * 4 | * Copyright (c) Antmicro 5 | * Copyright (c) Realtime Embedded 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, see . 19 | */ 20 | #include 21 | 22 | #include "cpu.h" 23 | #include "cpu_registers.h" 24 | 25 | #ifdef TARGET_PPC64 26 | uint64_t *get_reg_pointer_64(int reg) 27 | { 28 | switch(reg) { 29 | case R_0_64 ... R_31_64: 30 | return &(cpu->gpr[reg - R_0_64]); 31 | case NIP_64: 32 | return &(cpu->nip); 33 | case MSR_64: 34 | return &(cpu->msr); 35 | case LR_64: 36 | return &(cpu->lr); 37 | case CTR_64: 38 | return &(cpu->ctr); 39 | case XER_64: 40 | return &(cpu->xer); 41 | default: 42 | return NULL; 43 | } 44 | } 45 | CPU_REGISTER_ACCESSOR(64); 46 | #endif 47 | #ifdef TARGET_PPC32 48 | uint32_t *get_reg_pointer_32(int reg) 49 | { 50 | switch(reg) { 51 | case R_0_32 ... R_31_32: 52 | return &(cpu->gpr[reg - R_0_32]); 53 | case NIP_32: 54 | return &(cpu->nip); 55 | case MSR_32: 56 | return &(cpu->msr); 57 | case LR_32: 58 | return &(cpu->lr); 59 | case CTR_32: 60 | return &(cpu->ctr); 61 | case XER_32: 62 | return &(cpu->xer); 63 | default: 64 | return NULL; 65 | } 66 | } 67 | CPU_REGISTER_ACCESSOR(32); 68 | #endif 69 | -------------------------------------------------------------------------------- /arch/ppc/cpu_registers.h: -------------------------------------------------------------------------------- 1 | #include "cpu-defs.h" 2 | 3 | typedef enum { 4 | #ifdef TARGET_PPC64 5 | R_0_64 = 0, 6 | R_1_64 = 1, 7 | R_2_64 = 2, 8 | R_3_64 = 3, 9 | R_4_64 = 4, 10 | R_5_64 = 5, 11 | R_6_64 = 6, 12 | R_7_64 = 7, 13 | R_8_64 = 8, 14 | R_9_64 = 9, 15 | R_10_64 = 10, 16 | R_11_64 = 11, 17 | R_12_64 = 12, 18 | R_13_64 = 13, 19 | R_14_64 = 14, 20 | R_15_64 = 15, 21 | R_16_64 = 16, 22 | R_17_64 = 17, 23 | R_18_64 = 18, 24 | R_19_64 = 19, 25 | R_20_64 = 20, 26 | R_21_64 = 21, 27 | R_22_64 = 22, 28 | R_23_64 = 23, 29 | R_24_64 = 24, 30 | R_25_64 = 25, 31 | R_26_64 = 26, 32 | R_27_64 = 27, 33 | R_28_64 = 28, 34 | R_29_64 = 29, 35 | R_30_64 = 30, 36 | R_31_64 = 31, 37 | NIP_64 = 64, 38 | MSR_64 = 65, 39 | LR_64 = 67, 40 | CTR_64 = 68, 41 | XER_64 = 69, 42 | #endif 43 | #ifdef TARGET_PPC32 44 | R_0_32 = 0, 45 | R_1_32 = 1, 46 | R_2_32 = 2, 47 | R_3_32 = 3, 48 | R_4_32 = 4, 49 | R_5_32 = 5, 50 | R_6_32 = 6, 51 | R_7_32 = 7, 52 | R_8_32 = 8, 53 | R_9_32 = 9, 54 | R_10_32 = 10, 55 | R_11_32 = 11, 56 | R_12_32 = 12, 57 | R_13_32 = 13, 58 | R_14_32 = 14, 59 | R_15_32 = 15, 60 | R_16_32 = 16, 61 | R_17_32 = 17, 62 | R_18_32 = 18, 63 | R_19_32 = 19, 64 | R_20_32 = 20, 65 | R_21_32 = 21, 66 | R_22_32 = 22, 67 | R_23_32 = 23, 68 | R_24_32 = 24, 69 | R_25_32 = 25, 70 | R_26_32 = 26, 71 | R_27_32 = 27, 72 | R_28_32 = 28, 73 | R_29_32 = 29, 74 | R_30_32 = 30, 75 | R_31_32 = 31, 76 | NIP_32 = 64, 77 | MSR_32 = 65, 78 | LR_32 = 67, 79 | CTR_32 = 68, 80 | XER_32 = 69, 81 | #endif 82 | } Registers; 83 | -------------------------------------------------------------------------------- /arch/ppc/helper_regs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PowerPC emulation special registers manipulation helpers for qemu. 3 | * 4 | * Copyright (c) 2003-2007 Jocelyn Mayer 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | /* Swap temporary saved registers with GPRs */ 23 | static inline void hreg_swap_gpr_tgpr(CPUState *env) 24 | { 25 | target_ulong tmp; 26 | 27 | tmp = env->gpr[0]; 28 | env->gpr[0] = env->tgpr[0]; 29 | env->tgpr[0] = tmp; 30 | tmp = env->gpr[1]; 31 | env->gpr[1] = env->tgpr[1]; 32 | env->tgpr[1] = tmp; 33 | tmp = env->gpr[2]; 34 | env->gpr[2] = env->tgpr[2]; 35 | env->tgpr[2] = tmp; 36 | tmp = env->gpr[3]; 37 | env->gpr[3] = env->tgpr[3]; 38 | env->tgpr[3] = tmp; 39 | } 40 | 41 | static inline void hreg_compute_mem_idx(CPUState *env) 42 | { 43 | /* Precompute MMU index */ 44 | if(msr_pr == 0 && msr_hv != 0) { 45 | env->mmu_idx = 2; 46 | } else { 47 | env->mmu_idx = 1 - msr_pr; 48 | } 49 | } 50 | 51 | static inline void hreg_compute_hflags(CPUState *env) 52 | { 53 | target_ulong hflags_mask; 54 | 55 | /* We 'forget' FE0 & FE1: we'll never generate imprecise exceptions */ 56 | hflags_mask = (1 << MSR_VR) | (1 << MSR_AP) | (1 << MSR_SA) | (1 << MSR_PR) | (1 << MSR_FP) | (1 << MSR_SE) | (1 << MSR_BE) | 57 | (1 << MSR_LE); 58 | hflags_mask |= (1ULL << MSR_CM) | (1ULL << MSR_SF) | MSR_HVB; 59 | hreg_compute_mem_idx(env); 60 | env->hflags = env->msr & hflags_mask; 61 | /* Merge with hflags coming from other registers */ 62 | env->hflags |= env->hflags_nmsr; 63 | } 64 | 65 | static inline int hreg_store_msr(CPUState *env, target_ulong value, int alter_hv) 66 | { 67 | int excp; 68 | 69 | excp = 0; 70 | value &= env->msr_mask; 71 | if(!alter_hv) { 72 | /* mtmsr cannot alter the hypervisor state */ 73 | value &= ~MSR_HVB; 74 | value |= env->msr & MSR_HVB; 75 | } 76 | if(((value >> MSR_IR) & 1) != msr_ir || ((value >> MSR_DR) & 1) != msr_dr) { 77 | /* Flush all tlb when changing translation mode */ 78 | tlb_flush(env, 1, true); 79 | excp = POWERPC_EXCP_NONE; 80 | set_interrupt_pending(env, CPU_INTERRUPT_EXITTB); 81 | } 82 | if(unlikely((env->flags & POWERPC_FLAG_TGPR) && ((value ^ env->msr) & (1 << MSR_TGPR)))) { 83 | /* Swap temporary saved registers with GPRs */ 84 | hreg_swap_gpr_tgpr(env); 85 | } 86 | if(unlikely((value >> MSR_EP) & 1) != msr_ep) { 87 | /* Change the exception prefix on PowerPC 601 */ 88 | env->excp_prefix = ((value >> MSR_EP) & 1) * 0xFFF00000; 89 | } 90 | env->msr = value; 91 | hreg_compute_hflags(env); 92 | if(unlikely(msr_pow == 1)) { 93 | if((*env->check_pow)(env)) { 94 | env->wfi = 1; 95 | excp = EXCP_WFI; 96 | } 97 | } 98 | 99 | return excp; 100 | } 101 | -------------------------------------------------------------------------------- /arch/ppc/mfrom_table.inc: -------------------------------------------------------------------------------- 1 | static const uint8_t mfrom_ROM_table[602] = 2 | { 3 | 77, 77, 76, 76, 75, 75, 74, 74, 73, 73, 72, 72, 71, 71, 70, 70, 69, 69, 68, 68, 68, 67, 67, 66, 66, 4 | 65, 65, 64, 64, 64, 63, 63, 62, 62, 61, 61, 61, 60, 60, 59, 59, 58, 58, 58, 57, 57, 56, 56, 56, 55, 5 | 55, 54, 54, 54, 53, 53, 53, 52, 52, 51, 51, 51, 50, 50, 50, 49, 49, 49, 48, 48, 47, 47, 47, 46, 46, 6 | 46, 45, 45, 45, 44, 44, 44, 43, 43, 43, 42, 42, 42, 42, 41, 41, 41, 40, 40, 40, 39, 39, 39, 39, 38, 7 | 38, 38, 37, 37, 37, 37, 36, 36, 36, 35, 35, 35, 35, 34, 34, 34, 34, 33, 33, 33, 33, 32, 32, 32, 32, 8 | 31, 31, 31, 31, 30, 30, 30, 30, 29, 29, 29, 29, 28, 28, 28, 28, 28, 27, 27, 27, 27, 26, 26, 26, 26, 9 | 26, 25, 25, 25, 25, 25, 24, 24, 24, 24, 24, 23, 23, 23, 23, 23, 23, 22, 22, 22, 22, 22, 21, 21, 21, 10 | 21, 21, 21, 20, 20, 20, 20, 20, 20, 19, 19, 19, 19, 19, 19, 19, 18, 18, 18, 18, 18, 18, 17, 17, 17, 11 | 17, 17, 17, 17, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 12 | 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 13 | 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 14 | 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 15 | 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 16 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 17 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 18 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 19 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 20 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 22 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 24 | 1, 1, 1, 1, 0, 25 | }; 26 | -------------------------------------------------------------------------------- /arch/riscv/arch_callbacks.c: -------------------------------------------------------------------------------- 1 | /* 2 | * RISC-V callbacks 3 | * 4 | * Copyright (c) Antmicro 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, see . 18 | */ 19 | #include "callbacks.h" 20 | #include "arch_callbacks.h" 21 | 22 | DEFAULT_INT_HANDLER1(uint64_t tlib_get_cpu_time, void) 23 | DEFAULT_INT_HANDLER2(int32_t tlib_handle_custom_instruction, uint64_t id, uint64_t opcode) 24 | DEFAULT_VOID_HANDLER2(void tlib_handle_post_opcode_execution_hook, uint32_t id, uint64_t pc) 25 | DEFAULT_VOID_HANDLER1(void tlib_mip_changed, uint64_t value) 26 | DEFAULT_INT_HANDLER1(uint64_t tlib_read_csr, uint64_t csr) 27 | DEFAULT_VOID_HANDLER2(void tlib_write_csr, uint64_t csr, uint64_t value) 28 | DEFAULT_VOID_HANDLER2(void tlib_handle_post_gpr_access_hook, uint32_t register_index, uint32_t is_write) 29 | DEFAULT_VOID_HANDLER1(void tlib_clic_clear_edge_interrupt, void) 30 | DEFAULT_VOID_HANDLER1(void tlib_clic_acknowledge_interrupt, void) 31 | -------------------------------------------------------------------------------- /arch/riscv/arch_callbacks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | uint64_t tlib_get_cpu_time(); 6 | 7 | uint64_t tlib_read_csr(uint64_t csr); 8 | void tlib_write_csr(uint64_t csr, uint64_t value); 9 | void tlib_mip_changed(uint64_t value); 10 | 11 | int32_t tlib_handle_custom_instruction(uint64_t id, uint64_t opcode); 12 | void tlib_handle_post_opcode_execution_hook(uint32_t id, uint64_t pc); 13 | void tlib_handle_post_gpr_access_hook(uint32_t register_index, uint32_t isWrite); 14 | void tlib_clic_clear_edge_interrupt(void); 15 | void tlib_clic_acknowledge_interrupt(void); 16 | -------------------------------------------------------------------------------- /arch/riscv/arch_exports.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | void tlib_allow_feature(uint32_t feature_bit); 6 | void tlib_allow_additional_feature(uint32_t feature_bit); 7 | 8 | uint32_t tlib_is_feature_enabled(uint32_t feature_bit); 9 | 10 | uint32_t tlib_is_feature_allowed(uint32_t feature_bit); 11 | 12 | void tlib_set_privilege_architecture(int32_t privilege_architecture); 13 | 14 | void tlib_set_nmi_vector(uint64_t nmi_adress, uint32_t nmi_lenght); 15 | 16 | void tlib_set_nmi(int32_t nmi, int32_t state, uint64_t mcause); 17 | 18 | void tlib_allow_unaligned_accesses(int32_t allowed); 19 | 20 | uint32_t tlib_set_vlen(uint32_t vlen); 21 | uint32_t tlib_set_elen(uint32_t elen); 22 | void tlib_set_pmpaddr_bits(uint32_t number_of_bits); 23 | 24 | uint64_t tlib_get_vector(uint32_t regn, uint32_t idx); 25 | void tlib_set_vector(uint32_t regn, uint32_t idx, uint64_t value); 26 | 27 | uint32_t tlib_get_whole_vector(uint32_t regn, uint8_t *bytes); 28 | uint32_t tlib_set_whole_vector(uint32_t regn, uint8_t *bytes); 29 | uint32_t tlib_install_post_opcode_execution_hook(uint64_t mask, uint64_t value); 30 | void tlib_enable_post_opcode_execution_hooks(uint32_t value); 31 | void tlib_enable_post_gpr_access_hooks(uint32_t value); 32 | void tlib_enable_post_gpr_access_hook_on(uint32_t register_index, uint32_t value); 33 | void tlib_set_napot_grain(uint32_t minimal_napot_in_bytes); 34 | -------------------------------------------------------------------------------- /arch/riscv/pmp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Physical Memory Protection 3 | * 4 | * Author: Daire McNamara, daire.mcnamara@emdalo.com 5 | * Ivan Griffin, ivan.griffin@emdalo.com 6 | * 7 | * This provides a RISC-V Physical Memory Protection interface 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in 17 | * all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | * THE SOFTWARE. 26 | */ 27 | 28 | #pragma once 29 | 30 | typedef enum { PMP_READ = 1 << 0, PMP_WRITE = 1 << 1, PMP_EXEC = 1 << 2, PMP_LOCK = 1 << 7 } pmp_priv_t; 31 | 32 | typedef enum { 33 | PMP_AMATCH_OFF, /* Null (off) */ 34 | PMP_AMATCH_TOR, /* Top of Range */ 35 | PMP_AMATCH_NA4, /* Naturally aligned four-byte region */ 36 | PMP_AMATCH_NAPOT /* Naturally aligned power-of-two region */ 37 | } pmp_am_t; 38 | 39 | typedef struct { 40 | target_ulong addr_reg; 41 | uint8_t cfg_reg; 42 | } pmp_entry_t; 43 | 44 | typedef struct { 45 | target_ulong sa; 46 | target_ulong ea; 47 | } pmp_addr_t; 48 | 49 | typedef struct { 50 | pmp_entry_t pmp[MAX_RISCV_PMPS]; 51 | pmp_addr_t addr[MAX_RISCV_PMPS]; 52 | uint32_t num_rules; 53 | } pmp_table_t; 54 | 55 | void pmpcfg_csr_write(CPUState *env, uint32_t reg_index, target_ulong val); 56 | target_ulong pmpcfg_csr_read(CPUState *env, uint32_t reg_index); 57 | void pmpaddr_csr_write(CPUState *env, uint32_t addr_index, target_ulong val); 58 | target_ulong pmpaddr_csr_read(CPUState *env, uint32_t addr_index); 59 | int pmp_get_access(CPUState *env, target_ulong addr, target_ulong size, int access_type); 60 | int pmp_find_overlapping(CPUState *env, target_ulong addr, target_ulong size, int starting_index); 61 | bool pmp_is_any_region_locked(CPUState *env); 62 | -------------------------------------------------------------------------------- /arch/sparc/arch_callbacks.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPARC callbacks. 3 | * 4 | * Copyright (c) Antmicro 5 | * Copyright (c) Realtime Embedded 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, see . 19 | */ 20 | #include "callbacks.h" 21 | #include "arch_callbacks.h" 22 | 23 | DEFAULT_INT_HANDLER1(int32_t tlib_find_best_interrupt, void) 24 | 25 | DEFAULT_VOID_HANDLER1(void tlib_acknowledge_interrupt, int32_t number) 26 | 27 | DEFAULT_VOID_HANDLER1(void tlib_on_cpu_halted, void) 28 | 29 | DEFAULT_VOID_HANDLER1(void tlib_on_cpu_power_down, void) 30 | -------------------------------------------------------------------------------- /arch/sparc/arch_callbacks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | int32_t tlib_find_best_interrupt(void); 6 | void tlib_acknowledge_interrupt(int32_t number); 7 | void tlib_on_cpu_halted(void); 8 | void tlib_on_cpu_power_down(void); 9 | -------------------------------------------------------------------------------- /arch/sparc/arch_exports.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPARC interface functions. 3 | * 4 | * Copyright (c) Antmicro 5 | * Copyright (c) Realtime Embedded 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, see . 19 | */ 20 | #include 21 | #include "cpu.h" 22 | #include "unwind.h" 23 | 24 | /* Add CPU slot number info to ASR17 register, */ 25 | /* bit field [31:28] is for processor index */ 26 | void tlib_set_slot(uint32_t slot) 27 | { 28 | unsigned int asr17; 29 | /* Default value is set for core 0, */ 30 | /* only update ASR17 for slave cores 1-15 */ 31 | if((slot > 0) && slot < 16) { 32 | asr17 = (unsigned int)((cpu->asr[1] & 0xFFFFFFF) + ((slot << 28) & 0xF0000000)); 33 | cpu->asr[1] = asr17; 34 | } 35 | } 36 | 37 | EXC_VOID_1(tlib_set_slot, uint32_t, slot) 38 | 39 | void tlib_set_entry_point(uint32_t entry_point) 40 | { 41 | cpu->pc = entry_point; 42 | cpu->npc = cpu->pc + 4; 43 | } 44 | 45 | EXC_VOID_1(tlib_set_entry_point, uint32_t, entry_point) 46 | 47 | void tlib_clear_wfi() 48 | { 49 | cpu->wfi = 0; 50 | } 51 | 52 | EXC_VOID_0(tlib_clear_wfi) 53 | 54 | void tlib_set_wfi() 55 | { 56 | cpu->wfi = 1; 57 | } 58 | 59 | EXC_VOID_0(tlib_set_wfi) 60 | -------------------------------------------------------------------------------- /arch/sparc/arch_exports.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | void tlib_set_slot(uint32_t slot); 6 | 7 | void tlib_set_entry_point(uint32_t entry_point); 8 | 9 | void tlib_clear_wfi(void); 10 | 11 | void tlib_set_wfi(void); 12 | -------------------------------------------------------------------------------- /arch/sparc/cpu_registers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPARC registers interface. 3 | * 4 | * Copyright (c) Antmicro 5 | * Copyright (c) Realtime Embedded 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, see . 19 | */ 20 | #include 21 | 22 | #include "cpu.h" 23 | #include "cpu_registers.h" 24 | 25 | uint32_t *get_reg_pointer_32(int reg) 26 | { 27 | switch(reg) { 28 | case R_0_32 ... R_7_32: /* R0-R7 aka Global0-7 */ 29 | return &(cpu->gregs[reg]); 30 | case R_8_32 ... R_31_32: /* R8 to 31 : Out0-7, Local0-7, In0-7 */ 31 | return &(cpu->regwptr[reg - R_8_32]); 32 | case PSR_32: 33 | /* Compute PSR before exposing state. */ 34 | if(cpu->cc_op != CC_OP_FLAGS) { 35 | cpu_get_psr(cpu); 36 | } 37 | return &(cpu->psr); 38 | case TBR_32: 39 | return &(cpu->tbr); 40 | case Y_32: 41 | return &(cpu->y); 42 | case PC_32: 43 | return &(cpu->pc); 44 | case NPC_32: 45 | return &(cpu->npc); 46 | case ASR_16_32 ... ASR_31_32: 47 | return &(cpu->asr[reg - ASR_16_32]); 48 | case WIM_32: 49 | return &(cpu->wim); 50 | case FSR_32: 51 | return &(cpu->fsr); 52 | case CSR_32: 53 | return &(cpu->csr); 54 | default: 55 | return NULL; 56 | } 57 | } 58 | 59 | CPU_REGISTER_ACCESSOR(32) 60 | -------------------------------------------------------------------------------- /arch/sparc/cpu_registers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cpu-defs.h" 4 | 5 | typedef enum { 6 | R_0_32 = 0, 7 | R_1_32 = 1, 8 | R_2_32 = 2, 9 | R_3_32 = 3, 10 | R_4_32 = 4, 11 | R_5_32 = 5, 12 | R_6_32 = 6, 13 | R_7_32 = 7, 14 | R_8_32 = 8, 15 | R_9_32 = 9, 16 | R_10_32 = 10, 17 | R_11_32 = 11, 18 | R_12_32 = 12, 19 | R_13_32 = 13, 20 | R_14_32 = 14, 21 | R_15_32 = 15, 22 | R_16_32 = 16, 23 | R_17_32 = 17, 24 | R_18_32 = 18, 25 | R_19_32 = 19, 26 | R_20_32 = 20, 27 | R_21_32 = 21, 28 | R_22_32 = 22, 29 | R_23_32 = 23, 30 | R_24_32 = 24, 31 | R_25_32 = 25, 32 | R_26_32 = 26, 33 | R_27_32 = 27, 34 | R_28_32 = 28, 35 | R_29_32 = 29, 36 | R_30_32 = 30, 37 | R_31_32 = 31, 38 | ASR_16_32 = 37, 39 | ASR_17_32 = 38, 40 | ASR_18_32 = 39, 41 | ASR_19_32 = 40, 42 | ASR_20_32 = 41, 43 | ASR_21_32 = 42, 44 | ASR_22_32 = 43, 45 | ASR_23_32 = 44, 46 | ASR_24_32 = 45, 47 | ASR_25_32 = 46, 48 | ASR_26_32 = 47, 49 | ASR_27_32 = 48, 50 | ASR_28_32 = 49, 51 | ASR_29_32 = 50, 52 | ASR_30_32 = 51, 53 | ASR_31_32 = 52, 54 | Y_32 = 64, 55 | PSR_32 = 65, 56 | WIM_32 = 66, 57 | TBR_32 = 67, 58 | PC_32 = 68, 59 | NPC_32 = 69, 60 | FSR_32 = 70, 61 | CSR_32 = 71 62 | } Registers; 63 | 64 | // Frame and stack pointers correspond to R30 and R14 respectively 65 | #define FP_32 30 66 | #define SP_32 14 67 | 68 | #define RA R_7_32 69 | #define RETURN_ADDRESS_OFFSET 8 70 | -------------------------------------------------------------------------------- /arch/sparc/helper.h: -------------------------------------------------------------------------------- 1 | #include "def-helper.h" 2 | 3 | DEF_HELPER_0(power_down, void) 4 | DEF_HELPER_0(rett, void) 5 | DEF_HELPER_1(wrpsr, void, tl) 6 | DEF_HELPER_0(rdpsr, tl) 7 | DEF_HELPER_2(check_align, void, tl, i32) 8 | DEF_HELPER_0(debug, void) 9 | DEF_HELPER_0(save, void) 10 | DEF_HELPER_0(restore, void) 11 | DEF_HELPER_2(udiv, tl, tl, tl) 12 | DEF_HELPER_2(udiv_cc, tl, tl, tl) 13 | DEF_HELPER_2(sdiv, tl, tl, tl) 14 | DEF_HELPER_2(sdiv_cc, tl, tl, tl) 15 | DEF_HELPER_2(stdf, void, tl, int) 16 | DEF_HELPER_2(lddf, void, tl, int) 17 | DEF_HELPER_2(ldqf, void, tl, int) 18 | DEF_HELPER_2(stqf, void, tl, int) 19 | DEF_HELPER_4(ld_asi, i64, tl, int, int, int) 20 | DEF_HELPER_4(st_asi, void, tl, i64, int, int) 21 | DEF_HELPER_4(cas_asi, tl, tl, tl, tl, i32) 22 | DEF_HELPER_1(ldfsr, void, i32) 23 | DEF_HELPER_0(check_ieee_exceptions, void) 24 | DEF_HELPER_0(clear_float_exceptions, void) 25 | DEF_HELPER_1(fabss, f32, f32) 26 | DEF_HELPER_1(fsqrts, f32, f32) 27 | DEF_HELPER_0(fsqrtd, void) 28 | DEF_HELPER_2(fcmps, void, f32, f32) 29 | DEF_HELPER_0(fcmpd, void) 30 | DEF_HELPER_2(fcmpes, void, f32, f32) 31 | DEF_HELPER_0(fcmped, void) 32 | DEF_HELPER_0(fsqrtq, void) 33 | DEF_HELPER_0(fcmpq, void) 34 | DEF_HELPER_0(fcmpeq, void) 35 | DEF_HELPER_1(raise_exception, void, int) 36 | DEF_HELPER_0(shutdown, void) 37 | DEF_HELPER_1(ldstub, tl, i32) 38 | DEF_HELPER_2(swap, tl, tl, i32) 39 | #define F_HELPER_0_0(name) DEF_HELPER_0(f##name, void) 40 | #define F_HELPER_DQ_0_0(name) \ 41 | F_HELPER_0_0(name##d); \ 42 | F_HELPER_0_0(name##q) 43 | 44 | F_HELPER_DQ_0_0(add); 45 | F_HELPER_DQ_0_0(sub); 46 | F_HELPER_DQ_0_0(mul); 47 | F_HELPER_DQ_0_0(div); 48 | 49 | DEF_HELPER_2(fadds, f32, f32, f32) 50 | DEF_HELPER_2(fsubs, f32, f32, f32) 51 | DEF_HELPER_2(fmuls, f32, f32, f32) 52 | DEF_HELPER_2(fdivs, f32, f32, f32) 53 | 54 | DEF_HELPER_2(fsmuld, void, f32, f32) 55 | F_HELPER_0_0(dmulq); 56 | 57 | DEF_HELPER_1(fnegs, f32, f32) 58 | DEF_HELPER_1(fitod, void, s32) 59 | DEF_HELPER_1(fitoq, void, s32) 60 | 61 | DEF_HELPER_1(fitos, f32, s32) 62 | 63 | DEF_HELPER_0(fdtos, f32) 64 | DEF_HELPER_1(fstod, void, f32) 65 | DEF_HELPER_0(fqtos, f32) 66 | DEF_HELPER_1(fstoq, void, f32) 67 | F_HELPER_0_0(qtod); 68 | F_HELPER_0_0(dtoq); 69 | DEF_HELPER_1(fstoi, s32, f32) 70 | DEF_HELPER_0(fdtoi, s32) 71 | DEF_HELPER_0(fqtoi, s32) 72 | #undef F_HELPER_0_0 73 | #undef F_HELPER_DQ_0_0 74 | #undef VIS_HELPER 75 | #undef VIS_CMPHELPER 76 | DEF_HELPER_0(compute_psr, void); 77 | DEF_HELPER_0(compute_C_icc, i32); 78 | #include "def-helper.h" 79 | -------------------------------------------------------------------------------- /arch/xtensa/arch_callbacks.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Xtensa callbacks 3 | * 4 | * Copyright (c) Antmicro 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, see . 18 | */ 19 | #include "callbacks.h" 20 | #include "arch_callbacks.h" 21 | 22 | DEFAULT_VOID_HANDLER1(void tlib_do_semihosting, void) 23 | DEFAULT_INT_HANDLER1(uint64_t tlib_get_cpu_time, void) 24 | DEFAULT_VOID_HANDLER2(void tlib_timer_mod, uint32_t id, uint64_t value) 25 | -------------------------------------------------------------------------------- /arch/xtensa/arch_callbacks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | void tlib_do_semihosting(); 6 | uint64_t tlib_get_cpu_time(); 7 | void tlib_timer_mod(uint32_t id, uint64_t value); 8 | -------------------------------------------------------------------------------- /arch/xtensa/arch_exports.c: -------------------------------------------------------------------------------- 1 | #include "arch_exports.h" 2 | #include "cpu.h" 3 | #include "unwind.h" 4 | 5 | void tlib_set_irq_pending_bit(uint32_t irq, uint32_t value) 6 | { 7 | xtensa_cpu_set_irq_pending_bit(env, irq, value); 8 | } 9 | 10 | EXC_VOID_2(tlib_set_irq_pending_bit, uint32_t, irq, uint32_t, value) 11 | 12 | void tlib_set_single_step(uint32_t enabled) 13 | { 14 | cpu->singlestep_enabled = enabled; 15 | } 16 | 17 | EXC_VOID_1(tlib_set_single_step, uint32_t, enabled) 18 | -------------------------------------------------------------------------------- /arch/xtensa/arch_exports.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | void tlib_set_irq_pending_bit(uint32_t irq, uint32_t value); 6 | void tlib_update_execution_mode(uint32_t mode); 7 | -------------------------------------------------------------------------------- /arch/xtensa/core-apollolake.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Intel Corporation. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the Open Source and Linux Lab nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "osdep.h" 29 | #include "cpu.h" 30 | 31 | #include "core-apollolake/core-isa.h" 32 | #include "overlay_tool.h" 33 | 34 | #include "core-apollolake/xtensa-modules.c.inc" 35 | 36 | XtensaConfig apollolake 37 | __attribute__((unused)) = { .name = "apollolake", .isa_internal = &xtensa_modules, .clock_freq_khz = 5000, DEFAULT_SECTIONS }; 38 | -------------------------------------------------------------------------------- /arch/xtensa/core-baytrail.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Intel Corporation. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the Open Source and Linux Lab nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "osdep.h" 29 | #include "cpu.h" 30 | 31 | #include "core-baytrail/core-isa.h" 32 | #include "overlay_tool.h" 33 | 34 | #include "core-baytrail/xtensa-modules.c.inc" 35 | 36 | XtensaConfig baytrail 37 | __attribute__((unused)) = { .name = "baytrail", .isa_internal = &xtensa_modules, .clock_freq_khz = 5000, DEFAULT_SECTIONS }; 38 | -------------------------------------------------------------------------------- /arch/xtensa/core-cannonlake.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Intel Corporation. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the Open Source and Linux Lab nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "osdep.h" 29 | #include "cpu.h" 30 | 31 | #include "core-cannonlake/core-isa.h" 32 | #include "overlay_tool.h" 33 | 34 | #include "core-cannonlake/xtensa-modules.c.inc" 35 | 36 | XtensaConfig cannonlake 37 | __attribute__((unused)) = { .name = "cannonlake", .isa_internal = &xtensa_modules, .clock_freq_khz = 5000, DEFAULT_SECTIONS }; 38 | -------------------------------------------------------------------------------- /arch/xtensa/core-dc233c.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012, Max Filippov, Open Source and Linux Lab. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the Open Source and Linux Lab nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "osdep.h" 29 | #include "cpu.h" 30 | 31 | #include "core-dc233c/core-isa.h" 32 | #include "overlay_tool.h" 33 | 34 | #define xtensa_modules xtensa_modules_dc233c 35 | #include "core-dc233c/xtensa-modules.c.inc" 36 | 37 | XtensaConfig dc233c 38 | __attribute__((unused)) = { .name = "dc233c", .isa_internal = &xtensa_modules, .clock_freq_khz = 10000, DEFAULT_SECTIONS }; 39 | -------------------------------------------------------------------------------- /arch/xtensa/core-de212.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Max Filippov, Open Source and Linux Lab. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the Open Source and Linux Lab nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "osdep.h" 29 | #include "cpu.h" 30 | 31 | #include "core-de212/core-isa.h" 32 | #include "overlay_tool.h" 33 | 34 | #define xtensa_modules xtensa_modules_de212 35 | #include "core-de212/xtensa-modules.c.inc" 36 | 37 | XtensaConfig de212 38 | __attribute__((unused)) = { .name = "de212", .isa_internal = &xtensa_modules, .clock_freq_khz = 40000, DEFAULT_SECTIONS }; 39 | -------------------------------------------------------------------------------- /arch/xtensa/core-de233_fpu.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Max Filippov, Open Source and Linux Lab. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the Open Source and Linux Lab nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "osdep.h" 29 | #include "cpu.h" 30 | 31 | #include "core-de233_fpu/core-isa.h" 32 | #include "core-de233_fpu/core-matmap.h" 33 | #include "overlay_tool.h" 34 | 35 | #define xtensa_modules xtensa_modules_de233_fpu 36 | #include "core-de233_fpu/xtensa-modules.c.inc" 37 | 38 | XtensaConfig de233_fpu __attribute__((unused)) = { 39 | .name = "de233_fpu", 40 | .isa_internal = &xtensa_modules, 41 | .clock_freq_khz = 40000, 42 | .opcode_translators = 43 | (const XtensaOpcodeTranslators *[]) { 44 | &xtensa_core_opcodes, 45 | &xtensa_fpu_opcodes, 46 | NULL, }, 47 | DEFAULT_SECTIONS 48 | }; 49 | -------------------------------------------------------------------------------- /arch/xtensa/core-dsp3400.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Max Filippov, Open Source and Linux Lab. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the Open Source and Linux Lab nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "osdep.h" 29 | #include "cpu.h" 30 | 31 | #include "core-dsp3400/core-isa.h" 32 | #include "core-dsp3400/core-matmap.h" 33 | #include "overlay_tool.h" 34 | 35 | #define xtensa_modules xtensa_modules_dsp3400 36 | #include "core-dsp3400/xtensa-modules.c.inc" 37 | 38 | XtensaConfig dsp3400 __attribute__((unused)) = { 39 | .name = "dsp3400", 40 | .isa_internal = &xtensa_modules, 41 | .clock_freq_khz = 40000, 42 | .opcode_translators = 43 | (const XtensaOpcodeTranslators *[]) { 44 | &xtensa_core_opcodes, 45 | &xtensa_fpu2000_opcodes, 46 | NULL, }, 47 | DEFAULT_SECTIONS 48 | }; 49 | -------------------------------------------------------------------------------- /arch/xtensa/core-esp32.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Max Filippov, Open Source and Linux Lab. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the Open Source and Linux Lab nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "osdep.h" 29 | #include "cpu.h" 30 | 31 | #include "core-esp32/core-isa.h" 32 | #include "overlay_tool.h" 33 | 34 | #define xtensa_modules xtensa_modules_esp32 35 | #include "core-esp32/xtensa-modules.c.inc" 36 | 37 | XtensaConfig esp32 38 | __attribute__((unused)) = { .name = "esp32", .isa_internal = &xtensa_modules, .clock_freq_khz = 140000, DEFAULT_SECTIONS }; 39 | -------------------------------------------------------------------------------- /arch/xtensa/core-esp32s2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Max Filippov, Open Source and Linux Lab. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the Open Source and Linux Lab nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "osdep.h" 29 | #include "cpu.h" 30 | 31 | #include "core-esp32s2/core-isa.h" 32 | #include "overlay_tool.h" 33 | 34 | #define xtensa_modules xtensa_modules_esp32s2 35 | 36 | // use the common implementation of ESP32 37 | #include "core-esp32/xtensa-modules.c.inc" 38 | 39 | XtensaConfig esp32s2 40 | __attribute__((unused)) = { .name = "esp32s2", .isa_internal = &xtensa_modules, .clock_freq_khz = 140000, DEFAULT_SECTIONS }; 41 | -------------------------------------------------------------------------------- /arch/xtensa/core-esp32s3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Max Filippov, Open Source and Linux Lab. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the Open Source and Linux Lab nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "osdep.h" 29 | #include "cpu.h" 30 | 31 | #include "core-esp32s3/core-isa.h" 32 | #include "overlay_tool.h" 33 | 34 | #define xtensa_modules xtensa_modules_esp32s3 35 | 36 | // use the common implementation of ESP32 37 | #include "core-esp32/xtensa-modules.c.inc" 38 | 39 | XtensaConfig esp32s3 40 | __attribute__((unused)) = { .name = "esp32s3", .isa_internal = &xtensa_modules, .clock_freq_khz = 140000, DEFAULT_SECTIONS }; 41 | -------------------------------------------------------------------------------- /arch/xtensa/core-haswell.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Intel Corporation. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the Open Source and Linux Lab nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "osdep.h" 29 | #include "cpu.h" 30 | 31 | #include "core-haswell/core-isa.h" 32 | #include "overlay_tool.h" 33 | 34 | #include "core-haswell/xtensa-modules.c.inc" 35 | 36 | XtensaConfig haswell 37 | __attribute__((unused)) = { .name = "haswell", .isa_internal = &xtensa_modules, .clock_freq_khz = 5000, DEFAULT_SECTIONS }; 38 | -------------------------------------------------------------------------------- /arch/xtensa/core-icelake.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Intel Corporation. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the Open Source and Linux Lab nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "osdep.h" 29 | #include "cpu.h" 30 | 31 | #include "core-icelake/core-isa.h" 32 | #include "overlay_tool.h" 33 | #include "core-icelake/xtensa-modules.c.inc" 34 | 35 | XtensaConfig icelake 36 | __attribute__((unused)) = { .name = "icelake", .isa_internal = &xtensa_modules, .clock_freq_khz = 5000, DEFAULT_SECTIONS }; 37 | -------------------------------------------------------------------------------- /arch/xtensa/core-imx8.c: -------------------------------------------------------------------------------- 1 | #include "osdep.h" 2 | #include "cpu.h" 3 | 4 | #include "core-imx8/core-isa.h" 5 | #include "overlay_tool.h" 6 | 7 | #define xtensa_modules xtensa_modules_imx8 8 | #include "core-imx8/xtensa-modules.c.inc" 9 | 10 | XtensaConfig imx8 11 | __attribute__((unused)) = { .name = "imx8", .isa_internal = &xtensa_modules, .clock_freq_khz = 40000, DEFAULT_SECTIONS }; 12 | -------------------------------------------------------------------------------- /arch/xtensa/core-imx8m.c: -------------------------------------------------------------------------------- 1 | #include "osdep.h" 2 | #include "cpu.h" 3 | 4 | #include "core-imx8m/core-isa.h" 5 | #include "overlay_tool.h" 6 | 7 | #define xtensa_modules xtensa_modules_imx8m 8 | #include "core-imx8m/xtensa-modules.c.inc" 9 | 10 | XtensaConfig imx8m 11 | __attribute__((unused)) = { .name = "imx8m", .isa_internal = &xtensa_modules, .clock_freq_khz = 40000, DEFAULT_SECTIONS }; 12 | -------------------------------------------------------------------------------- /arch/xtensa/core-sample_controller.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Max Filippov, Open Source and Linux Lab. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the Open Source and Linux Lab nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "osdep.h" 29 | #include "cpu.h" 30 | 31 | #include "core-sample_controller/core-isa.h" 32 | #include "overlay_tool.h" 33 | 34 | #define xtensa_modules xtensa_modules_sample_controller 35 | #include "core-sample_controller/xtensa-modules.c.inc" 36 | 37 | XtensaConfig sample_controller __attribute__(( 38 | unused)) = { .name = "sample_controller", .isa_internal = &xtensa_modules, .clock_freq_khz = 10000, DEFAULT_SECTIONS }; 39 | -------------------------------------------------------------------------------- /arch/xtensa/core-test_kc705_be.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018, Max Filippov, Open Source and Linux Lab. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the Open Source and Linux Lab nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "osdep.h" 29 | #include "cpu.h" 30 | 31 | #include "core-test_kc705_be/core-isa.h" 32 | #include "overlay_tool.h" 33 | 34 | #define xtensa_modules xtensa_modules_test_kc705_be 35 | #include "core-test_kc705_be/xtensa-modules.c.inc" 36 | 37 | XtensaConfig test_kc705_be __attribute__(( 38 | unused)) = { .name = "test_kc705_be", .isa_internal = &xtensa_modules, .clock_freq_khz = 40000, DEFAULT_SECTIONS }; 39 | -------------------------------------------------------------------------------- /arch/xtensa/core-test_mmuhifi_c3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Max Filippov, Open Source and Linux Lab. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the Open Source and Linux Lab nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "osdep.h" 29 | #include "cpu.h" 30 | 31 | #include "core-test_mmuhifi_c3/core-isa.h" 32 | #include "overlay_tool.h" 33 | 34 | #define xtensa_modules xtensa_modules_test_mmuhifi_c3 35 | #include "core-test_mmuhifi_c3/xtensa-modules.c.inc" 36 | 37 | XtensaConfig test_mmuhifi_c3 __attribute__(( 38 | unused)) = { .name = "test_mmuhifi_c3", .isa_internal = &xtensa_modules, .clock_freq_khz = 40000, DEFAULT_SECTIONS }; 39 | -------------------------------------------------------------------------------- /arch/xtensa/core-tigerlake.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, Intel Corporation. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the Open Source and Linux Lab nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "osdep.h" 29 | #include "cpu.h" 30 | 31 | #include "core-tigerlake/core-isa.h" 32 | #include "overlay_tool.h" 33 | 34 | #include "core-tigerlake/xtensa-modules.c.inc" 35 | 36 | XtensaConfig tigerlake 37 | __attribute__((unused)) = { .name = "tigerlake", .isa_internal = &xtensa_modules, .clock_freq_khz = 5000, DEFAULT_SECTIONS }; 38 | -------------------------------------------------------------------------------- /arch/xtensa/cpu.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Xtensa CPU 3 | * 4 | * Copyright (c) 2011, Max Filippov, Open Source and Linux Lab. 5 | * Copyright (c) 2012 SUSE LINUX Products GmbH 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * * Neither the name of the Open Source and Linux Lab nor the 16 | * names of its contributors may be used to endorse or promote products 17 | * derived from this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 23 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include "cpu.h" 32 | #include "osdep.h" 33 | #include "softfloat-2.h" 34 | 35 | static void xtensa_cpu_reset(CPUState *env) 36 | { 37 | /* Reset the CPU_COMMON part */ 38 | int common_offset = offsetof(CPUState, cpu_common_first_field); 39 | memset((char *)env + common_offset, 0, RESET_OFFSET - common_offset); 40 | env->exception_index = -1; 41 | 42 | /* Reset Xtensa-specific parts */ 43 | 44 | bool dfpu = xtensa_option_enabled(env->config, XTENSA_OPTION_DFP_COPROCESSOR); 45 | 46 | env->exception_taken = 0; 47 | env->pc = env->config->exception_vector[EXC_RESET0]; 48 | env->sregs[LITBASE] &= ~1; 49 | env->sregs[PS] = xtensa_option_enabled(env->config, XTENSA_OPTION_INTERRUPT) ? 0x1f : 0x10; 50 | env->pending_irq_level = 0; 51 | env->sregs[VECBASE] = env->config->vecbase; 52 | env->sregs[IBREAKENABLE] = 0; 53 | env->sregs[MEMCTL] = MEMCTL_IL0EN & env->config->memctl_mask; 54 | env->sregs[ATOMCTL] = xtensa_option_enabled(env->config, XTENSA_OPTION_ATOMCTL) ? 0x28 : 0x15; 55 | env->sregs[CONFIGID0] = env->config->configid[0]; 56 | env->sregs[CONFIGID1] = env->config->configid[1]; 57 | env->exclusive_addr = -1; 58 | 59 | reset_mmu(env); 60 | set_no_signaling_nans(!dfpu, &env->fp_status); 61 | set_use_first_nan(!dfpu, &env->fp_status); 62 | } 63 | 64 | void cpu_reset(CPUState *env) 65 | { 66 | xtensa_cpu_reset(env); 67 | } 68 | 69 | static void xtensa_cpu_initfn(CPUState *env, XtensaConfig *config) 70 | { 71 | env->config = config; 72 | 73 | pthread_mutex_init(&env->io_lock, NULL); 74 | } 75 | 76 | int cpu_init(const char *cpu_model) 77 | { 78 | XtensaConfig *config = xtensa_finalize_config(cpu_model); 79 | // Has to be run after 'xtensa_finalize_config' which calls 80 | // 'xtensa_collect_sr_names' required to initialize cpu_SR array. 81 | xtensa_translate_init(); 82 | xtensa_cpu_initfn(cpu, config); 83 | cpu_reset(cpu); 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /arch/xtensa/cpu_registers.h: -------------------------------------------------------------------------------- 1 | #include "cpu-defs.h" 2 | 3 | // REMARK: we use #ifdef/#endif, #ifdef/#endif instead of #ifdef/#else/#endif notation due to the limitation of 4 | // `RegisterEnumParser.cs` 5 | typedef enum { 6 | PC_32 = 0, 7 | AR_0_32 = 1, 8 | AR_1_32 = 2, 9 | AR_2_32 = 3, 10 | AR_3_32 = 4, 11 | AR_4_32 = 5, 12 | AR_5_32 = 6, 13 | AR_6_32 = 7, 14 | AR_7_32 = 8, 15 | AR_8_32 = 9, 16 | AR_9_32 = 10, 17 | AR_10_32 = 11, 18 | AR_11_32 = 12, 19 | AR_12_32 = 13, 20 | AR_13_32 = 14, 21 | AR_14_32 = 15, 22 | AR_15_32 = 16, 23 | AR_16_32 = 17, 24 | AR_17_32 = 18, 25 | AR_18_32 = 19, 26 | AR_19_32 = 20, 27 | AR_20_32 = 21, 28 | AR_21_32 = 22, 29 | AR_22_32 = 23, 30 | AR_23_32 = 24, 31 | AR_24_32 = 25, 32 | AR_25_32 = 26, 33 | AR_26_32 = 27, 34 | AR_27_32 = 28, 35 | AR_28_32 = 29, 36 | AR_29_32 = 30, 37 | AR_30_32 = 31, 38 | AR_31_32 = 32, 39 | SAR_32 = 33, 40 | WINDOWBASE_32 = 34, 41 | WINDOWSTART_32 = 35, 42 | CONFIGID_0_32 = 36, 43 | CONFIGID_1_32 = 37, 44 | PS_32 = 38, 45 | SCOMPARE_1_32 = 39, 46 | EXPSTATE_32 = 40, 47 | MMID_32 = 41, 48 | IBREAKENABLE_32 = 42, 49 | ATOMCTL_32 = 43, 50 | DDR_32 = 44, 51 | IBREAKA_0_32 = 45, 52 | IBREAKA_1_32 = 46, 53 | DBREAKA_0_32 = 47, 54 | DBREAKA_1_32 = 48, 55 | DBREAKC_0_32 = 49, 56 | DBREAKC_1_32 = 50, 57 | EPC_1_32 = 51, 58 | EPC_2_32 = 52, 59 | EPC_3_32 = 53, 60 | EPC_4_32 = 54, 61 | EPC_5_32 = 55, 62 | EPC_6_32 = 56, 63 | EPC_7_32 = 57, 64 | DEPC_32 = 58, 65 | EPS_2_32 = 59, 66 | EPS_3_32 = 60, 67 | EPS_4_32 = 61, 68 | EPS_5_32 = 62, 69 | EPS_6_32 = 63, 70 | EPS_7_32 = 64, 71 | EXCSAVE_1_32 = 65, 72 | EXCSAVE_2_32 = 66, 73 | EXCSAVE_3_32 = 67, 74 | EXCSAVE_4_32 = 68, 75 | EXCSAVE_5_32 = 69, 76 | EXCSAVE_6_32 = 70, 77 | EXCSAVE_7_32 = 71, 78 | INTERRUPT_32 = 72, 79 | INTSET_32 = 73, 80 | INTCLEAR_32 = 74, 81 | INTENABLE_32 = 75, 82 | VECBASE_32 = 76, 83 | EXCCAUSE_32 = 77, 84 | DEBUGCAUSE_32 = 78, 85 | CCOUNT_32 = 79, 86 | PRID_32 = 80, 87 | ICOUNT_32 = 81, 88 | ICOUNTLEVEL_32 = 82, 89 | EXCVADDR_32 = 83, 90 | CCOMPARE_0_32 = 84, 91 | CCOMPARE_1_32 = 85, 92 | CCOMPARE_2_32 = 86, 93 | MISC_0_32 = 87, 94 | MISC_1_32 = 88, 95 | A_0_32 = 89, 96 | A_1_32 = 90, 97 | A_2_32 = 91, 98 | A_3_32 = 92, 99 | A_4_32 = 93, 100 | A_5_32 = 94, 101 | A_6_32 = 95, 102 | A_7_32 = 96, 103 | A_8_32 = 97, 104 | A_9_32 = 98, 105 | A_10_32 = 99, 106 | A_11_32 = 100, 107 | A_12_32 = 101, 108 | A_13_32 = 102, 109 | A_14_32 = 103, 110 | A_15_32 = 104, 111 | PSINTLEVEL_32 = 105, 112 | PSUM_32 = 106, 113 | PSWOE_32 = 107, 114 | PSEXCM_32 = 108, 115 | PSCALLINC_32 = 109, 116 | PSOWB_32 = 110, 117 | } Registers; 118 | -------------------------------------------------------------------------------- /arch/xtensa/dbg_helper.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 - 2019, Max Filippov, Open Source and Linux Lab. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the Open Source and Linux Lab nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include "cpu.h" 29 | #include "osdep.h" 30 | #include "tb-helper.h" 31 | 32 | void HELPER(wsr_ibreakenable)(CPUState *env, uint32_t v) 33 | { 34 | tlib_printf(LOG_LEVEL_WARNING, "Setting watchpoints with IBREAK instructions isn't supported!"); 35 | env->sregs[IBREAKENABLE] = v & ((1 << env->config->nibreak) - 1); 36 | } 37 | 38 | void HELPER(wsr_ibreaka)(CPUState *env, uint32_t i, uint32_t v) 39 | { 40 | tlib_printf(LOG_LEVEL_WARNING, "Setting watchpoints with IBREAK instructions isn't supported!"); 41 | env->sregs[IBREAKA + i] = v; 42 | } 43 | 44 | void HELPER(wsr_dbreaka)(CPUState *env, uint32_t i, uint32_t v) 45 | { 46 | tlib_printf(LOG_LEVEL_WARNING, "Setting watchpoints with DBREAK instructions isn't supported!"); 47 | env->sregs[DBREAKA + i] = v; 48 | } 49 | 50 | void HELPER(wsr_dbreakc)(CPUState *env, uint32_t i, uint32_t v) 51 | { 52 | tlib_printf(LOG_LEVEL_WARNING, "Setting watchpoints with DBREAK instructions isn't supported!"); 53 | env->sregs[DBREAKC + i] = v; 54 | } 55 | -------------------------------------------------------------------------------- /arch/xtensa/helper.h: -------------------------------------------------------------------------------- 1 | #include "def-helper.h" 2 | 3 | DEF_HELPER_2(exception, noreturn, env, i32) 4 | DEF_HELPER_3(exception_cause, noreturn, env, i32, i32) 5 | DEF_HELPER_4(exception_cause_vaddr, noreturn, env, i32, i32, i32) 6 | DEF_HELPER_3(debug_exception, noreturn, env, i32, i32) 7 | 8 | DEF_HELPER_1(sync_windowbase, void, env) 9 | DEF_HELPER_4(entry, void, env, i32, i32, i32) 10 | DEF_HELPER_2(test_ill_retw, void, env, i32) 11 | DEF_HELPER_2(test_underflow_retw, void, env, i32) 12 | DEF_HELPER_2(retw, void, env, i32) 13 | DEF_HELPER_3(window_check, noreturn, env, i32, i32) 14 | DEF_HELPER_1(restore_owb, void, env) 15 | DEF_HELPER_2(movsp, void, env, i32) 16 | DEF_HELPER_1(simcall, void, env) 17 | 18 | DEF_HELPER_3(waiti, void, env, i32, i32) 19 | DEF_HELPER_1(update_ccount, void, env) 20 | DEF_HELPER_2(wsr_ccount, void, env, i32) 21 | DEF_HELPER_2(update_ccompare, void, env, i32) 22 | DEF_HELPER_1(check_interrupts, void, env) 23 | DEF_HELPER_2(intset, void, env, i32) 24 | DEF_HELPER_2(intclear, void, env, i32) 25 | DEF_HELPER_3(check_atomctl, void, env, i32, i32) 26 | DEF_HELPER_4(check_exclusive, void, env, i32, i32, i32) 27 | DEF_HELPER_2(wsr_memctl, void, env, i32) 28 | 29 | DEF_HELPER_2(itlb_hit_test, void, env, i32) 30 | DEF_HELPER_2(wsr_rasid, void, env, i32) 31 | DEF_HELPER_FLAGS_3(rtlb0, TCG_CALL_PURE | TCG_CALL_CONST, i32, env, i32, i32) 32 | DEF_HELPER_FLAGS_3(rtlb1, TCG_CALL_PURE | TCG_CALL_CONST, i32, env, i32, i32) 33 | DEF_HELPER_3(itlb, void, env, i32, i32) 34 | DEF_HELPER_3(ptlb, i32, env, i32, i32) 35 | DEF_HELPER_4(wtlb, void, env, i32, i32, i32) 36 | DEF_HELPER_2(wsr_mpuenb, void, env, i32) 37 | DEF_HELPER_3(wptlb, void, env, i32, i32) 38 | DEF_HELPER_FLAGS_2(rptlb0, TCG_CALL_PURE | TCG_CALL_CONST, i32, env, i32) 39 | DEF_HELPER_FLAGS_2(rptlb1, TCG_CALL_PURE | TCG_CALL_CONST, i32, env, i32) 40 | DEF_HELPER_2(pptlb, i32, env, i32) 41 | 42 | DEF_HELPER_2(wsr_ibreakenable, void, env, i32) 43 | DEF_HELPER_3(wsr_ibreaka, void, env, i32, i32) 44 | DEF_HELPER_3(wsr_dbreaka, void, env, i32, i32) 45 | DEF_HELPER_3(wsr_dbreakc, void, env, i32, i32) 46 | 47 | DEF_HELPER_2(wur_fpu2k_fcr, void, env, i32) 48 | DEF_HELPER_FLAGS_1(abs_s, TCG_CALL_PURE | TCG_CALL_CONST, f32, f32) 49 | DEF_HELPER_FLAGS_1(neg_s, TCG_CALL_PURE | TCG_CALL_CONST, f32, f32) 50 | DEF_HELPER_3(fpu2k_add_s, f32, env, f32, f32) 51 | DEF_HELPER_3(fpu2k_sub_s, f32, env, f32, f32) 52 | DEF_HELPER_3(fpu2k_mul_s, f32, env, f32, f32) 53 | DEF_HELPER_4(fpu2k_madd_s, f32, env, f32, f32, f32) 54 | DEF_HELPER_4(fpu2k_msub_s, f32, env, f32, f32, f32) 55 | DEF_HELPER_4(ftoi_s, i32, env, f32, i32, i32) 56 | DEF_HELPER_4(ftoui_s, i32, env, f32, i32, i32) 57 | DEF_HELPER_3(itof_s, f32, env, i32, i32) 58 | DEF_HELPER_3(uitof_s, f32, env, i32, i32) 59 | DEF_HELPER_2(cvtd_s, f64, env, f32) 60 | 61 | DEF_HELPER_3(un_s, i32, env, f32, f32) 62 | DEF_HELPER_3(oeq_s, i32, env, f32, f32) 63 | DEF_HELPER_3(ueq_s, i32, env, f32, f32) 64 | DEF_HELPER_3(olt_s, i32, env, f32, f32) 65 | DEF_HELPER_3(ult_s, i32, env, f32, f32) 66 | DEF_HELPER_3(ole_s, i32, env, f32, f32) 67 | DEF_HELPER_3(ule_s, i32, env, f32, f32) 68 | 69 | DEF_HELPER_2(wur_fpu_fcr, void, env, i32) 70 | DEF_HELPER_1(rur_fpu_fsr, i32, env) 71 | DEF_HELPER_2(wur_fpu_fsr, void, env, i32) 72 | DEF_HELPER_FLAGS_1(abs_d, TCG_CALL_PURE | TCG_CALL_CONST, f64, f64) 73 | DEF_HELPER_FLAGS_1(neg_d, TCG_CALL_PURE | TCG_CALL_CONST, f64, f64) 74 | DEF_HELPER_3(add_d, f64, env, f64, f64) 75 | DEF_HELPER_3(add_s, f32, env, f32, f32) 76 | DEF_HELPER_3(sub_d, f64, env, f64, f64) 77 | DEF_HELPER_3(sub_s, f32, env, f32, f32) 78 | DEF_HELPER_3(mul_d, f64, env, f64, f64) 79 | DEF_HELPER_3(mul_s, f32, env, f32, f32) 80 | DEF_HELPER_4(madd_d, f64, env, f64, f64, f64) 81 | DEF_HELPER_4(madd_s, f32, env, f32, f32, f32) 82 | DEF_HELPER_4(msub_d, f64, env, f64, f64, f64) 83 | DEF_HELPER_4(msub_s, f32, env, f32, f32, f32) 84 | DEF_HELPER_3(mkdadj_d, f64, env, f64, f64) 85 | DEF_HELPER_3(mkdadj_s, f32, env, f32, f32) 86 | DEF_HELPER_2(mksadj_d, f64, env, f64) 87 | DEF_HELPER_2(mksadj_s, f32, env, f32) 88 | DEF_HELPER_4(ftoi_d, i32, env, f64, i32, i32) 89 | DEF_HELPER_4(ftoui_d, i32, env, f64, i32, i32) 90 | DEF_HELPER_3(itof_d, f64, env, i32, i32) 91 | DEF_HELPER_3(uitof_d, f64, env, i32, i32) 92 | DEF_HELPER_2(cvts_d, f32, env, f64) 93 | 94 | DEF_HELPER_3(un_d, i32, env, f64, f64) 95 | DEF_HELPER_3(oeq_d, i32, env, f64, f64) 96 | DEF_HELPER_3(ueq_d, i32, env, f64, f64) 97 | DEF_HELPER_3(olt_d, i32, env, f64, f64) 98 | DEF_HELPER_3(ult_d, i32, env, f64, f64) 99 | DEF_HELPER_3(ole_d, i32, env, f64, f64) 100 | DEF_HELPER_3(ule_d, i32, env, f64, f64) 101 | 102 | DEF_HELPER_2(rer, i32, env, i32) 103 | DEF_HELPER_3(wer, void, env, i32, i32) 104 | 105 | #include "def-helper.h" 106 | -------------------------------------------------------------------------------- /callbacks.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Common interface for translation libraries. 3 | * 4 | * Copyright (c) Antmicro 5 | * Copyright (c) Realtime Embedded 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, see . 19 | */ 20 | #include 21 | #include "callbacks.h" 22 | #include "unwind.h" 23 | 24 | DEFAULT_VOID_HANDLER1(void tlib_on_translation_block_find_slow, uint64_t pc) 25 | 26 | void tlib_abort(char *message) __attribute__((weak)); 27 | 28 | void tlib_abort(char *message) 29 | { 30 | abort(); 31 | } 32 | 33 | DEFAULT_VOID_HANDLER2(void tlib_log, int32_t level, char *message) 34 | 35 | DEFAULT_INT_HANDLER2(uint64_t tlib_read_byte, uint64_t address, uint64_t cpustate) 36 | 37 | DEFAULT_INT_HANDLER2(uint64_t tlib_read_word, uint64_t address, uint64_t cpustate) 38 | 39 | DEFAULT_INT_HANDLER2(uint64_t tlib_read_double_word, uint64_t address, uint64_t cpustate) 40 | 41 | DEFAULT_INT_HANDLER2(uint64_t tlib_read_quad_word, uint64_t address, uint64_t cpustate) 42 | 43 | DEFAULT_VOID_HANDLER3(void tlib_write_byte, uint64_t address, uint64_t value, uint64_t cpustate) 44 | 45 | DEFAULT_VOID_HANDLER3(void tlib_write_word, uint64_t address, uint64_t value, uint64_t cpustate) 46 | 47 | DEFAULT_VOID_HANDLER3(void tlib_write_double_word, uint64_t address, uint64_t value, uint64_t cpustate) 48 | 49 | DEFAULT_VOID_HANDLER3(void tlib_write_quad_word, uint64_t address, uint64_t value, uint64_t cpustate) 50 | 51 | DEFAULT_INT_HANDLER2(uint32_t tlib_on_block_begin, uint64_t address, uint32_t size) 52 | 53 | DEFAULT_VOID_HANDLER2(void tlib_on_block_finished, uint64_t pc, uint32_t executed_instructions) 54 | 55 | void *tlib_malloc(size_t size) __attribute__((weak)); 56 | 57 | void *tlib_malloc(size_t size) 58 | { 59 | return malloc(size); 60 | } 61 | 62 | void *tlib_realloc(void *ptr, size_t size) __attribute__((weak)); 63 | 64 | void *tlib_realloc(void *ptr, size_t size) 65 | { 66 | return realloc(ptr, size); 67 | } 68 | 69 | void tlib_free(void *ptr) __attribute__((weak)); 70 | 71 | void tlib_free(void *ptr) 72 | { 73 | free(ptr); 74 | } 75 | 76 | DEFAULT_VOID_HANDLER1(void tlib_on_translation_cache_size_change, uint64_t new_size) 77 | 78 | DEFAULT_VOID_HANDLER2(void tlib_invalidate_tb_in_other_cpus, uintptr_t start, uintptr_t end) 79 | 80 | DEFAULT_INT_HANDLER1(uint32_t tlib_get_mp_index, void) 81 | 82 | int32_t tlib_is_on_block_translation_enabled; 83 | 84 | void tlib_set_on_block_translation_enabled(int32_t value) 85 | { 86 | tlib_is_on_block_translation_enabled = value; 87 | } 88 | 89 | EXC_VOID_1(tlib_set_on_block_translation_enabled, int32_t, value) 90 | 91 | void tlib_on_block_translation(uint64_t start, uint32_t size, uint32_t flags) __attribute__((weak)); 92 | 93 | void tlib_on_block_translation(uint64_t start, uint32_t size, uint32_t flags) { } 94 | 95 | DEFAULT_VOID_HANDLER4(void tlib_on_memory_access, uint64_t pc, uint32_t operation, uint64_t address, uint64_t value) 96 | 97 | DEFAULT_INT_HANDLER1(uint32_t tlib_is_in_debug_mode, void) 98 | 99 | DEFAULT_VOID_HANDLER1(void tlib_on_interrupt_begin, uint64_t exception_index) 100 | 101 | DEFAULT_VOID_HANDLER1(void tlib_on_interrupt_end, uint64_t exception_index) 102 | 103 | DEFAULT_PTR_HANDLER1(void *tlib_guest_offset_to_host_ptr, uint64_t offset) 104 | 105 | DEFAULT_INT_HANDLER1(uint64_t tlib_host_ptr_to_guest_offset, void *ptr) 106 | 107 | DEFAULT_VOID_HANDLER3(void tlib_mmu_fault_external_handler, uint64_t addr, int32_t access_type, int32_t window_index) 108 | 109 | DEFAULT_VOID_HANDLER4(void tlib_profiler_announce_stack_change, uint64_t current_address, uint64_t return_address, 110 | uint64_t instructions_count, int32_t is_frame_add) 111 | 112 | DEFAULT_VOID_HANDLER1(void tlib_profiler_announce_context_change, uint64_t context_id) 113 | 114 | DEFAULT_VOID_HANDLER4(void tlib_profiler_announce_stack_pointer_change, uint64_t address, uint64_t old_stack_pointer, 115 | uint64_t stack_pointer, uint64_t instructions_count) 116 | 117 | DEFAULT_VOID_HANDLER2(void tlib_mass_broadcast_dirty, void *list_start, int32_t size) 118 | 119 | DEFAULT_PTR_HANDLER1(void *tlib_get_dirty_addresses_list, void *size) 120 | 121 | DEFAULT_VOID_HANDLER1(void tlib_on_wfi_state_change, int32_t is_in_wfi) 122 | 123 | DEFAULT_INT_HANDLER2(uint32_t tlib_is_memory_disabled, uint64_t start, uint64_t size) 124 | -------------------------------------------------------------------------------- /debug.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Debug functions. 3 | * 4 | * Copyright (c) Antmicro 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, see . 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include "infrastructure.h" 24 | #include "cpu.h" 25 | #include "tcg-op.h" 26 | #include 27 | #define GEN_HELPER 1 28 | #include 29 | #include 30 | #include "debug.h" 31 | 32 | char *msgs[MAX_MSG_COUNT]; 33 | #define MAX_MSG_LENGTH 4096 34 | 35 | #ifdef DEBUG_ON 36 | static uint32_t log_set_msg(char *msg) 37 | { 38 | int id = 0; 39 | while(msgs[id] != NULL) { 40 | if((strcmp(msgs[id], msg)) == 0) { 41 | return id; 42 | } 43 | id++; 44 | } 45 | if(id >= MAX_MSG_COUNT) { 46 | msgs[0] = tlib_strdup("MSG_COUNT_OVERFLOW"); 47 | return 0; // overflow 48 | } 49 | msgs[id] = tlib_strdup(msg); 50 | return id; 51 | } 52 | #endif 53 | 54 | void generate_log(uint64_t pc, char *format, ...) 55 | { 56 | #ifdef DEBUG_ON 57 | char msg[MAX_MSG_LENGTH]; 58 | va_list argList; 59 | va_start(argList, format); 60 | vsprintf(msg, format, argList); 61 | va_end(argList); 62 | TCGv ll = tcg_temp_new(); 63 | TCGv ll2 = tcg_temp_new(); 64 | int id = log_set_msg(msg); 65 | tcg_gen_movi_tl(ll, id); 66 | tcg_gen_movi_tl(ll2, pc); 67 | gen_helper_log(ll, ll2); 68 | tcg_temp_free(ll); 69 | tcg_temp_free(ll2); 70 | #endif 71 | } 72 | 73 | void mark_as_locked(struct TranslationBlock *tb, char *filename, int line_number) 74 | { 75 | #if DEBUG 76 | tb->lock_active = 1; 77 | tb->lock_file = filename; 78 | tb->lock_line = line_number; 79 | #endif 80 | } 81 | 82 | void check_locked(struct TranslationBlock *tb) 83 | { 84 | #if DEBUG 85 | if(tb->lock_active) { 86 | tlib_abortf("Translation after locking the TB detected @ %s:%d", tb->lock_file, tb->lock_line); 87 | } 88 | #endif 89 | } 90 | 91 | void generate_var_log(TCGv v) 92 | { 93 | #ifdef DEBUG_ON 94 | gen_helper_var_log(v); 95 | #endif 96 | } 97 | -------------------------------------------------------------------------------- /include/address-translation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | * Translates a page-aligned guest address into its corresponding host address, 5 | * filling the translation lookaside buffer (TLB) if it wasn't already cached. 6 | * The access width is 32. 7 | * 8 | * The address must not span pages, as the pages are not necessarily contiguous 9 | * in memory and parts of the value may therefore lie at completely different 10 | * host addresses. 11 | * 12 | * In case the guest address corresponds to an MMIO address, it is returned unchanged. 13 | */ 14 | uintptr_t translate_page_aligned_address_and_fill_tlb_u32(target_ulong addr, uint32_t mmu_idx, void *return_address); 15 | 16 | /* 17 | * Translates a page-aligned guest address into its corresponding host address, 18 | * filling the translation lookaside buffer (TLB) if it wasn't already cached. 19 | * The access width is 64. 20 | * 21 | * The address must not span pages, as the pages are not necessarily contiguous 22 | * in memory and parts of the value may therefore lie at completely different 23 | * host addresses. 24 | * 25 | * In case the guest address corresponds to an MMIO address, it is returned unchanged. 26 | */ 27 | uintptr_t translate_page_aligned_address_and_fill_tlb_u64(target_ulong addr, uint32_t mmu_idx, void *return_address); 28 | uintptr_t translate_page_aligned_address_and_fill_tlb_u128(target_ulong addr, uint32_t mmu_idx, void *return_address); 29 | -------------------------------------------------------------------------------- /include/atomic-intrinsics.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void tcg_try_gen_atomic_fetch_add_intrinsic_i32(TCGv_i32 result, TCGv_ptr guestAddress, TCGv_i32 toAdd, uint32_t memIndex, 4 | int fallbackLabel); 5 | 6 | void tcg_try_gen_atomic_fetch_add_intrinsic_i64(TCGv_i64 result, TCGv_ptr guestAddress, TCGv_i64 toAdd, uint32_t memIndex, 7 | int fallbackLabel); 8 | 9 | void tcg_try_gen_atomic_compare_and_swap_intrinsic_i32(TCGv_i32 actual, TCGv_i32 expected, TCGv_ptr guestAddress, 10 | TCGv_i32 newValue, uint32_t memIndex, int fallbackLabel); 11 | 12 | void tcg_try_gen_atomic_compare_and_swap_intrinsic_i64(TCGv_i64 actual, TCGv_i64 expected, TCGv_ptr guestAddress, 13 | TCGv_i64 newValue, uint32_t memIndex, int fallbackLabel); 14 | 15 | void tcg_try_gen_atomic_compare_and_swap_intrinsic_i128(TCGv_i128 actual, TCGv_i128 expected, TCGv_ptr guestAddress, 16 | TCGv_i128 newValue, uint64_t memIndex, int fallbackLabel); 17 | -------------------------------------------------------------------------------- /include/atomic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "targphys.h" 6 | 7 | #define MAX_NUMBER_OF_CPUS 32 8 | 9 | #define NO_CPU_ID 0xFFFFFFFF 10 | #define NO_RESERVATION -1 11 | 12 | struct CPUState; 13 | 14 | typedef struct address_reservation_t { 15 | uint32_t locking_cpu_id; 16 | uint64_t address; 17 | uint8_t active_flag; 18 | uint8_t id; 19 | uint8_t manual_free; 20 | } address_reservation_t; 21 | 22 | typedef struct atomic_memory_state_t { 23 | uint8_t is_mutex_initialized; 24 | uint8_t are_reservations_valid; 25 | 26 | uint32_t number_of_registered_cpus; 27 | 28 | uint32_t locking_cpu_id; 29 | uint32_t entries_count; 30 | 31 | int reservations_count; 32 | int reservations_by_cpu[MAX_NUMBER_OF_CPUS]; 33 | address_reservation_t reservations[MAX_NUMBER_OF_CPUS]; 34 | 35 | pthread_mutex_t global_mutex; 36 | pthread_cond_t global_cond; 37 | 38 | } atomic_memory_state_t; 39 | 40 | int32_t register_in_atomic_memory_state(atomic_memory_state_t *sm, int32_t atomic_id); 41 | 42 | void acquire_global_memory_lock(struct CPUState *env); 43 | void release_global_memory_lock(struct CPUState *env); 44 | void clear_global_memory_lock(struct CPUState *env); 45 | 46 | void reserve_address(struct CPUState *env, target_phys_addr_t address, uint8_t manual_free); 47 | uint32_t check_address_reservation(struct CPUState *env, target_phys_addr_t address); 48 | void register_address_access(struct CPUState *env, target_phys_addr_t address); 49 | void cancel_reservation(struct CPUState *env); 50 | -------------------------------------------------------------------------------- /include/callbacks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "infrastructure.h" 6 | 7 | #define DEFAULT_VOID_HANDLER0(NAME) \ 8 | NAME(void) __attribute__((weak)); \ 9 | \ 10 | NAME(void) { } 11 | 12 | #define DEFAULT_VOID_HANDLER1(NAME, PARAM1) \ 13 | NAME(PARAM1) __attribute__((weak)); \ 14 | \ 15 | NAME(PARAM1) { } 16 | 17 | #define DEFAULT_VOID_HANDLER2(NAME, PARAM1, PARAM2) \ 18 | NAME(PARAM1, PARAM2) __attribute__((weak)); \ 19 | \ 20 | NAME(PARAM1, PARAM2) { } 21 | 22 | #define DEFAULT_VOID_HANDLER3(NAME, PARAM1, PARAM2, PARAM3) \ 23 | NAME(PARAM1, PARAM2, PARAM3) __attribute__((weak)); \ 24 | \ 25 | NAME(PARAM1, PARAM2, PARAM3) { } 26 | 27 | #define DEFAULT_VOID_HANDLER4(NAME, PARAM1, PARAM2, PARAM3, PARAM4) \ 28 | NAME(PARAM1, PARAM2, PARAM3, PARAM4) __attribute__((weak)); \ 29 | \ 30 | NAME(PARAM1, PARAM2, PARAM3, PARAM4) { } 31 | 32 | #define DEFAULT_INT_HANDLER1(NAME, PARAM1) \ 33 | NAME(PARAM1) __attribute__((weak)); \ 34 | \ 35 | NAME(PARAM1) \ 36 | { \ 37 | return 0; \ 38 | } 39 | 40 | #define DEFAULT_INT_HANDLER2(NAME, PARAM1, PARAM2) \ 41 | NAME(PARAM1, PARAM2) __attribute__((weak)); \ 42 | \ 43 | NAME(PARAM1, PARAM2) \ 44 | { \ 45 | return 0; \ 46 | } 47 | 48 | #define DEFAULT_PTR_HANDLER1(NAME, PARAM1) \ 49 | NAME(PARAM1) __attribute__((weak)); \ 50 | \ 51 | NAME(PARAM1) \ 52 | { \ 53 | return NULL; \ 54 | } 55 | 56 | uint64_t tlib_read_byte(uint64_t address, uint64_t cpustate); 57 | uint64_t tlib_read_word(uint64_t address, uint64_t cpustate); 58 | uint64_t tlib_read_double_word(uint64_t address, uint64_t cpustate); 59 | uint64_t tlib_read_quad_word(uint64_t address, uint64_t cpustate); 60 | void tlib_write_byte(uint64_t address, uint64_t value, uint64_t cpustate); 61 | void tlib_write_word(uint64_t address, uint64_t value, uint64_t cpustate); 62 | void tlib_write_double_word(uint64_t address, uint64_t value, uint64_t cpustate); 63 | void tlib_write_quad_word(uint64_t address, uint64_t value, uint64_t cpustate); 64 | void *tlib_guest_offset_to_host_ptr(uint64_t offset); 65 | uint64_t tlib_host_ptr_to_guest_offset(void *ptr); 66 | void tlib_mmu_fault_external_handler(uint64_t addr, int32_t access_type, int32_t window_index); 67 | void tlib_invalidate_tb_in_other_cpus(uintptr_t start, uintptr_t end); 68 | void tlib_update_instruction_counter(int32_t value); 69 | uint32_t tlib_get_mp_index(void); 70 | 71 | void *tlib_malloc(size_t size); 72 | void *tlib_realloc(void *ptr, size_t size); 73 | void tlib_free(void *ptr); 74 | 75 | void tlib_abort(char *message); 76 | void tlib_log(int32_t level, char *message); 77 | 78 | void tlib_on_translation_block_find_slow(uint64_t pc); 79 | uint32_t tlib_on_block_begin(uint64_t address, uint32_t size); 80 | void tlib_on_translation_cache_size_change(uint64_t new_size); 81 | void tlib_on_block_translation(uint64_t start, uint32_t size, uint32_t flags); 82 | extern int32_t tlib_is_on_block_translation_enabled; 83 | void tlib_set_on_block_translation_enabled(int32_t value); 84 | void tlib_on_block_finished(uint64_t pc, uint32_t executed_instructions); 85 | void tlib_on_interrupt_begin(uint64_t exception_index); 86 | void tlib_on_interrupt_end(uint64_t exception_index); 87 | void tlib_profiler_announce_stack_change(uint64_t current_address, uint64_t current_return_address, 88 | uint64_t current_instructions_count, int32_t is_frame_add); 89 | void tlib_profiler_announce_context_change(uint64_t context_id); 90 | void tlib_on_memory_access(uint64_t pc, uint32_t operation, uint64_t addr, uint64_t value); 91 | void tlib_profiler_announce_stack_pointer_change(uint64_t address, uint64_t old_stack_pointer, uint64_t stack_pointer, 92 | uint64_t current_instructions_count); 93 | void tlib_on_memory_access_event_enabled(int32_t value); 94 | void tlib_mass_broadcast_dirty(void *list_start, int size); 95 | void *tlib_get_dirty_addresses_list(void *size); 96 | 97 | uint32_t tlib_is_in_debug_mode(void); 98 | 99 | void tlib_clean_wfi_proc_state(void); 100 | void tlib_on_wfi_state_change(int32_t is_in_wfi); 101 | 102 | uint32_t tlib_is_memory_disabled(uint64_t start, uint64_t size); 103 | -------------------------------------------------------------------------------- /include/compiler.h: -------------------------------------------------------------------------------- 1 | /* public domain */ 2 | 3 | #pragma once 4 | 5 | #define TLIB_NORETURN __attribute__((__noreturn__)) 6 | 7 | #if defined(_WIN32) 8 | #define TLIB_PACKED __attribute__((gcc_struct, packed)) 9 | #else 10 | #define TLIB_PACKED __attribute__((packed)) 11 | #endif 12 | -------------------------------------------------------------------------------- /include/cpu-common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* CPU interfaces that are target indpendent. */ 4 | 5 | // TODO: Fix or remove. Using 'WORDS_ALIGNED' is currently broken 6 | // but it turns out it isn't really required on ARMv7. 7 | // #if defined(__arm__) 8 | // #define WORDS_ALIGNED 9 | // #endif 10 | 11 | #include 12 | 13 | #include "targphys.h" 14 | #include "bswap.h" 15 | #include "tlib-queue.h" 16 | 17 | #ifndef CPU_PC 18 | #define CPU_PC(x) x->pc 19 | #endif 20 | 21 | /* address in the RAM (different from a physical address) */ 22 | typedef uintptr_t ram_addr_t; 23 | 24 | /* memory API */ 25 | 26 | typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value); 27 | typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr); 28 | 29 | void cpu_register_physical_memory_log(target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset, 30 | ram_addr_t region_offset, bool log_dirty); 31 | 32 | static inline void cpu_register_physical_memory_offset(target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset, 33 | ram_addr_t region_offset) 34 | { 35 | cpu_register_physical_memory_log(start_addr, size, phys_offset, region_offset, false); 36 | } 37 | 38 | static inline void cpu_register_physical_memory(target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset) 39 | { 40 | cpu_register_physical_memory_offset(start_addr, size, phys_offset, 0); 41 | } 42 | 43 | ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr); 44 | /* This should only be used for ram local to a device. */ 45 | void *get_ram_ptr(ram_addr_t addr); 46 | /* This should not be used by devices. */ 47 | ram_addr_t ram_addr_from_host(void *ptr); 48 | 49 | void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, int len, int is_write); 50 | static inline void cpu_physical_memory_read(target_phys_addr_t addr, void *buf, int len) 51 | { 52 | cpu_physical_memory_rw(addr, buf, len, 0); 53 | } 54 | static inline void cpu_physical_memory_write(target_phys_addr_t addr, const void *buf, int len) 55 | { 56 | cpu_physical_memory_rw(addr, (void *)buf, len, 1); 57 | } 58 | 59 | uint32_t ldub_phys(target_phys_addr_t addr); 60 | void stb_phys(target_phys_addr_t addr, uint32_t val); 61 | 62 | uint32_t lduw_phys(target_phys_addr_t addr); 63 | uint32_t ldl_phys(target_phys_addr_t addr); 64 | uint64_t ldq_phys(target_phys_addr_t addr); 65 | target_ulong ldp_phys(target_phys_addr_t addr); 66 | void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val); 67 | void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val); 68 | void stw_phys(target_phys_addr_t addr, uint32_t val); 69 | void stl_phys(target_phys_addr_t addr, uint32_t val); 70 | void stq_phys(target_phys_addr_t addr, uint64_t val); 71 | 72 | void cpu_physical_memory_write_rom(target_phys_addr_t addr, const uint8_t *buf, int len); 73 | 74 | #define IO_MEM_SHIFT 3 75 | 76 | #define IO_MEM_RAM (0 << IO_MEM_SHIFT) /* hardcoded offset */ 77 | #define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */ 78 | #define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT) 79 | #define IO_MEM_NOTDIRTY (3 << IO_MEM_SHIFT) 80 | // TLB_MMIO (4 << IO_MEM_SHIFT) 81 | #define IO_MEM_EXECUTABLE_IO (8 << IO_MEM_SHIFT) 82 | /* Acts like a ROM when read and like a device when written. */ 83 | #define IO_MEM_ROMD (1) 84 | #define IO_MEM_SUBPAGE (2) 85 | 86 | typedef struct __attribute__((__packed__)) { 87 | bool dirty : 1; 88 | bool executable_io_mem : 1; 89 | } PhysPageDescFlags; 90 | 91 | typedef struct PhysPageDesc { 92 | /* offset in host memory of the page + io_index in the low bits */ 93 | ram_addr_t phys_offset; 94 | ram_addr_t region_offset; 95 | PhysPageDescFlags flags; 96 | } PhysPageDesc; 97 | 98 | target_ulong virt_to_phys(target_ulong virtual, uint32_t access_type, uint32_t nofault); 99 | 100 | void tlib_arch_dispose(void); 101 | void translate_init(void); 102 | -------------------------------------------------------------------------------- /include/debug.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "tcg-op.h" 5 | 6 | #define MAX_MSG_COUNT 10000 7 | extern char *msgs[MAX_MSG_COUNT]; 8 | 9 | #ifdef DEBUG_ON 10 | #define LOG_CURRENT_LOCATION() \ 11 | do { \ 12 | tlib_printf(LOG_LEVEL_INFO, "We are in %s (%s:%d)", __func__, __FILE__, __LINE__); \ 13 | } while(0) 14 | #else 15 | #define LOG_CURRENT_LOCATION() 16 | #endif 17 | 18 | void generate_log(uint64_t pc, char *format, ...); 19 | void generate_var_log(TCGv v); 20 | 21 | void mark_as_locked(struct TranslationBlock *tb, char *filename, int line_number); 22 | void check_locked(struct TranslationBlock *tb); 23 | 24 | #if DEBUG 25 | #define LOCK_TB(tb) mark_as_locked(tb, __FILE__, __LINE__); 26 | #define UNLOCK_TB(tb) tb->lock_active = 0 27 | #define CHECK_LOCKED(tb) check_locked(tb) 28 | #else 29 | #define LOCK_TB(tb) 30 | #define UNLOCK_TB(tb) 31 | #define CHECK_LOCKED(tb) 32 | #endif 33 | -------------------------------------------------------------------------------- /include/disas_context_base.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct DisasContextBase { 4 | struct TranslationBlock *tb; 5 | target_ulong pc; 6 | int mem_idx; 7 | int is_jmp; 8 | int guest_profile; 9 | bool generate_block_exit_check; 10 | } DisasContextBase; 11 | -------------------------------------------------------------------------------- /include/exports.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | uint32_t tlib_set_maximum_block_size(uint32_t size); 6 | uint32_t tlib_get_maximum_block_size(void); 7 | 8 | void tlib_set_millicycles_per_instruction(uint32_t count); 9 | uint32_t tlib_get_millicycles_per_instruction(void); 10 | 11 | void gen_helpers(void); 12 | 13 | char *tlib_get_arch(); 14 | char *tlib_get_commit(); 15 | 16 | int32_t tlib_init(char *cpu_name); 17 | int32_t tlib_atomic_memory_state_init(uintptr_t atomic_memory_state_ptr, int32_t atomic_id); 18 | void tlib_dispose(void); 19 | uint64_t tlib_get_executed_instructions(void); 20 | void tlib_reset(void); 21 | int32_t tlib_execute(uint32_t max_insns); 22 | void tlib_request_translation_block_interrupt(int); 23 | void tlib_try_interrupt_translation_block(void); 24 | void tlib_set_return_request(void); 25 | void tlib_set_paused(void); 26 | void tlib_clear_paused(void); 27 | int32_t tlib_is_wfi(void); 28 | 29 | uint32_t tlib_get_page_size(void); 30 | void tlib_map_range(uint64_t start_addr, uint64_t length); 31 | void tlib_unmap_range(uint64_t start, uint64_t end); 32 | uint32_t tlib_is_range_mapped(uint64_t start, uint64_t end); 33 | 34 | void tlib_invalidate_translation_blocks(uintptr_t start, uintptr_t end); 35 | 36 | uint64_t tlib_translate_to_physical_address(uint64_t address, uint32_t access_type); 37 | 38 | void tlib_set_irq(int32_t interrupt, int32_t state); 39 | int32_t tlib_is_irq_set(void); 40 | 41 | void tlib_add_breakpoint(uint64_t address); 42 | void tlib_remove_breakpoint(uint64_t address); 43 | void tlib_set_block_begin_hook_present(uint32_t val); 44 | 45 | uint64_t tlib_get_total_executed_instructions(void); 46 | 47 | void tlib_set_translation_cache_configuration(uint64_t min_size, uint64_t max_size); 48 | void tlib_invalidate_translation_cache(void); 49 | 50 | void tlib_enable_guest_profiler(int value); 51 | 52 | void tlib_set_page_io_accessed(uint64_t address); 53 | void tlib_clear_page_io_accessed(uint64_t address); 54 | 55 | int tlib_restore_context(void); 56 | void *tlib_export_state(void); 57 | int32_t tlib_get_state_size(void); 58 | 59 | void tlib_set_chaining_enabled(uint32_t val); 60 | uint32_t tlib_get_chaining_enabled(void); 61 | 62 | void tlib_set_tb_cache_enabled(uint32_t val); 63 | uint32_t tlib_get_tb_cache_enabled(void); 64 | 65 | void tlib_set_block_finished_hook_present(uint32_t val); 66 | void tlib_set_cpu_wfi_state_change_hook_present(uint32_t val); 67 | 68 | int32_t tlib_set_return_on_exception(int32_t value); 69 | void tlib_flush_page(uint64_t address); 70 | 71 | uint64_t tlib_get_register_value(int reg_number); 72 | void tlib_set_register_value(int reg_number, uint64_t val); 73 | 74 | void tlib_set_event_flag(int value); 75 | 76 | uint32_t tlib_get_current_tb_disas_flags(void); 77 | 78 | uint32_t tlib_get_mmu_windows_count(void); 79 | 80 | void tlib_enable_external_window_mmu(uint32_t value); 81 | 82 | int32_t tlib_acquire_mmu_window(uint32_t type); 83 | 84 | void tlib_set_mmu_window_start(uint32_t index, uint64_t addr_start); 85 | 86 | void tlib_set_mmu_window_end(uint32_t index, uint64_t addr_end, uint32_t range_end_inclusive); 87 | 88 | void tlib_set_window_privileges(uint32_t index, int32_t privileges); 89 | 90 | void tlib_set_mmu_window_addend(uint32_t index, uint64_t addend); 91 | 92 | uint64_t tlib_get_mmu_window_start(uint32_t index); 93 | 94 | uint64_t tlib_get_mmu_window_end(uint32_t index); 95 | 96 | int tlib_get_window_privileges(uint32_t index); 97 | 98 | uint64_t tlib_get_mmu_window_addend(uint32_t index); 99 | 100 | // Defined in 'arch/*/cpu_registers.c'. 101 | uint32_t tlib_get_register_value_32(int reg_number); 102 | void tlib_set_register_value_32(int reg_number, uint32_t value); 103 | 104 | #if TARGET_LONG_BITS == 64 105 | uint64_t tlib_get_register_value_64(int reg_number); 106 | void tlib_set_register_value_64(int reg_number, uint64_t value); 107 | #endif 108 | 109 | void tlib_before_save(void *env); 110 | 111 | void tlib_after_load(void *env); 112 | 113 | void tlib_enable_read_cache(uint64_t access_address, uint64_t lower_access_count, uint64_t upper_access_count); 114 | 115 | uint64_t tlib_get_cpu_state_for_memory_transaction(CPUState *env, uint64_t addr, int access_type); 116 | -------------------------------------------------------------------------------- /include/global_helper.h: -------------------------------------------------------------------------------- 1 | #include "def-helper.h" 2 | 3 | DEF_HELPER_1(prepare_block_for_execution, i32, ptr) 4 | DEF_HELPER_0(block_begin_event, i32) 5 | DEF_HELPER_2(block_finished_event, void, tl, i32) 6 | DEF_HELPER_1(try_exit_cpu_loop, void, env) 7 | DEF_HELPER_2(log, void, i32, i64) 8 | DEF_HELPER_1(var_log, void, tl) 9 | DEF_HELPER_0(abort, void) 10 | DEF_HELPER_2(announce_stack_change, void, tl, i32) 11 | DEF_HELPER_3(announce_stack_pointer_change, void, tl, tl, tl) 12 | DEF_HELPER_1(on_interrupt_end_event, void, i64) 13 | 14 | DEF_HELPER_1(invalidate_dirty_addresses_shared, void, env) 15 | DEF_HELPER_4(mark_tbs_as_dirty, void, env, tl, i32, i32) 16 | 17 | DEF_HELPER_1(count_opcode_inner, void, i32) 18 | DEF_HELPER_1(tlb_flush, void, env) 19 | 20 | DEF_HELPER_1(acquire_global_memory_lock, void, env) 21 | DEF_HELPER_1(release_global_memory_lock, void, env) 22 | DEF_HELPER_3(reserve_address, void, env, uintptr, i32) 23 | DEF_HELPER_2(check_address_reservation, tl, env, uintptr) 24 | DEF_HELPER_2(register_address_access, void, env, uintptr) 25 | DEF_HELPER_1(cancel_reservation, void, env) 26 | 27 | DEF_HELPER_2(translate_page_aligned_address_and_fill_tlb_u32, uintptr, tl, i32) 28 | DEF_HELPER_2(translate_page_aligned_address_and_fill_tlb_u64, uintptr, tl, i32) 29 | DEF_HELPER_2(translate_page_aligned_address_and_fill_tlb_u128, uintptr, tl, i32) 30 | 31 | #include "def-helper.h" 32 | -------------------------------------------------------------------------------- /include/infrastructure.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "osdep.h" // For the 'unlikely' macro. 6 | 7 | enum log_level { LOG_LEVEL_NOISY = -1, LOG_LEVEL_DEBUG = 0, LOG_LEVEL_INFO = 1, LOG_LEVEL_WARNING = 2, LOG_LEVEL_ERROR = 3 }; 8 | 9 | void *tlib_mallocz(size_t size); 10 | char *tlib_strdup(const char *str); 11 | void tlib_printf(enum log_level level, char *fmt, ...); 12 | void tlib_abort(char *message); 13 | void tlib_abortf(char *fmt, ...); 14 | 15 | #define tlib_assert(x) \ 16 | { \ 17 | if(unlikely(!(x))) { \ 18 | tlib_abortf("Assert not met in %s:%d: %s", __FILE__, __LINE__, #x); \ 19 | __builtin_unreachable(); \ 20 | } \ 21 | } 22 | 23 | #define tlib_assert_not_reached() \ 24 | { \ 25 | tlib_abortf("Should not reach here: %s %d", __FILE__, __LINE__); \ 26 | __builtin_unreachable(); \ 27 | } 28 | #define g_assert_not_reached tlib_assert_not_reached 29 | 30 | #include "callbacks.h" 31 | -------------------------------------------------------------------------------- /include/int128.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Antmicro 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "stdint.h" 10 | #include "stdbool.h" 11 | 12 | static inline __int128_t int128_add(const __int128_t a, const __int128_t b) 13 | { 14 | return a + b; 15 | } 16 | 17 | static inline bool int128_eq(const __int128_t a, const __int128_t b) 18 | { 19 | return a == b; 20 | }; 21 | 22 | static inline __int128_t int128_exts64(const int64_t a) 23 | { 24 | return (__int128_t)a; 25 | } 26 | 27 | static inline int64_t int128_gethi(const __int128_t a) 28 | { 29 | return (int64_t)(a >> 64); 30 | } 31 | 32 | static inline uint64_t int128_getlo(const __int128_t a) 33 | { 34 | return (uint64_t)a; 35 | } 36 | 37 | static inline __int128_t int128_lshift(const __int128_t a, const uint8_t shift) 38 | { 39 | return a << shift; 40 | } 41 | 42 | static inline __int128_t int128_make128(const uint64_t low, const uint64_t high) 43 | { 44 | return (__int128_t)(((__int128_t)(high) << 64) | low); 45 | } 46 | 47 | static inline __int128_t int128_make64(const uint64_t a) 48 | { 49 | return (__int128_t)a; 50 | } 51 | 52 | static inline __int128_t int128_neg(const __int128_t a) 53 | { 54 | return -a; 55 | } 56 | 57 | static inline __int128_t int128_rshift(const __int128_t a, const uint8_t shift) 58 | { 59 | return a >> shift; 60 | } 61 | -------------------------------------------------------------------------------- /include/osdep.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #ifndef glue 13 | #define xglue(x, y) x##y 14 | #define glue(x, y) xglue(x, y) 15 | #define stringify(s) tostring(s) 16 | #define tostring(s) #s 17 | #endif 18 | 19 | #ifndef likely 20 | #ifdef __GNUC__ 21 | #define __builtin_expect(x, n) (x) 22 | #endif 23 | 24 | #define likely(x) __builtin_expect(!!(x), 1) 25 | #define unlikely(x) __builtin_expect(!!(x), 0) 26 | #endif 27 | 28 | #ifdef CONFIG_NEED_OFFSETOF 29 | #define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER) 30 | #error 31 | #endif 32 | 33 | #ifndef ARRAY_SIZE 34 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 35 | #endif 36 | 37 | #ifdef __i386__ 38 | #define REGPARM __attribute((regparm(3))) 39 | #else 40 | #define REGPARM 41 | #endif 42 | -------------------------------------------------------------------------------- /include/softmmu_defs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | uint8_t REGPARM __ldb_mmu(target_ulong addr, int mmu_idx); 4 | uint8_t REGPARM __ldb_err_mmu(target_ulong addr, int mmu_idx, int *err); 5 | uint8_t REGPARM __inner_ldb_err_mmu(target_ulong addr, int mmu_idx, int *err, void *retaddr); 6 | void REGPARM __stb_mmu(target_ulong addr, uint8_t val, int mmu_idx); 7 | void REGPARM __inner_stb_mmu(target_ulong addr, uint8_t val, int mmu_idx, void *retaddr); 8 | uint16_t REGPARM __ldw_mmu(target_ulong addr, int mmu_idx); 9 | uint16_t REGPARM __ldw_err_mmu(target_ulong addr, int mmu_idx, int *err); 10 | uint16_t REGPARM __inner_ldw_err_mmu(target_ulong addr, int mmu_idx, int *err, void *retaddr); 11 | void REGPARM __stw_mmu(target_ulong addr, uint16_t val, int mmu_idx); 12 | void REGPARM __inner_stw_mmu(target_ulong addr, uint16_t val, int mmu_idx, void *retaddr); 13 | uint32_t REGPARM __ldl_mmu(target_ulong addr, int mmu_idx); 14 | uint32_t REGPARM __ldl_err_mmu(target_ulong addr, int mmu_idx, int *err); 15 | uint32_t REGPARM __inner_ldl_err_mmu(target_ulong addr, int mmu_idx, int *err, void *retaddr); 16 | void REGPARM __stl_mmu(target_ulong addr, uint32_t val, int mmu_idx); 17 | void REGPARM __inner_stl_mmu(target_ulong addr, uint32_t val, int mmu_idx, void *retaddr); 18 | uint64_t REGPARM __ldq_mmu(target_ulong addr, int mmu_idx); 19 | uint64_t REGPARM __ldq_err_mmu(target_ulong addr, int mmu_idx, int *err); 20 | uint64_t REGPARM __inner_ldq_err_mmu(target_ulong addr, int mmu_idx, int *err, void *retaddr); 21 | void REGPARM __stq_mmu(target_ulong addr, uint64_t val, int mmu_idx); 22 | void REGPARM __inner_stq_mmu(target_ulong addr, uint64_t val, int mmu_idx, void *retaddr); 23 | 24 | uint8_t REGPARM __ldb_cmmu(target_ulong addr, int mmu_idx); 25 | uint8_t REGPARM __ldb_err_cmmu(target_ulong addr, int mmu_idx, int *err); 26 | uint8_t REGPARM __inner_ldb_err_cmmu(target_ulong addr, int mmu_idx, int *err, void *retaddr); 27 | void REGPARM __stb_cmmu(target_ulong addr, uint8_t val, int mmu_idx); 28 | void REGPARM __inner_stb_cmmu(target_ulong addr, uint8_t val, int mmu_idx, void *retaddr); 29 | uint16_t REGPARM __ldw_cmmu(target_ulong addr, int mmu_idx); 30 | uint16_t REGPARM __ldw_err_cmmu(target_ulong addr, int mmu_idx, int *err); 31 | uint16_t REGPARM __inner_ldw_err_cmmu(target_ulong addr, int mmu_idx, int *err, void *retaddr); 32 | void REGPARM __stw_cmmu(target_ulong addr, uint16_t val, int mmu_idx); 33 | void REGPARM __inner_stw_cmmu(target_ulong addr, uint16_t val, int mmu_idx, void *retaddr); 34 | uint32_t REGPARM __ldl_cmmu(target_ulong addr, int mmu_idx); 35 | uint32_t REGPARM __ldl_err_cmmu(target_ulong addr, int mmu_idx, int *err); 36 | uint32_t REGPARM __inner_ldl_err_cmmu(target_ulong addr, int mmu_idx, int *err, void *retaddr); 37 | void REGPARM __stl_cmmu(target_ulong addr, uint32_t val, int mmu_idx); 38 | void REGPARM __inner_stl_cmmu(target_ulong addr, uint32_t val, int mmu_idx, void *retaddr); 39 | uint64_t REGPARM __ldq_cmmu(target_ulong addr, int mmu_idx); 40 | uint64_t REGPARM __ldq_err_cmmu(target_ulong addr, int mmu_idx, int *err); 41 | uint64_t REGPARM __inner_ldq_err_cmmu(target_ulong addr, int mmu_idx, int *err, void *retaddr); 42 | void REGPARM __stq_cmmu(target_ulong addr, uint64_t val, int mmu_idx); 43 | void REGPARM __inner_stq_cmmu(target_ulong addr, uint64_t val, int mmu_idx, void *retaddr); 44 | -------------------------------------------------------------------------------- /include/targphys.h: -------------------------------------------------------------------------------- 1 | /* Define target_phys_addr_t if it exists. */ 2 | 3 | #pragma once 4 | 5 | #ifndef TARGET_PHYS_ADDR_BITS 6 | #define TARGET_PHYS_ADDR_BITS TARGET_LONG_BITS 7 | #endif 8 | 9 | /* target_phys_addr_t is the type of a physical address (its size can 10 | be different from 'target_ulong'). 11 | 12 | SPARC architecture has 36-bits wide physical address, that's why 13 | we use `<=` operators below instead of simple `==` 14 | */ 15 | 16 | #if TARGET_PHYS_ADDR_BITS <= 32 17 | typedef uint32_t target_phys_addr_t; 18 | #define TARGET_PHYS_ADDR_MAX UINT32_MAX 19 | #define TARGET_FMT_plx "%08X" 20 | #elif TARGET_PHYS_ADDR_BITS <= 64 21 | typedef uint64_t target_phys_addr_t; 22 | #define TARGET_PHYS_ADDR_MAX UINT64_MAX 23 | #define TARGET_FMT_plx "%016" PRIX64 24 | #else 25 | #error "Target physical address width is too big" 26 | #endif 27 | -------------------------------------------------------------------------------- /include/tb-helper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "tcg-op.h" 4 | 5 | #include 6 | 7 | #include 8 | #define GEN_HELPER 1 9 | #include 10 | 11 | #include "helper.h" 12 | #define GEN_HELPER 1 13 | #include "helper.h" 14 | 15 | extern TCGv_ptr cpu_env; 16 | -------------------------------------------------------------------------------- /include/tlib-alloc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "infrastructure.h" 6 | 7 | // Size in bytes of the tcg prologue, put at the end of the code_gen_buffer 8 | #define TCG_PROLOGUE_SIZE 1024 9 | 10 | extern uint8_t *tcg_rw_buffer; 11 | extern uint8_t *tcg_rx_buffer; 12 | extern intptr_t tcg_wx_diff; 13 | extern uint64_t code_gen_buffer_size; 14 | 15 | static inline bool is_ptr_in_rw_buf(const void *ptr) 16 | { 17 | return (ptr >= (void *)tcg_rw_buffer) && (ptr < ((void *)tcg_rw_buffer + code_gen_buffer_size + TCG_PROLOGUE_SIZE)); 18 | } 19 | 20 | static inline bool is_ptr_in_rx_buf(const void *ptr) 21 | { 22 | return (ptr >= (void *)tcg_rx_buffer) && (ptr < ((void *)tcg_rx_buffer + code_gen_buffer_size + TCG_PROLOGUE_SIZE)); 23 | } 24 | 25 | static inline void *rw_ptr_to_rx(void *ptr) 26 | { 27 | if(ptr == NULL) { 28 | // null pointers should not be changed 29 | return ptr; 30 | } 31 | tlib_assert(is_ptr_in_rx_buf(ptr - tcg_wx_diff)); 32 | return ptr - tcg_wx_diff; 33 | } 34 | 35 | static inline void *rx_ptr_to_rw(const void *ptr) 36 | { 37 | if(ptr == NULL) { 38 | // null pointers should not be changed 39 | return (void *)ptr; 40 | } 41 | tlib_assert(is_ptr_in_rw_buf(ptr + tcg_wx_diff)); 42 | return (void *)(ptr + tcg_wx_diff); 43 | } 44 | 45 | bool alloc_code_gen_buf(uint64_t size); 46 | void free_code_gen_buf(); 47 | -------------------------------------------------------------------------------- /infrastructure.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Basic implementations of common functions. 3 | * 4 | * Copyright (c) Antmicro 5 | * Copyright (c) Realtime Embedded 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, see . 19 | */ 20 | #include 21 | #include 22 | #include 23 | #ifndef _WIN32 // This header is not available on MinGW 24 | #include 25 | #endif 26 | #include "callbacks.h" 27 | #include "infrastructure.h" 28 | 29 | void *global_retaddr = 0; 30 | 31 | #if defined(__linux__) && defined(__x86_64__) 32 | 33 | asm(".symver memcpy, memcpy@GLIBC_2.2.5"); 34 | 35 | void *__wrap_memcpy(void *dest, const void *src, size_t n) 36 | { 37 | return memcpy(dest, src, n); 38 | } 39 | #endif 40 | 41 | void *tlib_mallocz(size_t size) 42 | { 43 | void *ret = tlib_malloc(size); 44 | memset(ret, 0, size); 45 | return ret; 46 | } 47 | 48 | char *tlib_strdup(const char *str) 49 | { 50 | int length = strlen(str); 51 | char *ret = tlib_malloc(length + 1); 52 | strcpy(ret, str); 53 | return ret; 54 | } 55 | 56 | void tlib_printf(enum log_level level, char *fmt, ...) 57 | { 58 | char s[1024]; 59 | va_list ap; 60 | va_start(ap, fmt); 61 | vsnprintf(s, 1024, fmt, ap); 62 | tlib_log((int32_t)level, s); 63 | va_end(ap); 64 | } 65 | 66 | void tlib_abortf(char *fmt, ...) 67 | { 68 | char result[1024]; 69 | va_list ap; 70 | va_start(ap, fmt); 71 | vsnprintf(result, 1024, fmt, ap); 72 | #if DEBUG && !defined(_WIN32) 73 | #define TRACE_MAX_SIZE 20 74 | void *array[TRACE_MAX_SIZE]; 75 | char **strings; 76 | int size, i; 77 | size = backtrace(array, TRACE_MAX_SIZE); 78 | strings = backtrace_symbols(array, size); 79 | if(strings != NULL) { 80 | tlib_printf(LOG_LEVEL_ERROR, "Stack: [%d frames]", size); 81 | // The last frame is meaningless, and the first one is the tlib_abort itself 82 | for(i = 1; i < size - 1; i++) { 83 | tlib_printf(LOG_LEVEL_ERROR, "%s\n", strings[i]); 84 | } 85 | } 86 | free(strings); 87 | #endif 88 | tlib_abort(result); 89 | va_end(ap); 90 | } 91 | -------------------------------------------------------------------------------- /profile-helper.c: -------------------------------------------------------------------------------- 1 | #include "tcg/additional.h" 2 | 3 | #ifdef GENERATE_PERF_MAP 4 | /* 5 | We place the helper here, since TB internals require cpu.h to be included, 6 | so this is the only util of the labeling pack, that has to be compiled 7 | not into tcg, but into tlibs. 8 | */ 9 | 10 | #include "cpu.h" 11 | #include "include/infrastructure.h" 12 | #include 13 | 14 | int tcg_perf_tb_info_to_string(TranslationBlock *tb, char *buffer, int maxsize) 15 | { 16 | snprintf(buffer, maxsize, ";addr:%p;size:%x;jmp_next:%p,%p;jmp_first:%p,icount:%d;", &(*tb), tb->size, tb->jmp_next[0], 17 | tb->jmp_next[1], tb->jmp_first, tb->icount); 18 | return strlen(buffer); 19 | } 20 | 21 | void tcg_perf_out_symbol_from_tb(TranslationBlock *tb, int host_size, const char *comment) 22 | { 23 | tcg_perf_out_symbol_s(tb->tc_ptr, host_size, comment, tb); 24 | } 25 | #else 26 | inline void tcg_perf_out_symbol_from_tb(struct TranslationBlock *tb, int host_size, const char *comment) { } 27 | #endif 28 | -------------------------------------------------------------------------------- /tcg/.gitignore: -------------------------------------------------------------------------------- 1 | tags 2 | build 3 | bin/ 4 | obj/ 5 | -------------------------------------------------------------------------------- /tcg/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | project (tcg LANGUAGES C) 4 | 5 | if(NOT HOST_ARCH) 6 | message (FATAL_ERROR "Host architecture not set") 7 | endif() 8 | if(NOT HOST_WORD_SIZE) 9 | message (FATAL_ERROR "Host word size not set") 10 | endif() 11 | 12 | add_definitions ( 13 | -fPIC 14 | 15 | -DTARGET_LONG_BITS=${TARGET_WORD_SIZE} 16 | -DHOST_LONG_BITS=${HOST_WORD_SIZE} 17 | -DTARGET_INSN_START_EXTRA_WORDS=${TARGET_INSN_START_EXTRA_WORDS} 18 | 19 | ${BIG_ENDIAN_DEF} 20 | ${DEBUG_DEF} 21 | ) 22 | 23 | include_directories ( 24 | ${HOST_ARCH} 25 | ${CMAKE_SOURCE_DIR} 26 | ) 27 | 28 | add_library (tcg OBJECT 29 | additional.c 30 | host-utils.c 31 | optimize.c 32 | tcg.c 33 | tcg-op-gvec.c 34 | tcg-op-vec.c 35 | tcg-runtime.c 36 | tcg-runtime-gvec.c 37 | ) 38 | 39 | -------------------------------------------------------------------------------- /tcg/LICENSE: -------------------------------------------------------------------------------- 1 | All the files in this directory and subdirectories are released under 2 | a BSD like license (see header in each file). No other license is 3 | accepted. 4 | -------------------------------------------------------------------------------- /tcg/additional.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | void *TCG_malloc(size_t size); 8 | void *TCG_realloc(void *ptr, size_t size); 9 | void TCG_free(void *ptr); 10 | void TCG_pstrcpy(char *buf, int buf_size, const char *str); 11 | char *TCG_pstrcat(char *buf, int buf_size, const char *s); 12 | 13 | // The highest value of NB_MMU_MODES used incremented by one. 14 | #define MMU_MODES_MAX 16 15 | 16 | extern unsigned int temp_buf_offset; 17 | extern unsigned int tlb_table_n_0_addr_read[MMU_MODES_MAX]; 18 | extern unsigned int tlb_table_n_0_addr_write[MMU_MODES_MAX]; 19 | extern unsigned int tlb_table_n_0_addend[MMU_MODES_MAX]; 20 | extern unsigned int tlb_table_n_0[MMU_MODES_MAX]; 21 | extern unsigned int tlb_entry_addr_read; 22 | extern unsigned int tlb_entry_addr_write; 23 | extern unsigned int tlb_entry_addend; 24 | extern unsigned int sizeof_CPUTLBEntry; 25 | 26 | /* XXX: make safe guess about sizes */ 27 | #define MAX_OP_PER_INSTR 208 28 | 29 | #if HOST_LONG_BITS == 32 30 | #define MAX_OPC_PARAM_PER_ARG 2 31 | #else 32 | #define MAX_OPC_PARAM_PER_ARG 1 33 | #endif 34 | #define MAX_OPC_PARAM_IARGS 5 35 | #define MAX_OPC_PARAM_OARGS 2 36 | #define MAX_OPC_PARAM_ARGS (MAX_OPC_PARAM_IARGS + MAX_OPC_PARAM_OARGS) 37 | 38 | /* A Call op needs up to 4 + 2N parameters on 32-bit archs, 39 | * and up to 4 + N parameters on 64-bit archs 40 | * (N = number of input arguments + output arguments). */ 41 | #define MAX_OPC_PARAM (4 + (MAX_OPC_PARAM_PER_ARG * MAX_OPC_PARAM_ARGS)) 42 | #define OPC_BUF_SIZE 640 43 | #define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR) 44 | 45 | /* Maximum size a TCG op can expand to. This is complicated because a 46 | single op may require several host instructions and register reloads. 47 | For now take a wild guess at 192 bytes, which should allow at least 48 | a couple of fixup instructions per argument. */ 49 | #define TCG_MAX_OP_SIZE 192 50 | 51 | /* The maximum size of generated code within a block. */ 52 | #define TCG_MAX_CODE_SIZE (TCG_MAX_OP_SIZE * OPC_BUF_SIZE) 53 | 54 | /* The maximum size of PC search data within a block. */ 55 | #define TCG_MAX_SEARCH_SIZE (TCG_MAX_CODE_SIZE * 0.3) 56 | 57 | #define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * MAX_OPC_PARAM) 58 | 59 | void tlib_abort(char *msg); 60 | 61 | static inline void tcg_abortf(char *fmt, ...) 62 | { 63 | char result[1024]; 64 | va_list ap; 65 | va_start(ap, fmt); 66 | vsnprintf(result, 1024, fmt, ap); 67 | tlib_abort(result); 68 | va_end(ap); 69 | __builtin_unreachable(); 70 | } 71 | struct TranslationBlock; 72 | 73 | void tcg_perf_init_labeling(); 74 | void tcg_perf_fini_labeling(); 75 | void tcg_perf_flush_map(); 76 | void tcg_perf_out_symbol_s(void *s, int size, const char *label, struct TranslationBlock *tb); 77 | void tcg_perf_out_symbol_i(void *s, int size, int label, struct TranslationBlock *tb); 78 | void tcg_perf_out_symbol(void *s, int size, struct TranslationBlock *tb); 79 | 80 | void tcg_perf_out_symbol_from_tb(struct TranslationBlock *tb, int host_size, const char *comment); 81 | int tcg_perf_tb_info_to_string(struct TranslationBlock *tb, char *buffer, int maxsize); 82 | -------------------------------------------------------------------------------- /tcg/arm/tcg-target.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny Code Generator for QEMU 3 | * 4 | * Copyright (c) 2008 Fabrice Bellard 5 | * Copyright (c) 2008 Andrzej Zaborowski 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | #pragma once 26 | 27 | #define TCG_TARGET_ARM 1 28 | 29 | #define TCG_TARGET_DEFAULT_MO 0 30 | 31 | #undef TCG_TARGET_WORDS_BIGENDIAN 32 | #undef TCG_TARGET_STACK_GROWSUP 33 | 34 | typedef enum { 35 | TCG_REG_R0 = 0, 36 | TCG_REG_R1, 37 | TCG_REG_R2, 38 | TCG_REG_R3, 39 | TCG_REG_R4, 40 | TCG_REG_R5, 41 | TCG_REG_R6, 42 | TCG_REG_R7, 43 | TCG_REG_R8, 44 | TCG_REG_R9, 45 | TCG_REG_R10, 46 | TCG_REG_R11, 47 | TCG_REG_R12, 48 | TCG_REG_R13, // SP 49 | TCG_REG_R14, // LR 50 | TCG_REG_PC, // PC 51 | } TCGReg; 52 | 53 | #define TCG_TARGET_NB_REGS 16 54 | 55 | #define TCG_CT_CONST_ARM 0x100 56 | 57 | /* used for function call generation */ 58 | #define TCG_REG_CALL_STACK TCG_REG_R13 59 | #define TCG_TARGET_STACK_ALIGN 8 60 | #define TCG_TARGET_CALL_ALIGN_ARGS 1 61 | #define TCG_TARGET_CALL_STACK_OFFSET 0 62 | 63 | /* optional instructions */ 64 | #define TCG_TARGET_HAS_andc_i32 1 65 | #define TCG_TARGET_HAS_bswap16_i32 1 66 | #define TCG_TARGET_HAS_bswap32_i32 1 67 | #define TCG_TARGET_HAS_deposit_i32 0 // TODO: Implement opcode and put 'use_armv7_instructions' here. 68 | #define TCG_TARGET_HAS_div_i32 0 69 | #define TCG_TARGET_HAS_eqv_i32 0 70 | #define TCG_TARGET_HAS_ext16s_i32 1 71 | #define TCG_TARGET_HAS_ext16u_i32 1 72 | #define TCG_TARGET_HAS_ext8s_i32 1 73 | #define TCG_TARGET_HAS_ext8u_i32 0 /* and r0, r1, #0xff */ 74 | #define TCG_TARGET_HAS_extract_i32 0 // TODO: Implement opcode and put 'use_armv7_instructions' here. 75 | #define TCG_TARGET_HAS_movcond_i32 0 // TODO: ARMv7 supports 'movcond' but it isn't supported by our 'arm/tcg-target.c'. 76 | #define TCG_TARGET_HAS_muls2_i32 1 77 | #define TCG_TARGET_HAS_mulu2_i32 1 78 | #define TCG_TARGET_HAS_nand_i32 0 79 | #define TCG_TARGET_HAS_neg_i32 1 80 | #define TCG_TARGET_HAS_nor_i32 0 81 | #define TCG_TARGET_HAS_not_i32 1 82 | #define TCG_TARGET_HAS_orc_i32 0 83 | #define TCG_TARGET_HAS_rot_i32 1 84 | #define TCG_TARGET_HAS_MEMORY_BSWAP 0 85 | 86 | #define TCG_TARGET_HAS_GUEST_BASE 87 | 88 | enum { 89 | /* Note: must be synced with cpu-defs.h */ 90 | TCG_AREG0 = TCG_REG_R7, 91 | }; 92 | 93 | static inline void flush_icache_range(unsigned long start, unsigned long stop) 94 | { 95 | #if defined(__GNUC__) 96 | __builtin___clear_cache((char *)start, (char *)stop); 97 | #else 98 | register unsigned long _beg __asm("a1") = start; 99 | register unsigned long _end __asm("a2") = stop; 100 | register unsigned long _flg __asm("a3") = 0; 101 | __asm __volatile__("swi 0x9f0002" : : "r"(_beg), "r"(_end), "r"(_flg)); 102 | #endif 103 | } 104 | -------------------------------------------------------------------------------- /tcg/host-utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Utility compute operations used by translated code. 3 | * 4 | * Copyright (c) 2003 Fabrice Bellard 5 | * Copyright (c) 2007 Aurelien Jarno 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | 26 | #include "host-utils.h" 27 | 28 | #if !defined(TCG_TARGET_I386) || HOST_LONG_BITS != 64 29 | /* Long integer helpers */ 30 | static inline void mul64(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b) 31 | { 32 | typedef union { 33 | uint64_t ll; 34 | struct { 35 | #if HOST_WORDS_BIGENDIAN 36 | uint32_t high, low; 37 | #else 38 | uint32_t low, high; 39 | #endif 40 | } l; 41 | } LL; 42 | LL rl, rm, rn, rh, a0, b0; 43 | uint64_t c; 44 | 45 | a0.ll = a; 46 | b0.ll = b; 47 | 48 | rl.ll = (uint64_t)a0.l.low * b0.l.low; 49 | rm.ll = (uint64_t)a0.l.low * b0.l.high; 50 | rn.ll = (uint64_t)a0.l.high * b0.l.low; 51 | rh.ll = (uint64_t)a0.l.high * b0.l.high; 52 | 53 | c = (uint64_t)rl.l.high + rm.l.low + rn.l.low; 54 | rl.l.high = c; 55 | c >>= 32; 56 | c = c + rm.l.high + rn.l.high + rh.l.low; 57 | rh.l.low = c; 58 | rh.l.high += (uint32_t)(c >> 32); 59 | 60 | *plow = rl.ll; 61 | *phigh = rh.ll; 62 | } 63 | 64 | /* Unsigned 64x64 -> 128 multiplication */ 65 | void mulu64(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b) 66 | { 67 | mul64(plow, phigh, a, b); 68 | } 69 | 70 | /* Signed 64x64 -> 128 multiplication */ 71 | void muls64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b) 72 | { 73 | uint64_t rh; 74 | 75 | mul64(plow, &rh, a, b); 76 | 77 | /* Adjust for signs. */ 78 | if(b < 0) { 79 | rh -= a; 80 | } 81 | if(a < 0) { 82 | rh -= b; 83 | } 84 | *phigh = rh; 85 | } 86 | #endif 87 | -------------------------------------------------------------------------------- /tcg/tcg-additional.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void attach_gen_opc_buf(void *buf); 4 | void attach_tcg(void *tcg_c); 5 | void attach_code_gen_prologue(void *prol); 6 | void attach_gen_opparam_buf(void *buf); 7 | void attach_ld_helpers(void *__ldb, void *__ldw, void *__ldl, void *__ldq); 8 | void attach_st_helpers(void *__stb, void *__stw, void *__stl, void *__stq); 9 | 10 | void set_temp_buf_offset(unsigned int offset); 11 | void set_tlb_table_n_0_rwa(int i, unsigned int read, unsigned int write, unsigned int addend); 12 | void set_tlb_table_n_0(int i, unsigned int offset); 13 | void set_TARGET_PAGE_BITS(int val); 14 | void set_sizeof_CPUTLBEntry(unsigned int sz); 15 | void set_tlb_entry_addr_rwu(unsigned int read, unsigned int write, unsigned int addend); 16 | 17 | void attach_malloc(void *malloc_callback); 18 | void attach_realloc(void *reall); 19 | void attach_free(void *free_callback); 20 | -------------------------------------------------------------------------------- /tcg/tcg-gvec-desc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Generic vector operation descriptor 3 | * 4 | * Copyright (c) 2018 Linaro 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, see . 18 | */ 19 | 20 | #pragma once 21 | 22 | #include "../include/bit_helper.h" 23 | 24 | /* 25 | * This configuration allows MAXSZ to represent 2048 bytes, and 26 | * OPRSZ to match MAXSZ, or represent the smaller values 8, 16, or 32. 27 | * 28 | * Encode this with: 29 | * 0, 1, 3 -> 8, 16, 32 30 | * 2 -> maxsz 31 | * 32 | * This steals the input that would otherwise map to 24 to match maxsz. 33 | */ 34 | #define SIMD_MAXSZ_SHIFT 0 35 | #define SIMD_MAXSZ_BITS 8 36 | 37 | #define SIMD_OPRSZ_SHIFT (SIMD_MAXSZ_SHIFT + SIMD_MAXSZ_BITS) 38 | #define SIMD_OPRSZ_BITS 2 39 | 40 | #define SIMD_DATA_SHIFT (SIMD_OPRSZ_SHIFT + SIMD_OPRSZ_BITS) 41 | #define SIMD_DATA_BITS (32 - SIMD_DATA_SHIFT) 42 | 43 | /* Create a descriptor from components. */ 44 | uint32_t simd_desc(uint32_t oprsz, uint32_t maxsz, int32_t data); 45 | 46 | /* Extract the max vector size from a descriptor. */ 47 | static inline intptr_t simd_maxsz(uint32_t desc) 48 | { 49 | return extract32(desc, SIMD_MAXSZ_SHIFT, SIMD_MAXSZ_BITS) * 8 + 8; 50 | } 51 | 52 | /* Extract the operation size from a descriptor. */ 53 | static inline intptr_t simd_oprsz(uint32_t desc) 54 | { 55 | uint32_t f = extract32(desc, SIMD_OPRSZ_SHIFT, SIMD_OPRSZ_BITS); 56 | intptr_t o = f * 8 + 8; 57 | intptr_t m = simd_maxsz(desc); 58 | return f == 2 ? m : o; 59 | } 60 | 61 | /* Extract the operation-specific data from a descriptor. */ 62 | static inline int32_t simd_data(uint32_t desc) 63 | { 64 | return sextract32(desc, SIMD_DATA_SHIFT, SIMD_DATA_BITS); 65 | } 66 | -------------------------------------------------------------------------------- /tcg/tcg-memop.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny Code Generator for QEMU 3 | * 4 | * Copyright (c) 2008 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | /* Constants for qemu_ld and qemu_st for the Memory Operation field. */ 28 | typedef enum TCGMemOp { 29 | MO_8 = 0, 30 | MO_16 = 1, 31 | MO_32 = 2, 32 | MO_64 = 3, 33 | MO_SIZE = 3, /* Mask for the above. */ 34 | 35 | MO_SIGN = 4, /* Sign-extended, otherwise zero-extended. */ 36 | 37 | MO_BSWAP = 8, /* Host reverse endian. */ 38 | #ifdef HOST_WORDS_BIGENDIAN 39 | MO_LE = MO_BSWAP, 40 | MO_BE = 0, 41 | #else 42 | MO_LE = 0, 43 | MO_BE = MO_BSWAP, 44 | #endif 45 | #ifdef TARGET_WORDS_BIGENDIAN 46 | MO_TE = MO_BE, 47 | #else 48 | MO_TE = MO_LE, 49 | #endif 50 | 51 | /* MO_UNALN accesses are never checked for alignment. 52 | * MO_ALIGN accesses will result in a call to the CPU's 53 | * do_unaligned_access hook if the guest address is not aligned. 54 | * The default depends on whether the target CPU defines ALIGNED_ONLY. 55 | * 56 | * Some architectures (e.g. ARMv8) need the address which is aligned 57 | * to a size more than the size of the memory access. 58 | * Some architectures (e.g. SPARCv9) need an address which is aligned, 59 | * but less strictly than the natural alignment. 60 | * 61 | * MO_ALIGN supposes the alignment size is the size of a memory access. 62 | * 63 | * There are three options: 64 | * - unaligned access permitted (MO_UNALN). 65 | * - an alignment to the size of an access (MO_ALIGN); 66 | * - an alignment to a specified size, which may be more or less than 67 | * the access size (MO_ALIGN_x where 'x' is a size in bytes); 68 | */ 69 | MO_ASHIFT = 4, 70 | MO_AMASK = 7 << MO_ASHIFT, 71 | #ifdef ALIGNED_ONLY 72 | MO_ALIGN = 0, 73 | MO_UNALN = MO_AMASK, 74 | #else 75 | MO_ALIGN = MO_AMASK, 76 | MO_UNALN = 0, 77 | #endif 78 | MO_ALIGN_2 = 1 << MO_ASHIFT, 79 | MO_ALIGN_4 = 2 << MO_ASHIFT, 80 | MO_ALIGN_8 = 3 << MO_ASHIFT, 81 | MO_ALIGN_16 = 4 << MO_ASHIFT, 82 | MO_ALIGN_32 = 5 << MO_ASHIFT, 83 | MO_ALIGN_64 = 6 << MO_ASHIFT, 84 | 85 | /* Combinations of the above, for ease of use. */ 86 | MO_UB = MO_8, 87 | MO_UW = MO_16, 88 | MO_UL = MO_32, 89 | MO_SB = MO_SIGN | MO_8, 90 | MO_SW = MO_SIGN | MO_16, 91 | MO_SL = MO_SIGN | MO_32, 92 | MO_Q = MO_64, 93 | 94 | MO_LEUW = MO_LE | MO_UW, 95 | MO_LEUL = MO_LE | MO_UL, 96 | MO_LESW = MO_LE | MO_SW, 97 | MO_LESL = MO_LE | MO_SL, 98 | MO_LEQ = MO_LE | MO_Q, 99 | 100 | MO_BEUW = MO_BE | MO_UW, 101 | MO_BEUL = MO_BE | MO_UL, 102 | MO_BESW = MO_BE | MO_SW, 103 | MO_BESL = MO_BE | MO_SL, 104 | MO_BEQ = MO_BE | MO_Q, 105 | 106 | MO_TEUW = MO_TE | MO_UW, 107 | MO_TEUL = MO_TE | MO_UL, 108 | MO_TESW = MO_TE | MO_SW, 109 | MO_TESL = MO_TE | MO_SL, 110 | MO_TEQ = MO_TE | MO_Q, 111 | 112 | MO_SSIZE = MO_SIZE | MO_SIGN, 113 | } TCGMemOp; 114 | -------------------------------------------------------------------------------- /tcg/tcg-mo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny Code Generator for QEMU 3 | * 4 | * Copyright (c) 2008 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | typedef enum { 28 | /* Used to indicate the type of accesses on which ordering 29 | is to be ensured. Modeled after SPARC barriers. 30 | 31 | This is of the form TCG_MO_A_B where A is before B in program order. 32 | */ 33 | TCG_MO_LD_LD = 0x01, 34 | TCG_MO_ST_LD = 0x02, 35 | TCG_MO_LD_ST = 0x04, 36 | TCG_MO_ST_ST = 0x08, 37 | TCG_MO_ALL = 0x0F, /* OR of the above */ 38 | 39 | /* Used to indicate the kind of ordering which is to be ensured by the 40 | instruction. These types are derived from x86/aarch64 instructions. 41 | It should be noted that these are different from C11 semantics. */ 42 | TCG_BAR_LDAQ = 0x10, /* Following ops will not come forward */ 43 | TCG_BAR_STRL = 0x20, /* Previous ops will not be delayed */ 44 | TCG_BAR_SC = 0x30, /* No ops cross barrier; OR of the above */ 45 | } TCGBar; 46 | -------------------------------------------------------------------------------- /tcg/tcg-runtime.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny Code Generator for QEMU 3 | * 4 | * Copyright (c) 2008 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include "host-utils.h" 27 | 28 | /* 32-bit helpers */ 29 | 30 | uint32_t tcg_helper_clrsb_i32(uint32_t arg) 31 | { 32 | return clrsb32(arg); 33 | } 34 | 35 | uint32_t tcg_helper_clz_i32(uint32_t arg, uint32_t zero_val) 36 | { 37 | return arg ? clz32(arg) : zero_val; 38 | } 39 | 40 | int32_t tcg_helper_div_i32(int32_t arg1, int32_t arg2) 41 | { 42 | return arg1 / arg2; 43 | } 44 | 45 | int32_t tcg_helper_rem_i32(int32_t arg1, int32_t arg2) 46 | { 47 | return arg1 % arg2; 48 | } 49 | 50 | uint32_t tcg_helper_divu_i32(uint32_t arg1, uint32_t arg2) 51 | { 52 | return arg1 / arg2; 53 | } 54 | 55 | uint32_t tcg_helper_remu_i32(uint32_t arg1, uint32_t arg2) 56 | { 57 | return arg1 % arg2; 58 | } 59 | 60 | /* 64-bit helpers */ 61 | 62 | uint64_t tcg_helper_shl_i64(uint64_t arg1, uint64_t arg2) 63 | { 64 | return arg1 << arg2; 65 | } 66 | 67 | uint64_t tcg_helper_shr_i64(uint64_t arg1, uint64_t arg2) 68 | { 69 | return arg1 >> arg2; 70 | } 71 | 72 | int64_t tcg_helper_sar_i64(int64_t arg1, int64_t arg2) 73 | { 74 | return arg1 >> arg2; 75 | } 76 | 77 | int64_t tcg_helper_div_i64(int64_t arg1, int64_t arg2) 78 | { 79 | return arg1 / arg2; 80 | } 81 | 82 | int64_t tcg_helper_rem_i64(int64_t arg1, int64_t arg2) 83 | { 84 | return arg1 % arg2; 85 | } 86 | 87 | int64_t tcg_helper_mulsh_i64(int64_t arg1, int64_t arg2) 88 | { 89 | uint64_t l, h; 90 | muls64(&l, &h, arg1, arg2); 91 | return h; 92 | } 93 | 94 | uint64_t tcg_helper_divu_i64(uint64_t arg1, uint64_t arg2) 95 | { 96 | return arg1 / arg2; 97 | } 98 | 99 | uint64_t tcg_helper_remu_i64(uint64_t arg1, uint64_t arg2) 100 | { 101 | return arg1 % arg2; 102 | } 103 | 104 | uint64_t tcg_helper_muluh_i64(uint64_t arg1, uint64_t arg2) 105 | { 106 | uint64_t l, h; 107 | mulu64(&l, &h, arg1, arg2); 108 | return h; 109 | } 110 | 111 | uint64_t tcg_helper_clrsb_i64(uint64_t arg) 112 | { 113 | return clrsb64(arg); 114 | } 115 | 116 | uint64_t tcg_helper_clz_i64(uint64_t arg, uint64_t zero_val) 117 | { 118 | return arg ? clz64(arg) : zero_val; 119 | } 120 | -------------------------------------------------------------------------------- /tlib-alloc.c: -------------------------------------------------------------------------------- 1 | #if defined(__linux__) 2 | #define _GNU_SOURCE 3 | #endif 4 | #if defined(__linux__) || defined(__APPLE__) 5 | #include 6 | #elif defined(_WIN32) 7 | #include 8 | #include 9 | #endif 10 | #if defined(__APPLE__) 11 | #include 12 | #include 13 | #endif 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "infrastructure.h" 21 | #include "tlib-alloc.h" 22 | #include "tcg/tcg.h" 23 | 24 | uint8_t *tcg_rw_buffer; 25 | uint8_t *tcg_rx_buffer; 26 | 27 | uint64_t code_gen_buffer_size; 28 | 29 | intptr_t tcg_wx_diff; 30 | 31 | #if (defined(__linux__) || defined(__APPLE__)) && (!defined(__aarch64__)) 32 | static bool alloc_code_gen_buf_unified(uint64_t size) 33 | { 34 | // No write/execute splitting 35 | int flags = MAP_ANON | MAP_PRIVATE; 36 | void *rwx = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, flags, -1, 0); 37 | if(rwx == MAP_FAILED) { 38 | tlib_printf(LOG_LEVEL_DEBUG, "Failed to mmap rwx buffer, error: %s", strerror(errno)); 39 | return false; 40 | } 41 | tcg_rx_buffer = tcg_rw_buffer = rwx; 42 | tcg_wx_diff = 0; 43 | return true; 44 | } 45 | #endif 46 | #if (defined(__linux__) || defined(__APPLE__)) 47 | void free_code_gen_buf() 48 | { 49 | // If not using split buffers the second one will fail, but this causes no issues 50 | munmap(tcg_rw_buffer, code_gen_buffer_size + TCG_PROLOGUE_SIZE); 51 | munmap(tcg_rx_buffer, code_gen_buffer_size + TCG_PROLOGUE_SIZE); 52 | } 53 | #endif 54 | 55 | #if defined(__linux__) && defined(__aarch64__) 56 | static bool alloc_code_gen_buf_split(uint64_t size) 57 | { 58 | // Split writable and executable mapping 59 | int fd = memfd_create("code_gen_buffer", 0); 60 | if(fd == -1) { 61 | tlib_abortf("Failed to create backing file for code_gen_buffer, error: %s", strerror(errno)); 62 | } 63 | if(ftruncate(fd, size) == -1) { 64 | tlib_printf(LOG_LEVEL_DEBUG, "Failed to allocate %u bytes for codegen buffer, error: %s", size, strerror(errno)); 65 | // Cleanup the fd 66 | close(fd); 67 | return false; 68 | } 69 | // Backing file creation succeded, mmap buffers 70 | int flags = MAP_SHARED; 71 | void *rw = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, fd, 0); 72 | if(rw == MAP_FAILED) { 73 | tlib_printf(LOG_LEVEL_DEBUG, "Failed to mmap rw buffer, error: %s", strerror(errno)); 74 | close(fd); 75 | return false; 76 | } 77 | void *rx = mmap(NULL, size, PROT_READ | PROT_EXEC, flags, fd, 0); 78 | if(rw == MAP_FAILED) { 79 | tlib_printf(LOG_LEVEL_DEBUG, "Failed to mmap rx buffer, error: %s", strerror(errno)); 80 | close(fd); 81 | // unmap region so it does not leak 82 | munmap(rw, size); 83 | return false; 84 | } 85 | // Mapping succeded, we can now close the fd safely 86 | close(fd); 87 | tcg_rw_buffer = (uint8_t *)rw; 88 | tcg_rx_buffer = (uint8_t *)rx; 89 | tcg_wx_diff = tcg_rw_buffer - tcg_rx_buffer; 90 | return true; 91 | } 92 | #elif defined(__APPLE__) && defined(__aarch64__) 93 | static bool alloc_code_gen_buf_split(uint64_t size) 94 | { 95 | mach_vm_address_t rw, rx; 96 | 97 | int flags = MAP_ANONYMOUS | MAP_SHARED; 98 | rw = (mach_vm_address_t)mmap(NULL, size, PROT_READ | PROT_WRITE, flags, -1, 0); 99 | if(rw == (mach_vm_address_t)MAP_FAILED) { 100 | tlib_printf(LOG_LEVEL_ERROR, "Failed to mmap rw buffer, error: %s", strerror(errno)); 101 | return false; 102 | } 103 | rx = 0; 104 | vm_prot_t current_prot, max_prot; 105 | kern_return_t res = mach_vm_remap(mach_task_self(), &rx, size, 0, VM_FLAGS_ANYWHERE, mach_task_self(), rw, false, 106 | ¤t_prot, &max_prot, VM_INHERIT_NONE); 107 | if(res != KERN_SUCCESS) { 108 | tlib_printf(LOG_LEVEL_ERROR, "Failed to mach_vm_remap rx buffer, error: %i", res); 109 | munmap((void *)rw, size); 110 | return false; 111 | } 112 | 113 | if(mprotect((void *)rx, size, PROT_READ | PROT_EXEC) != 0) { 114 | tlib_printf(LOG_LEVEL_ERROR, "Failed to mprotect rx buffer"); 115 | // Unmap the memory regions so they don't leak 116 | munmap((void *)rw, size); 117 | munmap((void *)rx, size); 118 | return false; 119 | } 120 | 121 | tcg_rw_buffer = (uint8_t *)rw; 122 | tcg_rx_buffer = (uint8_t *)rx; 123 | tcg_wx_diff = tcg_rw_buffer - tcg_rx_buffer; 124 | return true; 125 | } 126 | #elif defined(_WIN32) 127 | static bool map_exec(void *addr, long size) 128 | { 129 | DWORD old_protect; 130 | return (bool)VirtualProtect(addr, size, PAGE_EXECUTE_READWRITE, &old_protect); 131 | } 132 | static bool alloc_code_gen_buf_unified(uint64_t size) 133 | { 134 | uint8_t *buf = tlib_malloc(size); 135 | if(buf == NULL) { 136 | return false; 137 | } 138 | if(!map_exec(buf, size)) { 139 | tlib_printf(LOG_LEVEL_ERROR, "Failed to VirtualProtect code_gen_buffer"); 140 | return false; 141 | } 142 | tcg_rw_buffer = tcg_rx_buffer = buf; 143 | tcg_wx_diff = 0; 144 | return true; 145 | } 146 | void free_code_gen_buf() 147 | { 148 | tlib_free(tcg_rw_buffer); 149 | } 150 | #endif 151 | 152 | bool alloc_code_gen_buf(uint64_t size) 153 | { 154 | #if defined(__aarch64__) 155 | return alloc_code_gen_buf_split(size); 156 | #else 157 | return alloc_code_gen_buf_unified(size); 158 | #endif 159 | } 160 | --------------------------------------------------------------------------------