| 1 | /* |
| 2 | * ========== Copyright Header Begin ========================================== |
| 3 | * |
| 4 | * OpenSPARC T2 Processor File: config.h |
| 5 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. |
| 6 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. |
| 7 | * |
| 8 | * The above named program is free software; you can redistribute it and/or |
| 9 | * modify it under the terms of the GNU General Public |
| 10 | * License version 2 as published by the Free Software Foundation. |
| 11 | * |
| 12 | * The above named program is distributed in the hope that it will be |
| 13 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 | * General Public License for more details. |
| 16 | * |
| 17 | * You should have received a copy of the GNU General Public |
| 18 | * License along with this work; if not, write to the Free Software |
| 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. |
| 20 | * |
| 21 | * ========== Copyright Header End ============================================ |
| 22 | */ |
| 23 | /* |
| 24 | * Copyright 2006 Sun Microsystems, Inc. All rights reserved. |
| 25 | * Use is subject to license terms. |
| 26 | */ |
| 27 | |
| 28 | #ifndef _CONFIG_H |
| 29 | #define _CONFIG_H |
| 30 | |
| 31 | #pragma ident "@(#)config.h 1.42 06/12/07 SMI" |
| 32 | |
| 33 | #ifdef __cplusplus |
| 34 | extern "C" { |
| 35 | #endif |
| 36 | |
| 37 | #include <stdio.h> |
| 38 | |
| 39 | #include "list.h" |
| 40 | |
| 41 | |
| 42 | /* |
| 43 | * Please Note: this file is in support of machine independent |
| 44 | * constructors. Do not place anthing in this file that is |
| 45 | * machine specific. |
| 46 | */ |
| 47 | |
| 48 | typedef void(*op_funcp)(simcpu_t *sp, xicache_instn_t * xcip); |
| 49 | |
| 50 | typedef enum { |
| 51 | ES_IDLE, |
| 52 | ES_RESUME, |
| 53 | ES_RESET, |
| 54 | ES_SSI, |
| 55 | ES_JBUS, |
| 56 | ES_SPOR, |
| 57 | ES_XIR, |
| 58 | ES_NIU, |
| 59 | ES_PCIE, |
| 60 | ES_LEGION_SAVE_STATE |
| 61 | } ext_sig_t; |
| 62 | |
| 63 | |
| 64 | typedef enum { |
| 65 | DA_Load = 0x1, |
| 66 | DA_Store = 0x2, |
| 67 | DA_Atomic = 0x3, /* bit fields - atomic considered load | store */ |
| 68 | DA_Instn = 0x4, |
| 69 | DA_Other = 0x8 |
| 70 | } dev_access_t; |
| 71 | |
| 72 | /* |
| 73 | * Virtual function table for each processor |
| 74 | */ |
| 75 | |
| 76 | struct PROC_TYPE { |
| 77 | char * proc_type_namep; /* processor type name */ |
| 78 | bool_t flag_initialised; /* true if module initialised */ |
| 79 | bool_t (*init_module)(proc_type_t *); /* call to initialise module */ |
| 80 | |
| 81 | void (*parse_proc)(domain_t *, config_proc_t *); |
| 82 | void (*init_proc)(domain_t *, config_proc_t *); /* call back after parsing */ |
| 83 | void (*dump_proc)(domain_t *, config_proc_t *); /* dump processor config */ |
| 84 | |
| 85 | /* |
| 86 | * Execution support functions |
| 87 | */ |
| 88 | |
| 89 | bool_t (*regread)(void * pspecp, uint_t regnum, uint64_t * regp); |
| 90 | bool_t (*regwrite)(void * pspecp, uint_t regnum, uint64_t val); |
| 91 | |
| 92 | void (*exec_setup)(simcpu_t * sp); |
| 93 | void (*exec_cleanup)(simcpu_t * sp); |
| 94 | bool_t (*save_state)(simcpu_t * sp); |
| 95 | |
| 96 | void (*check_async_event)(simcpu_t * sp); |
| 97 | void (*take_exception)(simcpu_t * sp); |
| 98 | |
| 99 | #if ERROR_INJECTION |
| 100 | void (*error_condition)(simcpu_t * sp, error_conf_t * ep); |
| 101 | #endif |
| 102 | #if ERROR_TRAP_GEN /* { */ |
| 103 | bool_t (*trigger_error_trap)(simcpu_t * sp); |
| 104 | void (*load_error_file)(config_proc_t * cp); |
| 105 | void (*dump_error_active)(config_proc_t * cp); |
| 106 | void (*dump_error_supported)(config_proc_t * cp); |
| 107 | #endif /* ERROR_TRAP_GEN } */ |
| 108 | bool_t (*sp_interrupt)(simcpu_t *sp, uint64_t intr_level, char *error_name); |
| 109 | |
| 110 | /* Processor specific instructions */ |
| 111 | op_funcp (*cpu_decode_me)(simcpu_t *sp, xicache_instn_t * xcip, uint32_t instn); |
| 112 | struct fpsim_functions *fpsimp; /* pointer to fp simulated functions */ |
| 113 | |
| 114 | /* performance measurement callbacks */ |
| 115 | void (*perf_dump)(void * pspecp); |
| 116 | |
| 117 | /* functions to dump tlb, instruction counts etc */ |
| 118 | void (*tlb_dump)(config_proc_t *, bool_t); |
| 119 | void (*instn_cnt_dump)(config_proc_t *); |
| 120 | |
| 121 | /* |
| 122 | * External interface methods ... |
| 123 | * ... thread clean mechanism for delivering |
| 124 | * notifications to running cpus. |
| 125 | */ |
| 126 | |
| 127 | uint64_t (*ext_signal)(config_proc_t * cp, ext_sig_t sigtype, void *vp); |
| 128 | uint_t (*get_cpuid)(simcpu_t *sp); |
| 129 | void (*get_pseudo_dev)(config_proc_t *config_procp, char *dev_namep, void *devp); |
| 130 | bool_t (*dev_mem_access)(config_proc_t *cp, tvaddr_t addr, uint8_t *datap, |
| 131 | uint64_t size, dev_access_t type); |
| 132 | /* |
| 133 | * Principally debugger access methods, but may also get |
| 134 | * used for various magic traps ... |
| 135 | */ |
| 136 | void * (*dbgr_attach)(domain_t *, config_proc_t *, char * dbgr_str); |
| 137 | void (*dbgr_detach)(void * pspecp); |
| 138 | |
| 139 | /* returns the amount handled - zero on abject failure */ |
| 140 | uint64_t (*dbgr_mem_read)(void * pspecp, tvaddr_t vaddr, bool_t do_translate, uint8_t * bufp, uint64_t len); |
| 141 | uint64_t (*dbgr_mem_write)(void * pspecp, tvaddr_t vaddr, bool_t do_translate, uint8_t * bufp, uint64_t len); |
| 142 | uint64_t (*dbgr_mem_clear)(void * pspecp, tvaddr_t vaddr, bool_t do_translate, uint64_t len); |
| 143 | |
| 144 | void (*dbgr_set_break)(void * pspecp, tvaddr_t vaddr); |
| 145 | void (*dbgr_clear_break)(void * pspecp, tvaddr_t vaddr); |
| 146 | void (*domain_check)(domain_t * domainp); |
| 147 | |
| 148 | reg_map_t * reg_mapp; |
| 149 | |
| 150 | void *debug_hookp; |
| 151 | void *debug_hook_dumpp; |
| 152 | |
| 153 | #define CPU_MAGIC 0xc00ef00d |
| 154 | uint32_t proc_magic; |
| 155 | }; |
| 156 | |
| 157 | |
| 158 | typedef struct dev_child_type { |
| 159 | void *child_devicep; /* could be anything, depends on the parent */ |
| 160 | int parent_device_id; |
| 161 | } dev_child_type_t; |
| 162 | |
| 163 | struct DEV_TYPE { |
| 164 | char * dev_type_namep; |
| 165 | void (*parse_dev)(config_dev_t *); |
| 166 | void (*init_dev)(config_dev_t *); |
| 167 | void (*dump_dev)(config_dev_t *); /* dump device config */ |
| 168 | |
| 169 | /* return a pointer (and extent) to the block requested at |
| 170 | * offset, if it is cacheable - return 0 |
| 171 | */ |
| 172 | tpaddr_t (*dev_cacheable)(config_addr_t *, dev_access_t type, tpaddr_t offset, uint8_t ** cbp); |
| 173 | |
| 174 | bool_t (*dev_cpu_access)(simcpu_t *, config_addr_t *, tpaddr_t offset, maccess_t op, uint64_t * regp); |
| 175 | |
| 176 | #define DEV_MAGIC 0xc00fe00e |
| 177 | uint32_t dev_magic; |
| 178 | }; |
| 179 | |
| 180 | /* |
| 181 | * Holding struct for processor info |
| 182 | * This is a processor dependent structure which |
| 183 | * ultimately holds the number of simcpu_t that the |
| 184 | * processor supports. |
| 185 | */ |
| 186 | |
| 187 | struct CONFIG_PROC { |
| 188 | proc_type_t * proc_typep; |
| 189 | int proc_id; /* number of proc within domain */ |
| 190 | void * procp; /* processor specific data */ |
| 191 | domain_t * domainp; /* this proc's domain */ |
| 192 | }; |
| 193 | |
| 194 | |
| 195 | /* |
| 196 | * Similarly do the same for devices ... |
| 197 | */ |
| 198 | |
| 199 | struct CONFIG_ADDR { |
| 200 | tpaddr_t baseaddr; |
| 201 | tpaddr_t topaddr; |
| 202 | tpaddr_t range; |
| 203 | struct CONFIG_ADDR *nextp; |
| 204 | config_dev_t *config_devp; |
| 205 | }; |
| 206 | |
| 207 | struct CONFIG_DEV { |
| 208 | dev_type_t * dev_typep; |
| 209 | bool_t is_implied; /* is true if this device get auto created by another device etc. */ |
| 210 | domain_t * domainp; |
| 211 | int device_id; /* device id within domain */ |
| 212 | void * devp; |
| 213 | config_addr_t * addrp; |
| 214 | config_dev_t * nextp; |
| 215 | }; |
| 216 | |
| 217 | |
| 218 | struct DOMAIN { |
| 219 | int idx; |
| 220 | uint64_t sysclkfreq; |
| 221 | system_t * systemp; /* this proc's system */ |
| 222 | LIST_DEF( procs, config_proc_t ); |
| 223 | struct { /* linked sorted list not regular LIST */ |
| 224 | int count; |
| 225 | config_dev_t * listp; |
| 226 | } device; |
| 227 | struct { |
| 228 | int count; |
| 229 | config_addr_t *listp; |
| 230 | } address; |
| 231 | #if ERROR_INJECTION |
| 232 | error_conf_t * errlistp; |
| 233 | #endif |
| 234 | }; |
| 235 | |
| 236 | |
| 237 | struct SERVICE_PROC { |
| 238 | char *namep; |
| 239 | dev_type_t *dev_typep; |
| 240 | }; |
| 241 | |
| 242 | struct SYSTEM { |
| 243 | char * namep; |
| 244 | int idx; |
| 245 | service_proc_t *service_procp; |
| 246 | bool_t fake_sp; /* Fake anything the SP does. */ |
| 247 | LIST_DEF( domains, domain_t ); |
| 248 | }; |
| 249 | |
| 250 | struct ERROR_CONFIG { |
| 251 | uint64_t cycle; |
| 252 | uint32_t type; |
| 253 | char * type_namep; |
| 254 | uint32_t op; |
| 255 | char * op_namep; |
| 256 | uint8_t priv; |
| 257 | char * priv_namep; |
| 258 | error_conf_t * nextp; |
| 259 | bool_t npp; |
| 260 | }; |
| 261 | |
| 262 | |
| 263 | /* |
| 264 | * Configuration support functions |
| 265 | */ |
| 266 | |
| 267 | config_addr_t * find_domain_address(domain_t * domainp, tpaddr_t pa); |
| 268 | |
| 269 | |
| 270 | /* |
| 271 | * The struct that defines the simulator configuration |
| 272 | */ |
| 273 | |
| 274 | typedef struct { |
| 275 | LIST_DEF( systems, system_t ); |
| 276 | } target_config_t; |
| 277 | |
| 278 | extern target_config_t target_config; |
| 279 | |
| 280 | void init_target_config(); |
| 281 | |
| 282 | void dump_config(FILE * outp); |
| 283 | |
| 284 | void init_config(); |
| 285 | |
| 286 | /* |
| 287 | * Parser support functions ... |
| 288 | */ |
| 289 | |
| 290 | uint64_t parse_number_assign(); |
| 291 | config_dev_t * insert_domain_device(domain_t * domainp, config_dev_t * config_devp); |
| 292 | config_addr_t * insert_domain_address(domain_t * domainp, config_dev_t * config_devp, |
| 293 | tpaddr_t baseaddr, tpaddr_t topaddr); |
| 294 | |
| 295 | /* |
| 296 | * This macro is used in multinode systems in order to translate |
| 297 | * the node id to an index in domainp->procs.listbasep |
| 298 | */ |
| 299 | |
| 300 | #define NODE2IDX(_n, _d, _idx) do { \ |
| 301 | int i; \ |
| 302 | for (i=0; i < _d->procs.count; i++) { \ |
| 303 | if (LIST_ENTRY(_d->procs, i)->proc_id == _n) \ |
| 304 | break; \ |
| 305 | } \ |
| 306 | if (!(i < _d->procs.count)) \ |
| 307 | fatal("node_id %d not present on system\n", _n);\ |
| 308 | _idx = i; \ |
| 309 | } while (0) |
| 310 | |
| 311 | #ifdef __cplusplus |
| 312 | } |
| 313 | #endif |
| 314 | |
| 315 | #endif /* _CONFIG_H */ |