14e98e3e1Schristos /* The common simulator framework for GDB, the GNU Debugger. 24e98e3e1Schristos 3*88241920Schristos Copyright 2002-2024 Free Software Foundation, Inc. 44e98e3e1Schristos 54e98e3e1Schristos Contributed by Andrew Cagney and Red Hat. 64e98e3e1Schristos 74e98e3e1Schristos This file is part of GDB. 84e98e3e1Schristos 94e98e3e1Schristos This program is free software; you can redistribute it and/or modify 104e98e3e1Schristos it under the terms of the GNU General Public License as published by 114e98e3e1Schristos the Free Software Foundation; either version 3 of the License, or 124e98e3e1Schristos (at your option) any later version. 134e98e3e1Schristos 144e98e3e1Schristos This program is distributed in the hope that it will be useful, 154e98e3e1Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 164e98e3e1Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 174e98e3e1Schristos GNU General Public License for more details. 184e98e3e1Schristos 194e98e3e1Schristos You should have received a copy of the GNU General Public License 204e98e3e1Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 214e98e3e1Schristos 224b169a6bSchristos /* This must come before any other includes. */ 234b169a6bSchristos #include "defs.h" 244b169a6bSchristos 254b169a6bSchristos #include "bfd.h" 264e98e3e1Schristos 274e98e3e1Schristos #include "sim-main.h" 284e98e3e1Schristos #include "sim-assert.h" 294e98e3e1Schristos 304e98e3e1Schristos 31ba340e45Schristos enum bfd_endian current_target_byte_order = BFD_ENDIAN_UNKNOWN; 324e98e3e1Schristos int current_stdio; 334e98e3e1Schristos 344e98e3e1Schristos enum sim_alignments current_alignment; 354e98e3e1Schristos 364e98e3e1Schristos #if defined (WITH_FLOATING_POINT) 374e98e3e1Schristos int current_floating_point; 384e98e3e1Schristos #endif 394e98e3e1Schristos 404e98e3e1Schristos 414e98e3e1Schristos 424e98e3e1Schristos /* map a byte order onto a textual string */ 434e98e3e1Schristos 444e98e3e1Schristos static const char * 45ba340e45Schristos config_byte_order_to_a (enum bfd_endian byte_order) 464e98e3e1Schristos { 474e98e3e1Schristos switch (byte_order) 484e98e3e1Schristos { 49ba340e45Schristos case BFD_ENDIAN_LITTLE: 504e98e3e1Schristos return "LITTLE_ENDIAN"; 51ba340e45Schristos case BFD_ENDIAN_BIG: 524e98e3e1Schristos return "BIG_ENDIAN"; 53ba340e45Schristos case BFD_ENDIAN_UNKNOWN: 54ba340e45Schristos return "UNKNOWN_ENDIAN"; 554e98e3e1Schristos } 564e98e3e1Schristos return "UNKNOWN"; 574e98e3e1Schristos } 584e98e3e1Schristos 594e98e3e1Schristos 604e98e3e1Schristos static const char * 614e98e3e1Schristos config_stdio_to_a (int stdio) 624e98e3e1Schristos { 634e98e3e1Schristos switch (stdio) 644e98e3e1Schristos { 654e98e3e1Schristos case DONT_USE_STDIO: 664e98e3e1Schristos return "DONT_USE_STDIO"; 674e98e3e1Schristos case DO_USE_STDIO: 684e98e3e1Schristos return "DO_USE_STDIO"; 694e98e3e1Schristos case 0: 704e98e3e1Schristos return "0"; 714e98e3e1Schristos } 724e98e3e1Schristos return "UNKNOWN"; 734e98e3e1Schristos } 744e98e3e1Schristos 754e98e3e1Schristos 764e98e3e1Schristos static const char * 774e98e3e1Schristos config_environment_to_a (enum sim_environment environment) 784e98e3e1Schristos { 794e98e3e1Schristos switch (environment) 804e98e3e1Schristos { 814e98e3e1Schristos case ALL_ENVIRONMENT: 824e98e3e1Schristos return "ALL_ENVIRONMENT"; 834e98e3e1Schristos case USER_ENVIRONMENT: 844e98e3e1Schristos return "USER_ENVIRONMENT"; 854e98e3e1Schristos case VIRTUAL_ENVIRONMENT: 864e98e3e1Schristos return "VIRTUAL_ENVIRONMENT"; 874e98e3e1Schristos case OPERATING_ENVIRONMENT: 884e98e3e1Schristos return "OPERATING_ENVIRONMENT"; 894e98e3e1Schristos } 904e98e3e1Schristos return "UNKNOWN"; 914e98e3e1Schristos } 924e98e3e1Schristos 934e98e3e1Schristos 944e98e3e1Schristos static const char * 954e98e3e1Schristos config_alignment_to_a (enum sim_alignments alignment) 964e98e3e1Schristos { 974e98e3e1Schristos switch (alignment) 984e98e3e1Schristos { 994e98e3e1Schristos case MIXED_ALIGNMENT: 1004e98e3e1Schristos return "MIXED_ALIGNMENT"; 1014e98e3e1Schristos case NONSTRICT_ALIGNMENT: 1024e98e3e1Schristos return "NONSTRICT_ALIGNMENT"; 1034e98e3e1Schristos case STRICT_ALIGNMENT: 1044e98e3e1Schristos return "STRICT_ALIGNMENT"; 1054e98e3e1Schristos case FORCED_ALIGNMENT: 1064e98e3e1Schristos return "FORCED_ALIGNMENT"; 1074e98e3e1Schristos } 1084e98e3e1Schristos return "UNKNOWN"; 1094e98e3e1Schristos } 1104e98e3e1Schristos 1114e98e3e1Schristos 1124e98e3e1Schristos #if defined (WITH_FLOATING_POINT) 1134e98e3e1Schristos static const char * 1144e98e3e1Schristos config_floating_point_to_a (int floating_point) 1154e98e3e1Schristos { 1164e98e3e1Schristos switch (floating_point) 1174e98e3e1Schristos { 1184e98e3e1Schristos case SOFT_FLOATING_POINT: 1194e98e3e1Schristos return "SOFT_FLOATING_POINT"; 1204e98e3e1Schristos case HARD_FLOATING_POINT: 1214e98e3e1Schristos return "HARD_FLOATING_POINT"; 1224e98e3e1Schristos case 0: 1234e98e3e1Schristos return "0"; 1244e98e3e1Schristos } 1254e98e3e1Schristos return "UNKNOWN"; 1264e98e3e1Schristos } 1274e98e3e1Schristos #endif 1284e98e3e1Schristos 1294e98e3e1Schristos /* Set the default environment, prior to parsing argv. */ 1304e98e3e1Schristos 1314e98e3e1Schristos void 1324e98e3e1Schristos sim_config_default (SIM_DESC sd) 1334e98e3e1Schristos { 1344e98e3e1Schristos /* Set the current environment to ALL_ENVIRONMENT to indicate none has been 1354e98e3e1Schristos selected yet. This is so that after parsing argv, we know whether the 1364e98e3e1Schristos environment was explicitly specified or not. */ 1374e98e3e1Schristos STATE_ENVIRONMENT (sd) = ALL_ENVIRONMENT; 1384e98e3e1Schristos } 1394e98e3e1Schristos 1404e98e3e1Schristos /* Complete and verify the simulation environment. */ 1414e98e3e1Schristos 1424e98e3e1Schristos SIM_RC 1434e98e3e1Schristos sim_config (SIM_DESC sd) 1444e98e3e1Schristos { 145ba340e45Schristos enum bfd_endian prefered_target_byte_order; 1464e98e3e1Schristos SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 1474e98e3e1Schristos 1484e98e3e1Schristos /* extract all relevant information */ 1494e98e3e1Schristos if (STATE_PROG_BFD (sd) == NULL 1504e98e3e1Schristos /* If we have a binary input file (presumably with specified 1514e98e3e1Schristos "--architecture"), it'll have no endianness. */ 1524e98e3e1Schristos || (!bfd_little_endian (STATE_PROG_BFD (sd)) 1534e98e3e1Schristos && !bfd_big_endian (STATE_PROG_BFD (sd)))) 154ba340e45Schristos prefered_target_byte_order = BFD_ENDIAN_UNKNOWN; 1554e98e3e1Schristos else 1564e98e3e1Schristos prefered_target_byte_order = (bfd_little_endian (STATE_PROG_BFD (sd)) 157ba340e45Schristos ? BFD_ENDIAN_LITTLE 158ba340e45Schristos : BFD_ENDIAN_BIG); 1594e98e3e1Schristos 1604e98e3e1Schristos /* set the target byte order */ 1614e98e3e1Schristos #if (WITH_TREE_PROPERTIES) 162ba340e45Schristos if (current_target_byte_order == BFD_ENDIAN_UNKNOWN) 1634e98e3e1Schristos current_target_byte_order 1644e98e3e1Schristos = (tree_find_boolean_property (root, "/options/little-endian?") 165ba340e45Schristos ? BFD_ENDIAN_LITTLE 166ba340e45Schristos : BFD_ENDIAN_BIG); 1674e98e3e1Schristos #endif 168ba340e45Schristos if (current_target_byte_order == BFD_ENDIAN_UNKNOWN 169ba340e45Schristos && prefered_target_byte_order != BFD_ENDIAN_UNKNOWN) 1704e98e3e1Schristos current_target_byte_order = prefered_target_byte_order; 171ba340e45Schristos if (current_target_byte_order == BFD_ENDIAN_UNKNOWN) 1724e98e3e1Schristos current_target_byte_order = WITH_TARGET_BYTE_ORDER; 1734e98e3e1Schristos 1744e98e3e1Schristos /* verify the target byte order */ 175ba340e45Schristos if (CURRENT_TARGET_BYTE_ORDER == BFD_ENDIAN_UNKNOWN) 1764e98e3e1Schristos { 1774e98e3e1Schristos sim_io_eprintf (sd, "Target byte order unspecified\n"); 1784e98e3e1Schristos return SIM_RC_FAIL; 1794e98e3e1Schristos } 1804e98e3e1Schristos if (CURRENT_TARGET_BYTE_ORDER != current_target_byte_order) 1814e98e3e1Schristos sim_io_eprintf (sd, "Target (%s) and configured (%s) byte order in conflict\n", 1824e98e3e1Schristos config_byte_order_to_a (current_target_byte_order), 1834e98e3e1Schristos config_byte_order_to_a (CURRENT_TARGET_BYTE_ORDER)); 184ba340e45Schristos if (prefered_target_byte_order != BFD_ENDIAN_UNKNOWN 1854e98e3e1Schristos && CURRENT_TARGET_BYTE_ORDER != prefered_target_byte_order) 1864e98e3e1Schristos sim_io_eprintf (sd, "Target (%s) and specified (%s) byte order in conflict\n", 1874e98e3e1Schristos config_byte_order_to_a (CURRENT_TARGET_BYTE_ORDER), 1884e98e3e1Schristos config_byte_order_to_a (prefered_target_byte_order)); 1894e98e3e1Schristos 1904e98e3e1Schristos 1914e98e3e1Schristos /* set the stdio */ 1924e98e3e1Schristos if (current_stdio == 0) 1934e98e3e1Schristos current_stdio = WITH_STDIO; 1944e98e3e1Schristos if (current_stdio == 0) 1954e98e3e1Schristos current_stdio = DO_USE_STDIO; 1964e98e3e1Schristos 1974e98e3e1Schristos /* verify the stdio */ 1984e98e3e1Schristos if (CURRENT_STDIO == 0) 1994e98e3e1Schristos { 2004e98e3e1Schristos sim_io_eprintf (sd, "Target standard IO unspecified\n"); 2014e98e3e1Schristos return SIM_RC_FAIL; 2024e98e3e1Schristos } 2034e98e3e1Schristos if (CURRENT_STDIO != current_stdio) 2044e98e3e1Schristos { 2054e98e3e1Schristos sim_io_eprintf (sd, "Target (%s) and configured (%s) standard IO in conflict\n", 2064e98e3e1Schristos config_stdio_to_a (CURRENT_STDIO), 2074e98e3e1Schristos config_stdio_to_a (current_stdio)); 2084e98e3e1Schristos return SIM_RC_FAIL; 2094e98e3e1Schristos } 2104e98e3e1Schristos 2114e98e3e1Schristos 2124e98e3e1Schristos /* check the value of MSB */ 2134e98e3e1Schristos if (WITH_TARGET_WORD_MSB != 0 2144e98e3e1Schristos && WITH_TARGET_WORD_MSB != (WITH_TARGET_WORD_BITSIZE - 1)) 2154e98e3e1Schristos { 2164e98e3e1Schristos sim_io_eprintf (sd, "Target bitsize (%d) contradicts target most significant bit (%d)\n", 2174e98e3e1Schristos WITH_TARGET_WORD_BITSIZE, WITH_TARGET_WORD_MSB); 2184e98e3e1Schristos return SIM_RC_FAIL; 2194e98e3e1Schristos } 2204e98e3e1Schristos 2214e98e3e1Schristos 2224e98e3e1Schristos /* set the environment */ 2234e98e3e1Schristos #if (WITH_TREE_PROPERTIES) 2244e98e3e1Schristos if (STATE_ENVIRONMENT (sd) == ALL_ENVIRONMENT) 2254e98e3e1Schristos { 2264e98e3e1Schristos const char *env = 2274e98e3e1Schristos tree_find_string_property (root, "/openprom/options/env"); 2284e98e3e1Schristos STATE_ENVIRONMENT (sd) = ((strcmp (env, "user") == 0 2294e98e3e1Schristos || strcmp (env, "uea") == 0) 2304e98e3e1Schristos ? USER_ENVIRONMENT 2314e98e3e1Schristos : (strcmp (env, "virtual") == 0 2324e98e3e1Schristos || strcmp (env, "vea") == 0) 2334e98e3e1Schristos ? VIRTUAL_ENVIRONMENT 2344e98e3e1Schristos : (strcmp (env, "operating") == 0 2354e98e3e1Schristos || strcmp (env, "oea") == 0) 2364e98e3e1Schristos ? OPERATING_ENVIRONMENT 2374e98e3e1Schristos : ALL_ENVIRONMENT); 2384e98e3e1Schristos } 2394e98e3e1Schristos #endif 2404e98e3e1Schristos if (STATE_ENVIRONMENT (sd) == ALL_ENVIRONMENT) 241ba340e45Schristos STATE_ENVIRONMENT (sd) = (WITH_ENVIRONMENT != ALL_ENVIRONMENT ? 242ba340e45Schristos WITH_ENVIRONMENT : USER_ENVIRONMENT); 2434e98e3e1Schristos 2444e98e3e1Schristos 2454e98e3e1Schristos /* set the alignment */ 2464e98e3e1Schristos #if (WITH_TREE_PROPERTIES) 2474e98e3e1Schristos if (current_alignment == 0) 2484e98e3e1Schristos current_alignment = 2494e98e3e1Schristos (tree_find_boolean_property (root, "/openprom/options/strict-alignment?") 2504e98e3e1Schristos ? STRICT_ALIGNMENT 2514e98e3e1Schristos : NONSTRICT_ALIGNMENT); 2524e98e3e1Schristos #endif 2534e98e3e1Schristos if (current_alignment == 0) 2544e98e3e1Schristos current_alignment = WITH_ALIGNMENT; 2554b169a6bSchristos /* If the port hasn't specified an alignment, default to not enforcing. */ 2564e98e3e1Schristos if (current_alignment == 0) 2574b169a6bSchristos current_alignment = NONSTRICT_ALIGNMENT; 2584e98e3e1Schristos 2594e98e3e1Schristos /* verify the alignment */ 2604e98e3e1Schristos if (CURRENT_ALIGNMENT == 0) 2614e98e3e1Schristos { 2624e98e3e1Schristos sim_io_eprintf (sd, "Target alignment unspecified\n"); 2634e98e3e1Schristos return SIM_RC_FAIL; 2644e98e3e1Schristos } 2654e98e3e1Schristos if (CURRENT_ALIGNMENT != current_alignment) 2664e98e3e1Schristos { 2674e98e3e1Schristos sim_io_eprintf (sd, "Target (%s) and configured (%s) alignment in conflict\n", 2684e98e3e1Schristos config_alignment_to_a (CURRENT_ALIGNMENT), 2694e98e3e1Schristos config_alignment_to_a (current_alignment)); 2704e98e3e1Schristos return SIM_RC_FAIL; 2714e98e3e1Schristos } 2724e98e3e1Schristos 2734e98e3e1Schristos #if defined (WITH_FLOATING_POINT) 2744e98e3e1Schristos 2754e98e3e1Schristos /* set the floating point */ 2764e98e3e1Schristos if (current_floating_point == 0) 2774e98e3e1Schristos current_floating_point = WITH_FLOATING_POINT; 2784e98e3e1Schristos 2794e98e3e1Schristos /* verify the floating point */ 2804e98e3e1Schristos if (CURRENT_FLOATING_POINT == 0) 2814e98e3e1Schristos { 2824e98e3e1Schristos sim_io_eprintf (sd, "Target floating-point unspecified\n"); 2834e98e3e1Schristos return SIM_RC_FAIL; 2844e98e3e1Schristos } 2854e98e3e1Schristos if (CURRENT_FLOATING_POINT != current_floating_point) 2864e98e3e1Schristos { 2874e98e3e1Schristos sim_io_eprintf (sd, "Target (%s) and configured (%s) floating-point in conflict\n", 2884e98e3e1Schristos config_alignment_to_a (CURRENT_FLOATING_POINT), 2894e98e3e1Schristos config_alignment_to_a (current_floating_point)); 2904e98e3e1Schristos return SIM_RC_FAIL; 2914e98e3e1Schristos } 2924e98e3e1Schristos 2934e98e3e1Schristos #endif 2944e98e3e1Schristos return SIM_RC_OK; 2954e98e3e1Schristos } 2964e98e3e1Schristos 2974e98e3e1Schristos 2984e98e3e1Schristos void 2994b169a6bSchristos sim_config_print (SIM_DESC sd) 3004e98e3e1Schristos { 3014e98e3e1Schristos sim_io_printf (sd, "WITH_TARGET_BYTE_ORDER = %s\n", 3024e98e3e1Schristos config_byte_order_to_a (WITH_TARGET_BYTE_ORDER)); 3034e98e3e1Schristos 304ba340e45Schristos sim_io_printf (sd, "HOST_BYTE_ORDER = %s\n", 305ba340e45Schristos config_byte_order_to_a (HOST_BYTE_ORDER)); 3064e98e3e1Schristos 3074e98e3e1Schristos sim_io_printf (sd, "WITH_STDIO = %s\n", 3084e98e3e1Schristos config_stdio_to_a (WITH_STDIO)); 3094e98e3e1Schristos 3104e98e3e1Schristos sim_io_printf (sd, "WITH_TARGET_WORD_MSB = %d\n", 3114e98e3e1Schristos WITH_TARGET_WORD_MSB); 3124e98e3e1Schristos 3134e98e3e1Schristos sim_io_printf (sd, "WITH_TARGET_WORD_BITSIZE = %d\n", 3144e98e3e1Schristos WITH_TARGET_WORD_BITSIZE); 3154e98e3e1Schristos 3164e98e3e1Schristos sim_io_printf (sd, "WITH_TARGET_ADDRESS_BITSIZE = %d\n", 3174e98e3e1Schristos WITH_TARGET_ADDRESS_BITSIZE); 3184e98e3e1Schristos 3194e98e3e1Schristos sim_io_printf (sd, "WITH_TARGET_CELL_BITSIZE = %d\n", 3204e98e3e1Schristos WITH_TARGET_CELL_BITSIZE); 3214e98e3e1Schristos 3224e98e3e1Schristos sim_io_printf (sd, "WITH_TARGET_FLOATING_POINT_BITSIZE = %d\n", 3234e98e3e1Schristos WITH_TARGET_FLOATING_POINT_BITSIZE); 3244e98e3e1Schristos 3254e98e3e1Schristos sim_io_printf (sd, "WITH_ENVIRONMENT = %s\n", 3264e98e3e1Schristos config_environment_to_a (WITH_ENVIRONMENT)); 3274e98e3e1Schristos 3284e98e3e1Schristos sim_io_printf (sd, "WITH_ALIGNMENT = %s\n", 3294e98e3e1Schristos config_alignment_to_a (WITH_ALIGNMENT)); 3304e98e3e1Schristos 3314e98e3e1Schristos #if defined (WITH_XOR_ENDIAN) 3324e98e3e1Schristos sim_io_printf (sd, "WITH_XOR_ENDIAN = %d\n", WITH_XOR_ENDIAN); 3334e98e3e1Schristos #endif 3344e98e3e1Schristos 3354e98e3e1Schristos #if defined (WITH_FLOATING_POINT) 3364e98e3e1Schristos sim_io_printf (sd, "WITH_FLOATING_POINT = %s\n", 3374e98e3e1Schristos config_floating_point_to_a (WITH_FLOATING_POINT)); 3384e98e3e1Schristos #endif 3394e98e3e1Schristos 3404e98e3e1Schristos #if defined (WITH_SMP) 3414e98e3e1Schristos sim_io_printf (sd, "WITH_SMP = %d\n", WITH_SMP); 3424e98e3e1Schristos #endif 3434e98e3e1Schristos 3444e98e3e1Schristos #if defined (WITH_RESERVED_BITS) 3454e98e3e1Schristos sim_io_printf (sd, "WITH_RESERVED_BITS = %d\n", WITH_RESERVED_BITS); 3464e98e3e1Schristos #endif 3474e98e3e1Schristos 3484e98e3e1Schristos #if defined (WITH_PROFILE) 3494e98e3e1Schristos sim_io_printf (sd, "WITH_PROFILE = %d\n", WITH_PROFILE); 3504e98e3e1Schristos #endif 3514e98e3e1Schristos 3524e98e3e1Schristos } 353