├── .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 |
--------------------------------------------------------------------------------