166e63ce3Schristos /* frv simulator support code
2*1424dfb3Schristos Copyright (C) 1999-2020 Free Software Foundation, Inc.
366e63ce3Schristos Contributed by Red Hat.
466e63ce3Schristos
566e63ce3Schristos This file is part of the GNU simulators.
666e63ce3Schristos
766e63ce3Schristos This program is free software; you can redistribute it and/or modify
866e63ce3Schristos it under the terms of the GNU General Public License as published by
966e63ce3Schristos the Free Software Foundation; either version 3 of the License, or
1066e63ce3Schristos (at your option) any later version.
1166e63ce3Schristos
1266e63ce3Schristos This program is distributed in the hope that it will be useful,
1366e63ce3Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
1466e63ce3Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1566e63ce3Schristos GNU General Public License for more details.
1666e63ce3Schristos
1766e63ce3Schristos You should have received a copy of the GNU General Public License
1866e63ce3Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */
1966e63ce3Schristos
2066e63ce3Schristos #define WANT_CPU
2166e63ce3Schristos #define WANT_CPU_FRVBF
2266e63ce3Schristos
2366e63ce3Schristos #include "sim-main.h"
2466e63ce3Schristos #include "bfd.h"
2566e63ce3Schristos
2666e63ce3Schristos /* Initialize the frv simulator. */
2766e63ce3Schristos void
frv_initialize(SIM_CPU * current_cpu,SIM_DESC sd)2866e63ce3Schristos frv_initialize (SIM_CPU *current_cpu, SIM_DESC sd)
2966e63ce3Schristos {
3066e63ce3Schristos FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (current_cpu);
3166e63ce3Schristos PROFILE_DATA *p = CPU_PROFILE_DATA (current_cpu);
3266e63ce3Schristos FRV_CACHE *insn_cache = CPU_INSN_CACHE (current_cpu);
3366e63ce3Schristos FRV_CACHE *data_cache = CPU_DATA_CACHE (current_cpu);
3466e63ce3Schristos int insn_cache_enabled = CACHE_INITIALIZED (insn_cache);
3566e63ce3Schristos int data_cache_enabled = CACHE_INITIALIZED (data_cache);
3666e63ce3Schristos USI hsr0;
3766e63ce3Schristos
3866e63ce3Schristos /* Initialize the register control information first since some of the
3966e63ce3Schristos register values are used in further configuration. */
4066e63ce3Schristos frv_register_control_init (current_cpu);
4166e63ce3Schristos
4266e63ce3Schristos /* We need to ensure that the caches are initialized even if they are not
4366e63ce3Schristos initially enabled (via commandline) because they can be enabled by
4466e63ce3Schristos software. */
4566e63ce3Schristos if (! insn_cache_enabled)
4666e63ce3Schristos frv_cache_init (current_cpu, CPU_INSN_CACHE (current_cpu));
4766e63ce3Schristos if (! data_cache_enabled)
4866e63ce3Schristos frv_cache_init (current_cpu, CPU_DATA_CACHE (current_cpu));
4966e63ce3Schristos
5066e63ce3Schristos /* Set the default cpu frequency if it has not been set on the command
5166e63ce3Schristos line. */
5266e63ce3Schristos if (PROFILE_CPU_FREQ (p) == 0)
5366e63ce3Schristos PROFILE_CPU_FREQ (p) = 266000000; /* 266MHz */
5466e63ce3Schristos
5566e63ce3Schristos /* Allocate one cache line of memory containing the address of the reset
5666e63ce3Schristos register Use the largest of the insn cache line size and the data cache
5766e63ce3Schristos line size. */
5866e63ce3Schristos {
5966e63ce3Schristos int addr = RSTR_ADDRESS;
6066e63ce3Schristos void *aligned_buffer;
6166e63ce3Schristos int bytes;
6266e63ce3Schristos
6366e63ce3Schristos if (CPU_INSN_CACHE (current_cpu)->line_size
6466e63ce3Schristos > CPU_DATA_CACHE (current_cpu)->line_size)
6566e63ce3Schristos bytes = CPU_INSN_CACHE (current_cpu)->line_size;
6666e63ce3Schristos else
6766e63ce3Schristos bytes = CPU_DATA_CACHE (current_cpu)->line_size;
6866e63ce3Schristos
6966e63ce3Schristos /* 'bytes' is a power of 2. Calculate the starting address of the
7066e63ce3Schristos cache line. */
7166e63ce3Schristos addr &= ~(bytes - 1);
7266e63ce3Schristos aligned_buffer = zalloc (bytes); /* clear */
7366e63ce3Schristos sim_core_attach (sd, NULL, 0, access_read_write, 0, addr, bytes,
7466e63ce3Schristos 0, NULL, aligned_buffer);
7566e63ce3Schristos }
7666e63ce3Schristos
7766e63ce3Schristos PROFILE_INFO_CPU_CALLBACK(p) = frv_profile_info;
7866e63ce3Schristos ps->insn_fetch_address = -1;
7966e63ce3Schristos ps->branch_address = -1;
8066e63ce3Schristos
8166e63ce3Schristos cgen_init_accurate_fpu (current_cpu, CGEN_CPU_FPU (current_cpu),
8266e63ce3Schristos frvbf_fpu_error);
8366e63ce3Schristos
8466e63ce3Schristos /* Now perform power-on reset. */
8566e63ce3Schristos frv_power_on_reset (current_cpu);
8666e63ce3Schristos
8766e63ce3Schristos /* Make sure that HSR0.ICE and HSR0.DCE are set properly. */
8866e63ce3Schristos hsr0 = GET_HSR0 ();
8966e63ce3Schristos if (insn_cache_enabled)
9066e63ce3Schristos SET_HSR0_ICE (hsr0);
9166e63ce3Schristos else
9266e63ce3Schristos CLEAR_HSR0_ICE (hsr0);
9366e63ce3Schristos if (data_cache_enabled)
9466e63ce3Schristos SET_HSR0_DCE (hsr0);
9566e63ce3Schristos else
9666e63ce3Schristos CLEAR_HSR0_DCE (hsr0);
9766e63ce3Schristos SET_HSR0 (hsr0);
9866e63ce3Schristos }
9966e63ce3Schristos
10066e63ce3Schristos /* Initialize the frv simulator. */
10166e63ce3Schristos void
frv_term(SIM_DESC sd)10266e63ce3Schristos frv_term (SIM_DESC sd)
10366e63ce3Schristos {
10466e63ce3Schristos /* If the timer is enabled, and model profiling was not originally enabled,
10566e63ce3Schristos then turn it off again. This is the only place we can currently gain
10666e63ce3Schristos control to do this. */
10766e63ce3Schristos if (frv_interrupt_state.timer.enabled && ! frv_save_profile_model_p)
108c03b94e9Schristos sim_profile_set_option (sd, "-model", PROFILE_MODEL_IDX, "0");
10966e63ce3Schristos }
11066e63ce3Schristos
11166e63ce3Schristos /* Perform a power on reset. */
11266e63ce3Schristos void
frv_power_on_reset(SIM_CPU * cpu)11366e63ce3Schristos frv_power_on_reset (SIM_CPU *cpu)
11466e63ce3Schristos {
11566e63ce3Schristos /* GR, FR and CPR registers are undefined at initialization time. */
11666e63ce3Schristos frv_initialize_spr (cpu);
11766e63ce3Schristos /* Initialize the RSTR register (in memory). */
11866e63ce3Schristos if (frv_cache_enabled (CPU_DATA_CACHE (cpu)))
11966e63ce3Schristos frvbf_mem_set_SI (cpu, CPU_PC_GET (cpu), RSTR_ADDRESS, RSTR_INITIAL_VALUE);
12066e63ce3Schristos else
12166e63ce3Schristos SETMEMSI (cpu, CPU_PC_GET (cpu), RSTR_ADDRESS, RSTR_INITIAL_VALUE);
12266e63ce3Schristos }
12366e63ce3Schristos
12466e63ce3Schristos /* Perform a hardware reset. */
12566e63ce3Schristos void
frv_hardware_reset(SIM_CPU * cpu)12666e63ce3Schristos frv_hardware_reset (SIM_CPU *cpu)
12766e63ce3Schristos {
12866e63ce3Schristos /* GR, FR and CPR registers are undefined at hardware reset. */
12966e63ce3Schristos frv_initialize_spr (cpu);
13066e63ce3Schristos /* Reset the RSTR register (in memory). */
13166e63ce3Schristos if (frv_cache_enabled (CPU_DATA_CACHE (cpu)))
13266e63ce3Schristos frvbf_mem_set_SI (cpu, CPU_PC_GET (cpu), RSTR_ADDRESS, RSTR_HARDWARE_RESET);
13366e63ce3Schristos else
13466e63ce3Schristos SETMEMSI (cpu, CPU_PC_GET (cpu), RSTR_ADDRESS, RSTR_HARDWARE_RESET);
13566e63ce3Schristos /* Reset the insn and data caches. */
13666e63ce3Schristos frv_cache_invalidate_all (CPU_INSN_CACHE (cpu), 0/* no flush */);
13766e63ce3Schristos frv_cache_invalidate_all (CPU_DATA_CACHE (cpu), 0/* no flush */);
13866e63ce3Schristos }
13966e63ce3Schristos
14066e63ce3Schristos /* Perform a software reset. */
14166e63ce3Schristos void
frv_software_reset(SIM_CPU * cpu)14266e63ce3Schristos frv_software_reset (SIM_CPU *cpu)
14366e63ce3Schristos {
14466e63ce3Schristos /* GR, FR and CPR registers are undefined at software reset. */
14566e63ce3Schristos frv_reset_spr (cpu);
14666e63ce3Schristos /* Reset the RSTR register (in memory). */
14766e63ce3Schristos if (frv_cache_enabled (CPU_DATA_CACHE (cpu)))
14866e63ce3Schristos frvbf_mem_set_SI (cpu, CPU_PC_GET (cpu), RSTR_ADDRESS, RSTR_SOFTWARE_RESET);
14966e63ce3Schristos else
15066e63ce3Schristos SETMEMSI (cpu, CPU_PC_GET (cpu), RSTR_ADDRESS, RSTR_SOFTWARE_RESET);
15166e63ce3Schristos }
152