|  | /* The common simulator framework for GDB, the GNU Debugger. | 
|  |  | 
|  | Copyright 2002-2023 Free Software Foundation, Inc. | 
|  |  | 
|  | Contributed by Andrew Cagney and Red Hat. | 
|  |  | 
|  | This file is part of GDB. | 
|  |  | 
|  | This program is free software; you can redistribute it and/or modify | 
|  | it under the terms of the GNU General Public License as published by | 
|  | the Free Software Foundation; either version 3 of the License, or | 
|  | (at your option) any later version. | 
|  |  | 
|  | This program is distributed in the hope that it will be useful, | 
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | GNU General Public License for more details. | 
|  |  | 
|  | You should have received a copy of the GNU General Public License | 
|  | along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ | 
|  |  | 
|  |  | 
|  | #ifndef SIM_CORE_H | 
|  | #define SIM_CORE_H | 
|  |  | 
|  | #include "symcat.h" | 
|  |  | 
|  | /* core signals (error conditions) | 
|  | Define SIM_CORE_SIGNAL to catch these signals - see sim-core.c for | 
|  | details.  */ | 
|  |  | 
|  | typedef enum { | 
|  | sim_core_unmapped_signal, | 
|  | sim_core_unaligned_signal, | 
|  | nr_sim_core_signals, | 
|  | } sim_core_signals; | 
|  |  | 
|  | /* Type of SIM_CORE_SIGNAL handler.  */ | 
|  | typedef void (SIM_CORE_SIGNAL_FN) | 
|  | (SIM_DESC sd, sim_cpu *cpu, sim_cia cia, unsigned map, int nr_bytes, | 
|  | address_word addr, transfer_type transfer, sim_core_signals sig); | 
|  |  | 
|  | extern SIM_CORE_SIGNAL_FN sim_core_signal; | 
|  |  | 
|  |  | 
|  | /* basic types */ | 
|  |  | 
|  | typedef struct _sim_core_mapping sim_core_mapping; | 
|  | struct _sim_core_mapping { | 
|  | /* common */ | 
|  | int level; | 
|  | int space; | 
|  | unsigned_word base; | 
|  | unsigned_word bound; | 
|  | unsigned_word nr_bytes; | 
|  | unsigned mask; | 
|  | /* memory map */ | 
|  | void *free_buffer; | 
|  | void *buffer; | 
|  | /* callback map */ | 
|  | struct hw *device; | 
|  | /* tracing */ | 
|  | int trace; | 
|  | /* growth */ | 
|  | sim_core_mapping *next; | 
|  | }; | 
|  |  | 
|  | typedef struct _sim_core_map sim_core_map; | 
|  | struct _sim_core_map { | 
|  | sim_core_mapping *first; | 
|  | }; | 
|  |  | 
|  |  | 
|  | typedef struct _sim_core_common { | 
|  | sim_core_map map[nr_maps]; | 
|  | } sim_core_common; | 
|  |  | 
|  |  | 
|  | /* Main core structure */ | 
|  |  | 
|  | typedef struct _sim_core sim_core; | 
|  | struct _sim_core { | 
|  | sim_core_common common; | 
|  | address_word byte_xor; /* apply xor universally */ | 
|  | }; | 
|  |  | 
|  |  | 
|  | /* Per CPU distributed component of the core.  At present this is | 
|  | mostly a clone of the global core data structure. */ | 
|  |  | 
|  | typedef struct _sim_cpu_core { | 
|  | sim_core_common common; | 
|  | address_word byte_xor[WITH_XOR_ENDIAN + 1]; /* +1 to avoid zero-sized array */ | 
|  | } sim_cpu_core; | 
|  |  | 
|  |  | 
|  | /* Install the "core" module.  */ | 
|  |  | 
|  | extern SIM_RC sim_core_install (SIM_DESC sd); | 
|  |  | 
|  |  | 
|  |  | 
|  | /* Create a memory region within the core. | 
|  |  | 
|  | CPU - when non NULL, specifes the single processor that the memory | 
|  | space is to be attached to. (INIMPLEMENTED). | 
|  |  | 
|  | LEVEL - specifies the ordering of the memory region.  Lower regions | 
|  | are searched first.  Within a level, memory regions can not | 
|  | overlap. | 
|  |  | 
|  | MAPMASK - Bitmask specifying the memory maps that the region is to | 
|  | be attached to.  Typically the enums sim-basics.h:access_* are used. | 
|  |  | 
|  | ADDRESS_SPACE - For device regions, a MAP:ADDRESS pair is | 
|  | translated into ADDRESS_SPACE:OFFSET before being passed to the | 
|  | client device. | 
|  |  | 
|  | MODULO - Specifies that accesses to the region [ADDR .. ADDR+NR_BYTES) | 
|  | should be mapped onto the sub region [ADDR .. ADDR+MODULO).  The modulo | 
|  | value must be a power of two. | 
|  |  | 
|  | DEVICE - When non NULL, indicates that this is a callback memory | 
|  | space and specified device's memory callback handler should be | 
|  | called. | 
|  |  | 
|  | OPTIONAL_BUFFER - when non NULL, specifies the buffer to use for | 
|  | data read & written to the region.  Normally a more efficient | 
|  | internal structure is used.  It is assumed that buffer is allocated | 
|  | such that the byte alignmed of OPTIONAL_BUFFER matches ADDR vis | 
|  | (OPTIONAL_BUFFER % 8) == (ADDR % 8)).  It is defined to be a sub-optimal | 
|  | hook that allows clients to do nasty things that the interface doesn't | 
|  | accomodate. */ | 
|  |  | 
|  | extern void sim_core_attach | 
|  | (SIM_DESC sd, | 
|  | sim_cpu *cpu, | 
|  | int level, | 
|  | unsigned mapmask, | 
|  | int address_space, | 
|  | address_word addr, | 
|  | address_word nr_bytes, | 
|  | unsigned modulo, | 
|  | struct hw *client, | 
|  | void *optional_buffer); | 
|  |  | 
|  |  | 
|  | /* Delete a memory section within the core. | 
|  |  | 
|  | */ | 
|  |  | 
|  | extern void sim_core_detach | 
|  | (SIM_DESC sd, | 
|  | sim_cpu *cpu, | 
|  | int level, | 
|  | int address_space, | 
|  | address_word addr); | 
|  |  | 
|  |  | 
|  | /* Variable sized read/write | 
|  |  | 
|  | Transfer a variable sized block of raw data between the host and | 
|  | target.  Should any problems occur, the number of bytes | 
|  | successfully transfered is returned. | 
|  |  | 
|  | No host/target byte endian conversion is performed.  No xor-endian | 
|  | conversion is performed. | 
|  |  | 
|  | If CPU argument, when non NULL, specifies the processor specific | 
|  | address map that is to be used in the transfer. */ | 
|  |  | 
|  |  | 
|  | extern unsigned sim_core_read_buffer | 
|  | (SIM_DESC sd, | 
|  | sim_cpu *cpu, | 
|  | unsigned map, | 
|  | void *buffer, | 
|  | address_word addr, | 
|  | unsigned nr_bytes); | 
|  |  | 
|  | extern unsigned sim_core_write_buffer | 
|  | (SIM_DESC sd, | 
|  | sim_cpu *cpu, | 
|  | unsigned map, | 
|  | const void *buffer, | 
|  | address_word addr, | 
|  | unsigned nr_bytes); | 
|  |  | 
|  |  | 
|  |  | 
|  | /* Configure the core's XOR endian transfer mode.  Only applicable | 
|  | when WITH_XOR_ENDIAN is enabled. | 
|  |  | 
|  | Targets suporting XOR endian, shall notify the core of any changes | 
|  | in state via this call. | 
|  |  | 
|  | The CPU argument, when non NULL, specifes the single processor that | 
|  | the xor-endian configuration is to be applied to. */ | 
|  |  | 
|  | extern void sim_core_set_xor | 
|  | (SIM_DESC sd, | 
|  | sim_cpu *cpu, | 
|  | int is_xor); | 
|  |  | 
|  |  | 
|  | /* XOR version of variable sized read/write. | 
|  |  | 
|  | Transfer a variable sized block of raw data between the host and | 
|  | target.  Should any problems occur, the number of bytes | 
|  | successfully transfered is returned. | 
|  |  | 
|  | No host/target byte endian conversion is performed.  If applicable | 
|  | (WITH_XOR_ENDIAN and xor-endian set), xor-endian conversion *is* | 
|  | performed. | 
|  |  | 
|  | If CPU argument, when non NULL, specifies the processor specific | 
|  | address map that is to be used in the transfer. */ | 
|  |  | 
|  | extern unsigned sim_core_xor_read_buffer | 
|  | (SIM_DESC sd, | 
|  | sim_cpu *cpu, | 
|  | unsigned map, | 
|  | void *buffer, | 
|  | address_word addr, | 
|  | unsigned nr_bytes); | 
|  |  | 
|  | extern unsigned sim_core_xor_write_buffer | 
|  | (SIM_DESC sd, | 
|  | sim_cpu *cpu, | 
|  | unsigned map, | 
|  | const void *buffer, | 
|  | address_word addr, | 
|  | unsigned nr_bytes); | 
|  |  | 
|  |  | 
|  | /* Translate an address based on a map.  */ | 
|  |  | 
|  | extern void *sim_core_trans_addr | 
|  | (SIM_DESC sd, | 
|  | sim_cpu *cpu, | 
|  | unsigned map, | 
|  | address_word addr); | 
|  |  | 
|  |  | 
|  | /* Fixed sized, processor oriented, read/write. | 
|  |  | 
|  | Transfer a fixed amout of memory between the host and target.  The | 
|  | data transfered is translated from/to host to/from target byte | 
|  | order (including xor endian).  Should the transfer fail, the | 
|  | operation shall abort (no return). | 
|  |  | 
|  | ALIGNED assumes that the specified ADDRESS is correctly aligned | 
|  | for an N byte transfer (no alignment checks are made).  Passing an | 
|  | incorrectly aligned ADDRESS is erroneous. | 
|  |  | 
|  | UNALIGNED checks/modifies the ADDRESS according to the requirements | 
|  | of an N byte transfer. Action, as defined by WITH_ALIGNMENT, being | 
|  | taken should the check fail. | 
|  |  | 
|  | MISALIGNED transfers the data regardless. | 
|  |  | 
|  | Misaligned xor-endian accesses are broken into a sequence of | 
|  | transfers each <= WITH_XOR_ENDIAN bytes */ | 
|  |  | 
|  |  | 
|  | #define DECLARE_SIM_CORE_WRITE_N(ALIGNMENT,N,M) \ | 
|  | INLINE_SIM_CORE\ | 
|  | (void) sim_core_write_##ALIGNMENT##_##N \ | 
|  | (sim_cpu *cpu, \ | 
|  | sim_cia cia, \ | 
|  | unsigned map, \ | 
|  | address_word addr, \ | 
|  | unsigned_##M val); | 
|  |  | 
|  | DECLARE_SIM_CORE_WRITE_N(aligned,1,1) | 
|  | DECLARE_SIM_CORE_WRITE_N(aligned,2,2) | 
|  | DECLARE_SIM_CORE_WRITE_N(aligned,4,4) | 
|  | DECLARE_SIM_CORE_WRITE_N(aligned,8,8) | 
|  | DECLARE_SIM_CORE_WRITE_N(aligned,16,16) | 
|  |  | 
|  | #define sim_core_write_unaligned_1 sim_core_write_aligned_1 | 
|  | DECLARE_SIM_CORE_WRITE_N(unaligned,2,2) | 
|  | DECLARE_SIM_CORE_WRITE_N(unaligned,4,4) | 
|  | DECLARE_SIM_CORE_WRITE_N(unaligned,8,8) | 
|  | DECLARE_SIM_CORE_WRITE_N(unaligned,16,16) | 
|  |  | 
|  | DECLARE_SIM_CORE_WRITE_N(misaligned,3,4) | 
|  | DECLARE_SIM_CORE_WRITE_N(misaligned,5,8) | 
|  | DECLARE_SIM_CORE_WRITE_N(misaligned,6,8) | 
|  | DECLARE_SIM_CORE_WRITE_N(misaligned,7,8) | 
|  |  | 
|  | #define sim_core_write_1 sim_core_write_aligned_1 | 
|  | #define sim_core_write_2 sim_core_write_aligned_2 | 
|  | #define sim_core_write_4 sim_core_write_aligned_4 | 
|  | #define sim_core_write_8 sim_core_write_aligned_8 | 
|  | #define sim_core_write_16 sim_core_write_aligned_16 | 
|  |  | 
|  | #define sim_core_write_unaligned_word XCONCAT2(sim_core_write_unaligned_,WITH_TARGET_WORD_BITSIZE) | 
|  | #define sim_core_write_aligned_word XCONCAT2(sim_core_write_aligned_,WITH_TARGET_WORD_BITSIZE) | 
|  | #define sim_core_write_word XCONCAT2(sim_core_write_,WITH_TARGET_WORD_BITSIZE) | 
|  |  | 
|  | #undef DECLARE_SIM_CORE_WRITE_N | 
|  |  | 
|  |  | 
|  | #define DECLARE_SIM_CORE_READ_N(ALIGNMENT,N,M) \ | 
|  | INLINE_SIM_CORE\ | 
|  | (unsigned_##M) sim_core_read_##ALIGNMENT##_##N \ | 
|  | (sim_cpu *cpu, \ | 
|  | sim_cia cia, \ | 
|  | unsigned map, \ | 
|  | address_word addr); | 
|  |  | 
|  | DECLARE_SIM_CORE_READ_N(aligned,1,1) | 
|  | DECLARE_SIM_CORE_READ_N(aligned,2,2) | 
|  | DECLARE_SIM_CORE_READ_N(aligned,4,4) | 
|  | DECLARE_SIM_CORE_READ_N(aligned,8,8) | 
|  | DECLARE_SIM_CORE_READ_N(aligned,16,16) | 
|  |  | 
|  | #define sim_core_read_unaligned_1 sim_core_read_aligned_1 | 
|  | DECLARE_SIM_CORE_READ_N(unaligned,2,2) | 
|  | DECLARE_SIM_CORE_READ_N(unaligned,4,4) | 
|  | DECLARE_SIM_CORE_READ_N(unaligned,8,8) | 
|  | DECLARE_SIM_CORE_READ_N(unaligned,16,16) | 
|  |  | 
|  | DECLARE_SIM_CORE_READ_N(misaligned,3,4) | 
|  | DECLARE_SIM_CORE_READ_N(misaligned,5,8) | 
|  | DECLARE_SIM_CORE_READ_N(misaligned,6,8) | 
|  | DECLARE_SIM_CORE_READ_N(misaligned,7,8) | 
|  |  | 
|  |  | 
|  | #define sim_core_read_1 sim_core_read_aligned_1 | 
|  | #define sim_core_read_2 sim_core_read_aligned_2 | 
|  | #define sim_core_read_4 sim_core_read_aligned_4 | 
|  | #define sim_core_read_8 sim_core_read_aligned_8 | 
|  | #define sim_core_read_16 sim_core_read_aligned_16 | 
|  |  | 
|  | #define sim_core_read_unaligned_word XCONCAT2(sim_core_read_unaligned_,WITH_TARGET_WORD_BITSIZE) | 
|  | #define sim_core_read_aligned_word XCONCAT2(sim_core_read_aligned_,WITH_TARGET_WORD_BITSIZE) | 
|  | #define sim_core_read_word XCONCAT2(sim_core_read_,WITH_TARGET_WORD_BITSIZE) | 
|  |  | 
|  | #undef DECLARE_SIM_CORE_READ_N | 
|  |  | 
|  | #endif |