1 1.5 christos /* This file is part of SIS (SPARC instruction simulator) 2 1.5 christos 3 1.11 christos Copyright (C) 1995-2024 Free Software Foundation, Inc. 4 1.5 christos Contributed by Jiri Gaisler, European Space Agency 5 1.5 christos 6 1.5 christos This program is free software; you can redistribute it and/or modify 7 1.5 christos it under the terms of the GNU General Public License as published by 8 1.5 christos the Free Software Foundation; either version 3 of the License, or 9 1.5 christos (at your option) any later version. 10 1.5 christos 11 1.5 christos This program is distributed in the hope that it will be useful, 12 1.5 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.5 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.5 christos GNU General Public License for more details. 15 1.5 christos 16 1.5 christos You should have received a copy of the GNU General Public License 17 1.5 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 1.1 christos 19 1.1 christos /* The control space devices */ 20 1.1 christos 21 1.10 christos /* This must come before any other includes. */ 22 1.10 christos #include "defs.h" 23 1.10 christos 24 1.1 christos #include <sys/types.h> 25 1.1 christos #include <stdio.h> 26 1.1 christos #include <string.h> 27 1.10 christos #ifdef HAVE_TERMIOS_H 28 1.1 christos #include <termios.h> 29 1.10 christos #endif 30 1.1 christos #include <sys/fcntl.h> 31 1.1 christos #include <sys/file.h> 32 1.1 christos #include <unistd.h> 33 1.1 christos #include "sis.h" 34 1.1 christos #include "sim-config.h" 35 1.1 christos 36 1.1 christos extern int ctrl_c; 37 1.10 christos extern int32_t sis_verbose; 38 1.10 christos extern int32_t sparclite, sparclite_board; 39 1.1 christos extern int rom8,wrp,uben; 40 1.1 christos extern char uart_dev1[], uart_dev2[]; 41 1.1 christos 42 1.1 christos int dumbio = 0; /* normal, smart, terminal oriented IO by default */ 43 1.1 christos 44 1.1 christos /* MEC registers */ 45 1.1 christos #define MEC_START 0x01f80000 46 1.1 christos #define MEC_END 0x01f80100 47 1.1 christos 48 1.1 christos /* Memory exception waitstates */ 49 1.1 christos #define MEM_EX_WS 1 50 1.1 christos 51 1.1 christos /* ERC32 always adds one waitstate during RAM std */ 52 1.1 christos #define STD_WS 1 53 1.1 christos 54 1.1 christos #ifdef ERRINJ 55 1.1 christos extern int errmec; 56 1.1 christos #endif 57 1.1 christos 58 1.1 christos #define MEC_WS 0 /* Waitstates per MEC access (0 ws) */ 59 1.1 christos #define MOK 0 60 1.1 christos 61 1.1 christos /* MEC register addresses */ 62 1.1 christos 63 1.1 christos #define MEC_MCR 0x000 64 1.1 christos #define MEC_SFR 0x004 65 1.1 christos #define MEC_PWDR 0x008 66 1.1 christos #define MEC_MEMCFG 0x010 67 1.1 christos #define MEC_IOCR 0x014 68 1.1 christos #define MEC_WCR 0x018 69 1.1 christos 70 1.1 christos #define MEC_MAR0 0x020 71 1.1 christos #define MEC_MAR1 0x024 72 1.1 christos 73 1.1 christos #define MEC_SSA1 0x020 74 1.1 christos #define MEC_SEA1 0x024 75 1.1 christos #define MEC_SSA2 0x028 76 1.1 christos #define MEC_SEA2 0x02C 77 1.1 christos #define MEC_ISR 0x044 78 1.1 christos #define MEC_IPR 0x048 79 1.1 christos #define MEC_IMR 0x04C 80 1.1 christos #define MEC_ICR 0x050 81 1.1 christos #define MEC_IFR 0x054 82 1.1 christos #define MEC_WDOG 0x060 83 1.1 christos #define MEC_TRAPD 0x064 84 1.1 christos #define MEC_RTC_COUNTER 0x080 85 1.1 christos #define MEC_RTC_RELOAD 0x080 86 1.1 christos #define MEC_RTC_SCALER 0x084 87 1.1 christos #define MEC_GPT_COUNTER 0x088 88 1.1 christos #define MEC_GPT_RELOAD 0x088 89 1.1 christos #define MEC_GPT_SCALER 0x08C 90 1.1 christos #define MEC_TIMER_CTRL 0x098 91 1.1 christos #define MEC_SFSR 0x0A0 92 1.1 christos #define MEC_FFAR 0x0A4 93 1.1 christos #define MEC_ERSR 0x0B0 94 1.1 christos #define MEC_DBG 0x0C0 95 1.1 christos #define MEC_TCR 0x0D0 96 1.1 christos 97 1.1 christos #define MEC_BRK 0x0C4 98 1.1 christos #define MEC_WPR 0x0C8 99 1.1 christos 100 1.1 christos #define MEC_UARTA 0x0E0 101 1.1 christos #define MEC_UARTB 0x0E4 102 1.1 christos #define MEC_UART_CTRL 0x0E8 103 1.1 christos #define SIM_LOAD 0x0F0 104 1.1 christos 105 1.1 christos /* Memory exception causes */ 106 1.1 christos #define PROT_EXC 0x3 107 1.1 christos #define UIMP_ACC 0x4 108 1.1 christos #define MEC_ACC 0x6 109 1.1 christos #define WATCH_EXC 0xa 110 1.1 christos #define BREAK_EXC 0xb 111 1.1 christos 112 1.1 christos /* Size of UART buffers (bytes) */ 113 1.1 christos #define UARTBUF 1024 114 1.1 christos 115 1.1 christos /* Number of simulator ticks between flushing the UARTS. */ 116 1.1 christos /* For good performance, keep above 1000 */ 117 1.1 christos #define UART_FLUSH_TIME 3000 118 1.1 christos 119 1.1 christos /* MEC timer control register bits */ 120 1.1 christos #define TCR_GACR 1 121 1.1 christos #define TCR_GACL 2 122 1.1 christos #define TCR_GASE 4 123 1.1 christos #define TCR_GASL 8 124 1.1 christos #define TCR_TCRCR 0x100 125 1.1 christos #define TCR_TCRCL 0x200 126 1.1 christos #define TCR_TCRSE 0x400 127 1.1 christos #define TCR_TCRSL 0x800 128 1.1 christos 129 1.1 christos /* New uart defines */ 130 1.1 christos #define UART_TX_TIME 1000 131 1.1 christos #define UART_RX_TIME 1000 132 1.1 christos #define UARTA_DR 0x1 133 1.1 christos #define UARTA_SRE 0x2 134 1.1 christos #define UARTA_HRE 0x4 135 1.1 christos #define UARTA_OR 0x40 136 1.1 christos #define UARTA_CLR 0x80 137 1.1 christos #define UARTB_DR 0x10000 138 1.1 christos #define UARTB_SRE 0x20000 139 1.1 christos #define UARTB_HRE 0x40000 140 1.1 christos #define UARTB_OR 0x400000 141 1.1 christos #define UARTB_CLR 0x800000 142 1.1 christos 143 1.1 christos #define UART_DR 0x100 144 1.1 christos #define UART_TSE 0x200 145 1.1 christos #define UART_THE 0x400 146 1.1 christos 147 1.1 christos /* MEC registers */ 148 1.1 christos 149 1.1 christos static char fname[256]; 150 1.10 christos static int32_t find = 0; 151 1.10 christos static uint32_t mec_ssa[2]; /* Write protection start address */ 152 1.10 christos static uint32_t mec_sea[2]; /* Write protection end address */ 153 1.10 christos static uint32_t mec_wpr[2]; /* Write protection control fields */ 154 1.10 christos static uint32_t mec_sfsr; 155 1.10 christos static uint32_t mec_ffar; 156 1.10 christos static uint32_t mec_ipr; 157 1.10 christos static uint32_t mec_imr; 158 1.10 christos static uint32_t mec_isr; 159 1.10 christos static uint32_t mec_icr; 160 1.10 christos static uint32_t mec_ifr; 161 1.10 christos static uint32_t mec_mcr; /* MEC control register */ 162 1.10 christos static uint32_t mec_memcfg; /* Memory control register */ 163 1.10 christos static uint32_t mec_wcr; /* MEC waitstate register */ 164 1.10 christos static uint32_t mec_iocr; /* MEC IO control register */ 165 1.10 christos static uint32_t posted_irq; 166 1.10 christos static uint32_t mec_ersr; /* MEC error and status register */ 167 1.10 christos static uint32_t mec_tcr; /* MEC test comtrol register */ 168 1.10 christos 169 1.10 christos static uint32_t rtc_counter; 170 1.10 christos static uint32_t rtc_reload; 171 1.10 christos static uint32_t rtc_scaler; 172 1.10 christos static uint32_t rtc_scaler_start; 173 1.10 christos static uint32_t rtc_enabled; 174 1.10 christos static uint32_t rtc_cr; 175 1.10 christos static uint32_t rtc_se; 176 1.10 christos 177 1.10 christos static uint32_t gpt_counter; 178 1.10 christos static uint32_t gpt_reload; 179 1.10 christos static uint32_t gpt_scaler; 180 1.10 christos static uint32_t gpt_scaler_start; 181 1.10 christos static uint32_t gpt_enabled; 182 1.10 christos static uint32_t gpt_cr; 183 1.10 christos static uint32_t gpt_se; 184 1.10 christos 185 1.10 christos static uint32_t wdog_scaler; 186 1.10 christos static uint32_t wdog_counter; 187 1.10 christos static uint32_t wdog_rst_delay; 188 1.10 christos static uint32_t wdog_rston; 189 1.1 christos 190 1.1 christos enum wdog_type { 191 1.1 christos init, disabled, enabled, stopped 192 1.1 christos }; 193 1.1 christos 194 1.1 christos static enum wdog_type wdog_status; 195 1.1 christos 196 1.1 christos 197 1.1 christos /* ROM size 1024 Kbyte */ 198 1.1 christos #define ROM_SZ 0x100000 199 1.1 christos #define ROM_MASK 0x0fffff 200 1.1 christos 201 1.1 christos /* RAM size 4 Mbyte */ 202 1.1 christos #define RAM_START 0x02000000 203 1.1 christos #define RAM_END 0x02400000 204 1.1 christos #define RAM_MASK 0x003fffff 205 1.1 christos 206 1.1 christos /* SPARClite boards all seem to have RAM at the same place. */ 207 1.1 christos #define RAM_START_SLITE 0x40000000 208 1.1 christos #define RAM_END_SLITE 0x40400000 209 1.1 christos #define RAM_MASK_SLITE 0x003fffff 210 1.1 christos 211 1.1 christos /* Memory support variables */ 212 1.1 christos 213 1.10 christos static uint32_t mem_ramr_ws; /* RAM read waitstates */ 214 1.10 christos static uint32_t mem_ramw_ws; /* RAM write waitstates */ 215 1.10 christos static uint32_t mem_romr_ws; /* ROM read waitstates */ 216 1.10 christos static uint32_t mem_romw_ws; /* ROM write waitstates */ 217 1.10 christos static uint32_t mem_ramstart; /* RAM start */ 218 1.10 christos static uint32_t mem_ramend; /* RAM end */ 219 1.10 christos static uint32_t mem_rammask; /* RAM address mask */ 220 1.10 christos static uint32_t mem_ramsz; /* RAM size */ 221 1.10 christos static uint32_t mem_romsz; /* ROM size */ 222 1.10 christos static uint32_t mem_accprot; /* RAM write protection enabled */ 223 1.10 christos static uint32_t mem_blockprot; /* RAM block write protection enabled */ 224 1.1 christos 225 1.1 christos static unsigned char romb[ROM_SZ]; 226 1.1 christos static unsigned char ramb[RAM_END - RAM_START]; 227 1.1 christos 228 1.1 christos 229 1.1 christos /* UART support variables */ 230 1.1 christos 231 1.10 christos static int32_t fd1, fd2; /* file descriptor for input file */ 232 1.10 christos static int32_t Ucontrol; /* UART status register */ 233 1.1 christos static unsigned char aq[UARTBUF], bq[UARTBUF]; 234 1.10 christos static int32_t anum, aind = 0; 235 1.10 christos static int32_t bnum, bind = 0; 236 1.1 christos static char wbufa[UARTBUF], wbufb[UARTBUF]; 237 1.1 christos static unsigned wnuma; 238 1.1 christos static unsigned wnumb; 239 1.1 christos static FILE *f1in, *f1out, *f2in, *f2out; 240 1.10 christos #ifdef HAVE_TERMIOS_H 241 1.1 christos static struct termios ioc1, ioc2, iocold1, iocold2; 242 1.10 christos #endif 243 1.1 christos static int f1open = 0, f2open = 0; 244 1.1 christos 245 1.1 christos static char uarta_sreg, uarta_hreg, uartb_sreg, uartb_hreg; 246 1.10 christos static uint32_t uart_stat_reg; 247 1.10 christos static uint32_t uarta_data, uartb_data; 248 1.1 christos 249 1.1 christos #ifdef ERA 250 1.1 christos int era = 0; 251 1.1 christos int erareg; 252 1.1 christos #endif 253 1.1 christos 254 1.1 christos /* Forward declarations */ 255 1.1 christos 256 1.1 christos static void decode_ersr (void); 257 1.1 christos #ifdef ERRINJ 258 1.1 christos static void iucomperr (void); 259 1.1 christos #endif 260 1.1 christos static void mecparerror (void); 261 1.1 christos static void decode_memcfg (void); 262 1.1 christos static void decode_wcr (void); 263 1.1 christos static void decode_mcr (void); 264 1.1 christos static void close_port (void); 265 1.1 christos static void mec_reset (void); 266 1.10 christos static void mec_intack (int32_t level); 267 1.1 christos static void chk_irq (void); 268 1.10 christos static void mec_irq (int32_t level); 269 1.10 christos static void set_sfsr (uint32_t fault, uint32_t addr, 270 1.10 christos uint32_t asi, uint32_t read); 271 1.10 christos static int32_t mec_read (uint32_t addr, uint32_t asi, uint32_t *data); 272 1.10 christos static int mec_write (uint32_t addr, uint32_t data); 273 1.1 christos static void port_init (void); 274 1.10 christos static uint32_t read_uart (uint32_t addr); 275 1.10 christos static void write_uart (uint32_t addr, uint32_t data); 276 1.1 christos static void flush_uart (void); 277 1.10 christos static void uarta_tx (int32_t); 278 1.10 christos static void uartb_tx (int32_t); 279 1.10 christos static void uart_rx (int32_t); 280 1.10 christos static void uart_intr (int32_t); 281 1.1 christos static void uart_irq_start (void); 282 1.10 christos static void wdog_intr (int32_t); 283 1.1 christos static void wdog_start (void); 284 1.10 christos static void rtc_intr (int32_t); 285 1.1 christos static void rtc_start (void); 286 1.10 christos static uint32_t rtc_counter_read (void); 287 1.10 christos static void rtc_scaler_set (uint32_t val); 288 1.10 christos static void rtc_reload_set (uint32_t val); 289 1.10 christos static void gpt_intr (int32_t); 290 1.1 christos static void gpt_start (void); 291 1.10 christos static uint32_t gpt_counter_read (void); 292 1.10 christos static void gpt_scaler_set (uint32_t val); 293 1.10 christos static void gpt_reload_set (uint32_t val); 294 1.10 christos static void timer_ctrl (uint32_t val); 295 1.10 christos static void * get_mem_ptr (uint32_t addr, uint32_t size); 296 1.10 christos static void store_bytes (unsigned char *mem, uint32_t waddr, 297 1.10 christos uint32_t *data, int sz, int32_t *ws); 298 1.1 christos 299 1.1 christos extern int ext_irl; 300 1.1 christos 301 1.1 christos 302 1.1 christos /* One-time init */ 303 1.1 christos 304 1.1 christos void 305 1.10 christos init_sim(void) 306 1.1 christos { 307 1.1 christos port_init(); 308 1.1 christos } 309 1.1 christos 310 1.1 christos /* Power-on reset init */ 311 1.1 christos 312 1.1 christos void 313 1.10 christos reset(void) 314 1.1 christos { 315 1.1 christos mec_reset(); 316 1.1 christos uart_irq_start(); 317 1.1 christos wdog_start(); 318 1.1 christos } 319 1.1 christos 320 1.1 christos static void 321 1.10 christos decode_ersr(void) 322 1.1 christos { 323 1.1 christos if (mec_ersr & 0x01) { 324 1.1 christos if (!(mec_mcr & 0x20)) { 325 1.1 christos if (mec_mcr & 0x40) { 326 1.1 christos sys_reset(); 327 1.1 christos mec_ersr = 0x8000; 328 1.1 christos if (sis_verbose) 329 1.1 christos printf("Error manager reset - IU in error mode\n"); 330 1.1 christos } else { 331 1.1 christos sys_halt(); 332 1.1 christos mec_ersr |= 0x2000; 333 1.1 christos if (sis_verbose) 334 1.1 christos printf("Error manager halt - IU in error mode\n"); 335 1.1 christos } 336 1.1 christos } else 337 1.1 christos mec_irq(1); 338 1.1 christos } 339 1.1 christos if (mec_ersr & 0x04) { 340 1.1 christos if (!(mec_mcr & 0x200)) { 341 1.1 christos if (mec_mcr & 0x400) { 342 1.1 christos sys_reset(); 343 1.1 christos mec_ersr = 0x8000; 344 1.1 christos if (sis_verbose) 345 1.1 christos printf("Error manager reset - IU comparison error\n"); 346 1.1 christos } else { 347 1.1 christos sys_halt(); 348 1.1 christos mec_ersr |= 0x2000; 349 1.1 christos if (sis_verbose) 350 1.1 christos printf("Error manager halt - IU comparison error\n"); 351 1.1 christos } 352 1.1 christos } else 353 1.1 christos mec_irq(1); 354 1.1 christos } 355 1.1 christos if (mec_ersr & 0x20) { 356 1.1 christos if (!(mec_mcr & 0x2000)) { 357 1.1 christos if (mec_mcr & 0x4000) { 358 1.1 christos sys_reset(); 359 1.1 christos mec_ersr = 0x8000; 360 1.1 christos if (sis_verbose) 361 1.1 christos printf("Error manager reset - MEC hardware error\n"); 362 1.1 christos } else { 363 1.1 christos sys_halt(); 364 1.1 christos mec_ersr |= 0x2000; 365 1.1 christos if (sis_verbose) 366 1.1 christos printf("Error manager halt - MEC hardware error\n"); 367 1.1 christos } 368 1.1 christos } else 369 1.1 christos mec_irq(1); 370 1.1 christos } 371 1.1 christos } 372 1.1 christos 373 1.1 christos #ifdef ERRINJ 374 1.1 christos static void 375 1.1 christos iucomperr() 376 1.1 christos { 377 1.1 christos mec_ersr |= 0x04; 378 1.1 christos decode_ersr(); 379 1.1 christos } 380 1.1 christos #endif 381 1.1 christos 382 1.1 christos static void 383 1.10 christos mecparerror(void) 384 1.1 christos { 385 1.1 christos mec_ersr |= 0x20; 386 1.1 christos decode_ersr(); 387 1.1 christos } 388 1.1 christos 389 1.1 christos 390 1.1 christos /* IU error mode manager */ 391 1.1 christos 392 1.1 christos void 393 1.10 christos error_mode(uint32_t pc) 394 1.1 christos { 395 1.1 christos 396 1.1 christos mec_ersr |= 0x1; 397 1.1 christos decode_ersr(); 398 1.1 christos } 399 1.1 christos 400 1.1 christos 401 1.1 christos /* Check memory settings */ 402 1.1 christos 403 1.1 christos static void 404 1.10 christos decode_memcfg(void) 405 1.1 christos { 406 1.1 christos if (rom8) mec_memcfg &= ~0x20000; 407 1.1 christos else mec_memcfg |= 0x20000; 408 1.1 christos 409 1.1 christos mem_ramsz = (256 * 1024) << ((mec_memcfg >> 10) & 7); 410 1.1 christos mem_romsz = (128 * 1024) << ((mec_memcfg >> 18) & 7); 411 1.1 christos 412 1.1 christos if (sparclite_board) { 413 1.1 christos mem_ramstart = RAM_START_SLITE; 414 1.1 christos mem_ramend = RAM_END_SLITE; 415 1.1 christos mem_rammask = RAM_MASK_SLITE; 416 1.1 christos } 417 1.1 christos else { 418 1.1 christos mem_ramstart = RAM_START; 419 1.1 christos mem_ramend = RAM_END; 420 1.1 christos mem_rammask = RAM_MASK; 421 1.1 christos } 422 1.1 christos if (sis_verbose) 423 1.1 christos printf("RAM start: 0x%x, RAM size: %d K, ROM size: %d K\n", 424 1.1 christos mem_ramstart, mem_ramsz >> 10, mem_romsz >> 10); 425 1.1 christos } 426 1.1 christos 427 1.1 christos static void 428 1.10 christos decode_wcr(void) 429 1.1 christos { 430 1.1 christos mem_ramr_ws = mec_wcr & 3; 431 1.1 christos mem_ramw_ws = (mec_wcr >> 2) & 3; 432 1.1 christos mem_romr_ws = (mec_wcr >> 4) & 0x0f; 433 1.1 christos if (rom8) { 434 1.1 christos if (mem_romr_ws > 0 ) mem_romr_ws--; 435 1.1 christos mem_romr_ws = 5 + (4*mem_romr_ws); 436 1.1 christos } 437 1.1 christos mem_romw_ws = (mec_wcr >> 8) & 0x0f; 438 1.1 christos if (sis_verbose) 439 1.1 christos printf("Waitstates = RAM read: %d, RAM write: %d, ROM read: %d, ROM write: %d\n", 440 1.1 christos mem_ramr_ws, mem_ramw_ws, mem_romr_ws, mem_romw_ws); 441 1.1 christos } 442 1.1 christos 443 1.1 christos static void 444 1.10 christos decode_mcr(void) 445 1.1 christos { 446 1.1 christos mem_accprot = (mec_wpr[0] | mec_wpr[1]); 447 1.1 christos mem_blockprot = (mec_mcr >> 3) & 1; 448 1.1 christos if (sis_verbose && mem_accprot) 449 1.1 christos printf("Memory block write protection enabled\n"); 450 1.1 christos if (mec_mcr & 0x08000) { 451 1.1 christos mec_ersr |= 0x20; 452 1.1 christos decode_ersr(); 453 1.1 christos } 454 1.1 christos if (sis_verbose && (mec_mcr & 2)) 455 1.1 christos printf("Software reset enabled\n"); 456 1.1 christos if (sis_verbose && (mec_mcr & 1)) 457 1.1 christos printf("Power-down mode enabled\n"); 458 1.1 christos } 459 1.1 christos 460 1.1 christos /* Flush ports when simulator stops */ 461 1.1 christos 462 1.1 christos void 463 1.10 christos sim_halt(void) 464 1.1 christos { 465 1.1 christos #ifdef FAST_UART 466 1.1 christos flush_uart(); 467 1.1 christos #endif 468 1.1 christos } 469 1.1 christos 470 1.1 christos int 471 1.1 christos sim_stop(SIM_DESC sd) 472 1.1 christos { 473 1.1 christos ctrl_c = 1; 474 1.1 christos return 1; 475 1.1 christos } 476 1.1 christos 477 1.1 christos static void 478 1.10 christos close_port(void) 479 1.1 christos { 480 1.1 christos if (f1open && f1in != stdin) 481 1.1 christos fclose(f1in); 482 1.1 christos if (f2open && f2in != stdin) 483 1.1 christos fclose(f2in); 484 1.1 christos } 485 1.1 christos 486 1.1 christos void 487 1.10 christos exit_sim(void) 488 1.1 christos { 489 1.1 christos close_port(); 490 1.1 christos } 491 1.1 christos 492 1.1 christos static void 493 1.10 christos mec_reset(void) 494 1.1 christos { 495 1.1 christos int i; 496 1.1 christos 497 1.1 christos find = 0; 498 1.1 christos for (i = 0; i < 2; i++) 499 1.1 christos mec_ssa[i] = mec_sea[i] = mec_wpr[i] = 0; 500 1.1 christos mec_mcr = 0x01350014; 501 1.1 christos mec_iocr = 0; 502 1.1 christos mec_sfsr = 0x078; 503 1.1 christos mec_ffar = 0; 504 1.1 christos mec_ipr = 0; 505 1.1 christos mec_imr = 0x7ffe; 506 1.1 christos mec_isr = 0; 507 1.1 christos mec_icr = 0; 508 1.1 christos mec_ifr = 0; 509 1.1 christos mec_memcfg = 0x10000; 510 1.1 christos mec_wcr = -1; 511 1.1 christos mec_ersr = 0; /* MEC error and status register */ 512 1.1 christos mec_tcr = 0; /* MEC test comtrol register */ 513 1.1 christos 514 1.1 christos decode_memcfg(); 515 1.1 christos decode_wcr(); 516 1.1 christos decode_mcr(); 517 1.1 christos 518 1.1 christos posted_irq = 0; 519 1.1 christos wnuma = wnumb = 0; 520 1.1 christos anum = aind = bnum = bind = 0; 521 1.1 christos 522 1.1 christos uart_stat_reg = UARTA_SRE | UARTA_HRE | UARTB_SRE | UARTB_HRE; 523 1.1 christos uarta_data = uartb_data = UART_THE | UART_TSE; 524 1.1 christos 525 1.1 christos rtc_counter = 0xffffffff; 526 1.1 christos rtc_reload = 0xffffffff; 527 1.1 christos rtc_scaler = 0xff; 528 1.1 christos rtc_enabled = 0; 529 1.1 christos rtc_cr = 0; 530 1.1 christos rtc_se = 0; 531 1.1 christos 532 1.1 christos gpt_counter = 0xffffffff; 533 1.1 christos gpt_reload = 0xffffffff; 534 1.1 christos gpt_scaler = 0xffff; 535 1.1 christos gpt_enabled = 0; 536 1.1 christos gpt_cr = 0; 537 1.1 christos gpt_se = 0; 538 1.1 christos 539 1.1 christos wdog_scaler = 255; 540 1.1 christos wdog_rst_delay = 255; 541 1.1 christos wdog_counter = 0xffff; 542 1.1 christos wdog_rston = 0; 543 1.1 christos wdog_status = init; 544 1.1 christos 545 1.1 christos #ifdef ERA 546 1.1 christos erareg = 0; 547 1.1 christos #endif 548 1.1 christos 549 1.1 christos } 550 1.1 christos 551 1.1 christos 552 1.1 christos 553 1.1 christos static void 554 1.10 christos mec_intack(int32_t level) 555 1.1 christos { 556 1.1 christos int irq_test; 557 1.1 christos 558 1.1 christos if (sis_verbose) 559 1.1 christos printf("interrupt %d acknowledged\n", level); 560 1.1 christos irq_test = mec_tcr & 0x80000; 561 1.1 christos if ((irq_test) && (mec_ifr & (1 << level))) 562 1.1 christos mec_ifr &= ~(1 << level); 563 1.1 christos else 564 1.1 christos mec_ipr &= ~(1 << level); 565 1.1 christos chk_irq(); 566 1.1 christos } 567 1.1 christos 568 1.1 christos static void 569 1.10 christos chk_irq(void) 570 1.1 christos { 571 1.10 christos int32_t i; 572 1.10 christos uint32_t itmp; 573 1.1 christos int old_irl; 574 1.1 christos 575 1.1 christos old_irl = ext_irl; 576 1.1 christos if (mec_tcr & 0x80000) itmp = mec_ifr; 577 1.1 christos else itmp = 0; 578 1.1 christos itmp = ((mec_ipr | itmp) & ~mec_imr) & 0x0fffe; 579 1.1 christos ext_irl = 0; 580 1.1 christos if (itmp != 0) { 581 1.1 christos for (i = 15; i > 0; i--) { 582 1.1 christos if (((itmp >> i) & 1) != 0) { 583 1.1 christos if ((sis_verbose) && (i > old_irl)) 584 1.1 christos printf("IU irl: %d\n", i); 585 1.1 christos ext_irl = i; 586 1.1 christos set_int(i, mec_intack, i); 587 1.1 christos break; 588 1.1 christos } 589 1.1 christos } 590 1.1 christos } 591 1.1 christos } 592 1.1 christos 593 1.1 christos static void 594 1.10 christos mec_irq(int32_t level) 595 1.1 christos { 596 1.1 christos mec_ipr |= (1 << level); 597 1.1 christos chk_irq(); 598 1.1 christos } 599 1.1 christos 600 1.1 christos static void 601 1.10 christos set_sfsr(uint32_t fault, uint32_t addr, uint32_t asi, uint32_t read) 602 1.1 christos { 603 1.1 christos if ((asi == 0xa) || (asi == 0xb)) { 604 1.1 christos mec_ffar = addr; 605 1.1 christos mec_sfsr = (fault << 3) | (!read << 15); 606 1.1 christos mec_sfsr |= ((mec_sfsr & 1) ^ 1) | (mec_sfsr & 1); 607 1.1 christos switch (asi) { 608 1.1 christos case 0xa: 609 1.1 christos mec_sfsr |= 0x0004; 610 1.1 christos break; 611 1.1 christos case 0xb: 612 1.1 christos mec_sfsr |= 0x1004; 613 1.1 christos break; 614 1.1 christos } 615 1.1 christos } 616 1.1 christos } 617 1.1 christos 618 1.10 christos static int32_t 619 1.10 christos mec_read(uint32_t addr, uint32_t asi, uint32_t *data) 620 1.1 christos { 621 1.1 christos 622 1.1 christos switch (addr & 0x0ff) { 623 1.1 christos 624 1.1 christos case MEC_MCR: /* 0x00 */ 625 1.1 christos *data = mec_mcr; 626 1.1 christos break; 627 1.1 christos 628 1.1 christos case MEC_MEMCFG: /* 0x10 */ 629 1.1 christos *data = mec_memcfg; 630 1.1 christos break; 631 1.1 christos 632 1.1 christos case MEC_IOCR: 633 1.1 christos *data = mec_iocr; /* 0x14 */ 634 1.1 christos break; 635 1.1 christos 636 1.1 christos case MEC_SSA1: /* 0x20 */ 637 1.1 christos *data = mec_ssa[0] | (mec_wpr[0] << 23); 638 1.1 christos break; 639 1.1 christos case MEC_SEA1: /* 0x24 */ 640 1.1 christos *data = mec_sea[0]; 641 1.1 christos break; 642 1.1 christos case MEC_SSA2: /* 0x28 */ 643 1.1 christos *data = mec_ssa[1] | (mec_wpr[1] << 23); 644 1.1 christos break; 645 1.1 christos case MEC_SEA2: /* 0x2c */ 646 1.1 christos *data = mec_sea[1]; 647 1.1 christos break; 648 1.1 christos 649 1.1 christos case MEC_ISR: /* 0x44 */ 650 1.1 christos *data = mec_isr; 651 1.1 christos break; 652 1.1 christos 653 1.1 christos case MEC_IPR: /* 0x48 */ 654 1.1 christos *data = mec_ipr; 655 1.1 christos break; 656 1.1 christos 657 1.1 christos case MEC_IMR: /* 0x4c */ 658 1.1 christos *data = mec_imr; 659 1.1 christos break; 660 1.1 christos 661 1.1 christos case MEC_IFR: /* 0x54 */ 662 1.1 christos *data = mec_ifr; 663 1.1 christos break; 664 1.1 christos 665 1.1 christos case MEC_RTC_COUNTER: /* 0x80 */ 666 1.1 christos *data = rtc_counter_read(); 667 1.1 christos break; 668 1.1 christos case MEC_RTC_SCALER: /* 0x84 */ 669 1.1 christos if (rtc_enabled) 670 1.1 christos *data = rtc_scaler - (now() - rtc_scaler_start); 671 1.1 christos else 672 1.1 christos *data = rtc_scaler; 673 1.1 christos break; 674 1.1 christos 675 1.1 christos case MEC_GPT_COUNTER: /* 0x88 */ 676 1.1 christos *data = gpt_counter_read(); 677 1.1 christos break; 678 1.1 christos 679 1.1 christos case MEC_GPT_SCALER: /* 0x8c */ 680 1.1 christos if (rtc_enabled) 681 1.1 christos *data = gpt_scaler - (now() - gpt_scaler_start); 682 1.1 christos else 683 1.1 christos *data = gpt_scaler; 684 1.1 christos break; 685 1.1 christos 686 1.1 christos 687 1.1 christos case MEC_SFSR: /* 0xA0 */ 688 1.1 christos *data = mec_sfsr; 689 1.1 christos break; 690 1.1 christos 691 1.1 christos case MEC_FFAR: /* 0xA4 */ 692 1.1 christos *data = mec_ffar; 693 1.1 christos break; 694 1.1 christos 695 1.1 christos case SIM_LOAD: 696 1.1 christos fname[find] = 0; 697 1.1 christos if (find == 0) 698 1.1 christos strcpy(fname, "simload"); 699 1.1 christos find = bfd_load(fname); 700 1.1 christos if (find == -1) 701 1.1 christos *data = 0; 702 1.1 christos else 703 1.1 christos *data = 1; 704 1.1 christos find = 0; 705 1.1 christos break; 706 1.1 christos 707 1.1 christos case MEC_ERSR: /* 0xB0 */ 708 1.1 christos *data = mec_ersr; 709 1.1 christos break; 710 1.1 christos 711 1.1 christos case MEC_TCR: /* 0xD0 */ 712 1.1 christos *data = mec_tcr; 713 1.1 christos break; 714 1.1 christos 715 1.1 christos case MEC_UARTA: /* 0xE0 */ 716 1.1 christos case MEC_UARTB: /* 0xE4 */ 717 1.1 christos if (asi != 0xb) { 718 1.1 christos set_sfsr(MEC_ACC, addr, asi, 1); 719 1.5 christos return 1; 720 1.1 christos } 721 1.1 christos *data = read_uart(addr); 722 1.1 christos break; 723 1.1 christos 724 1.1 christos case MEC_UART_CTRL: /* 0xE8 */ 725 1.1 christos 726 1.1 christos *data = read_uart(addr); 727 1.1 christos break; 728 1.1 christos 729 1.5 christos case 0xF4: /* simulator RAM size in bytes */ 730 1.5 christos *data = 4096*1024; 731 1.5 christos break; 732 1.5 christos 733 1.5 christos case 0xF8: /* simulator ROM size in bytes */ 734 1.5 christos *data = 1024*1024; 735 1.5 christos break; 736 1.5 christos 737 1.1 christos default: 738 1.1 christos set_sfsr(MEC_ACC, addr, asi, 1); 739 1.5 christos return 1; 740 1.1 christos break; 741 1.1 christos } 742 1.5 christos return MOK; 743 1.1 christos } 744 1.1 christos 745 1.1 christos static int 746 1.10 christos mec_write(uint32_t addr, uint32_t data) 747 1.1 christos { 748 1.1 christos if (sis_verbose > 1) 749 1.1 christos printf("MEC write a: %08x, d: %08x\n",addr,data); 750 1.1 christos switch (addr & 0x0ff) { 751 1.1 christos 752 1.1 christos case MEC_MCR: 753 1.1 christos mec_mcr = data; 754 1.1 christos decode_mcr(); 755 1.1 christos if (mec_mcr & 0x08000) mecparerror(); 756 1.1 christos break; 757 1.1 christos 758 1.1 christos case MEC_SFR: 759 1.1 christos if (mec_mcr & 0x2) { 760 1.1 christos sys_reset(); 761 1.1 christos mec_ersr = 0x4000; 762 1.1 christos if (sis_verbose) 763 1.1 christos printf(" Software reset issued\n"); 764 1.1 christos } 765 1.1 christos break; 766 1.1 christos 767 1.1 christos case MEC_IOCR: 768 1.1 christos mec_iocr = data; 769 1.1 christos if (mec_iocr & 0xC0C0C0C0) mecparerror(); 770 1.1 christos break; 771 1.1 christos 772 1.1 christos case MEC_SSA1: /* 0x20 */ 773 1.1 christos if (data & 0xFE000000) mecparerror(); 774 1.1 christos mec_ssa[0] = data & 0x7fffff; 775 1.1 christos mec_wpr[0] = (data >> 23) & 0x03; 776 1.1 christos mem_accprot = mec_wpr[0] || mec_wpr[1]; 777 1.1 christos if (sis_verbose && mec_wpr[0]) 778 1.1 christos printf("Segment 1 memory protection enabled (0x02%06x - 0x02%06x)\n", 779 1.1 christos mec_ssa[0] << 2, mec_sea[0] << 2); 780 1.1 christos break; 781 1.1 christos case MEC_SEA1: /* 0x24 */ 782 1.1 christos if (data & 0xFF800000) mecparerror(); 783 1.1 christos mec_sea[0] = data & 0x7fffff; 784 1.1 christos break; 785 1.1 christos case MEC_SSA2: /* 0x28 */ 786 1.1 christos if (data & 0xFE000000) mecparerror(); 787 1.1 christos mec_ssa[1] = data & 0x7fffff; 788 1.1 christos mec_wpr[1] = (data >> 23) & 0x03; 789 1.1 christos mem_accprot = mec_wpr[0] || mec_wpr[1]; 790 1.1 christos if (sis_verbose && mec_wpr[1]) 791 1.1 christos printf("Segment 2 memory protection enabled (0x02%06x - 0x02%06x)\n", 792 1.1 christos mec_ssa[1] << 2, mec_sea[1] << 2); 793 1.1 christos break; 794 1.1 christos case MEC_SEA2: /* 0x2c */ 795 1.1 christos if (data & 0xFF800000) mecparerror(); 796 1.1 christos mec_sea[1] = data & 0x7fffff; 797 1.1 christos break; 798 1.1 christos 799 1.1 christos case MEC_UARTA: 800 1.1 christos case MEC_UARTB: 801 1.1 christos if (data & 0xFFFFFF00) mecparerror(); 802 1.11 christos ATTRIBUTE_FALLTHROUGH; 803 1.1 christos case MEC_UART_CTRL: 804 1.1 christos if (data & 0xFF00FF00) mecparerror(); 805 1.1 christos write_uart(addr, data); 806 1.1 christos break; 807 1.1 christos 808 1.1 christos case MEC_GPT_RELOAD: 809 1.1 christos gpt_reload_set(data); 810 1.1 christos break; 811 1.1 christos 812 1.1 christos case MEC_GPT_SCALER: 813 1.1 christos if (data & 0xFFFF0000) mecparerror(); 814 1.1 christos gpt_scaler_set(data); 815 1.1 christos break; 816 1.1 christos 817 1.1 christos case MEC_TIMER_CTRL: 818 1.1 christos if (data & 0xFFFFF0F0) mecparerror(); 819 1.1 christos timer_ctrl(data); 820 1.1 christos break; 821 1.1 christos 822 1.1 christos case MEC_RTC_RELOAD: 823 1.1 christos rtc_reload_set(data); 824 1.1 christos break; 825 1.1 christos 826 1.1 christos case MEC_RTC_SCALER: 827 1.1 christos if (data & 0xFFFFFF00) mecparerror(); 828 1.1 christos rtc_scaler_set(data); 829 1.1 christos break; 830 1.1 christos 831 1.1 christos case MEC_SFSR: /* 0xA0 */ 832 1.1 christos if (data & 0xFFFF0880) mecparerror(); 833 1.1 christos mec_sfsr = 0x78; 834 1.1 christos break; 835 1.1 christos 836 1.1 christos case MEC_ISR: 837 1.1 christos if (data & 0xFFFFE000) mecparerror(); 838 1.1 christos mec_isr = data; 839 1.1 christos break; 840 1.1 christos 841 1.1 christos case MEC_IMR: /* 0x4c */ 842 1.1 christos 843 1.1 christos if (data & 0xFFFF8001) mecparerror(); 844 1.1 christos mec_imr = data & 0x7ffe; 845 1.1 christos chk_irq(); 846 1.1 christos break; 847 1.1 christos 848 1.1 christos case MEC_ICR: /* 0x50 */ 849 1.1 christos 850 1.1 christos if (data & 0xFFFF0001) mecparerror(); 851 1.1 christos mec_ipr &= ~data & 0x0fffe; 852 1.1 christos chk_irq(); 853 1.1 christos break; 854 1.1 christos 855 1.1 christos case MEC_IFR: /* 0x54 */ 856 1.1 christos 857 1.1 christos if (mec_tcr & 0x080000) { 858 1.1 christos if (data & 0xFFFF0001) mecparerror(); 859 1.1 christos mec_ifr = data & 0xfffe; 860 1.1 christos chk_irq(); 861 1.1 christos } 862 1.1 christos break; 863 1.1 christos case SIM_LOAD: 864 1.1 christos fname[find++] = (char) data; 865 1.1 christos break; 866 1.1 christos 867 1.1 christos 868 1.1 christos case MEC_MEMCFG: /* 0x10 */ 869 1.1 christos if (data & 0xC0E08000) mecparerror(); 870 1.1 christos mec_memcfg = data; 871 1.1 christos decode_memcfg(); 872 1.1 christos if (mec_memcfg & 0xc0e08000) 873 1.1 christos mecparerror(); 874 1.1 christos break; 875 1.1 christos 876 1.1 christos case MEC_WCR: /* 0x18 */ 877 1.1 christos mec_wcr = data; 878 1.1 christos decode_wcr(); 879 1.1 christos break; 880 1.1 christos 881 1.1 christos case MEC_ERSR: /* 0xB0 */ 882 1.1 christos if (mec_tcr & 0x100000) 883 1.10 christos if (data & 0xFFFFEFC0) mecparerror(); 884 1.1 christos mec_ersr = data & 0x103f; 885 1.1 christos break; 886 1.1 christos 887 1.1 christos case MEC_TCR: /* 0xD0 */ 888 1.1 christos if (data & 0xFFE1FFC0) mecparerror(); 889 1.1 christos mec_tcr = data & 0x1e003f; 890 1.1 christos break; 891 1.1 christos 892 1.1 christos case MEC_WDOG: /* 0x60 */ 893 1.1 christos wdog_scaler = (data >> 16) & 0x0ff; 894 1.1 christos wdog_counter = data & 0x0ffff; 895 1.1 christos wdog_rst_delay = data >> 24; 896 1.1 christos wdog_rston = 0; 897 1.1 christos if (wdog_status == stopped) 898 1.1 christos wdog_start(); 899 1.1 christos wdog_status = enabled; 900 1.1 christos break; 901 1.1 christos 902 1.1 christos case MEC_TRAPD: /* 0x64 */ 903 1.1 christos if (wdog_status == init) { 904 1.1 christos wdog_status = disabled; 905 1.1 christos if (sis_verbose) 906 1.1 christos printf("Watchdog disabled\n"); 907 1.1 christos } 908 1.1 christos break; 909 1.1 christos 910 1.1 christos case MEC_PWDR: 911 1.1 christos if (mec_mcr & 1) 912 1.1 christos wait_for_irq(); 913 1.1 christos break; 914 1.1 christos 915 1.1 christos default: 916 1.1 christos set_sfsr(MEC_ACC, addr, 0xb, 0); 917 1.5 christos return 1; 918 1.1 christos break; 919 1.1 christos } 920 1.5 christos return MOK; 921 1.1 christos } 922 1.1 christos 923 1.1 christos 924 1.1 christos /* MEC UARTS */ 925 1.1 christos 926 1.1 christos static int ifd1 = -1, ifd2 = -1, ofd1 = -1, ofd2 = -1; 927 1.1 christos 928 1.1 christos void 929 1.10 christos init_stdio(void) 930 1.1 christos { 931 1.1 christos if (dumbio) 932 1.1 christos return; /* do nothing */ 933 1.10 christos #ifdef HAVE_TERMIOS_H 934 1.1 christos if (!ifd1) 935 1.1 christos tcsetattr(0, TCSANOW, &ioc1); 936 1.1 christos if (!ifd2) 937 1.1 christos tcsetattr(0, TCSANOW, &ioc2); 938 1.10 christos #endif 939 1.1 christos } 940 1.1 christos 941 1.1 christos void 942 1.10 christos restore_stdio(void) 943 1.1 christos { 944 1.1 christos if (dumbio) 945 1.1 christos return; /* do nothing */ 946 1.10 christos #ifdef HAVE_TERMIOS_H 947 1.1 christos if (!ifd1) 948 1.1 christos tcsetattr(0, TCSANOW, &iocold1); 949 1.1 christos if (!ifd2) 950 1.1 christos tcsetattr(0, TCSANOW, &iocold2); 951 1.10 christos #endif 952 1.1 christos } 953 1.1 christos 954 1.1 christos #define DO_STDIO_READ( _fd_, _buf_, _len_ ) \ 955 1.1 christos ( dumbio \ 956 1.1 christos ? (0) /* no bytes read, no delay */ \ 957 1.1 christos : read( _fd_, _buf_, _len_ ) ) 958 1.1 christos 959 1.1 christos 960 1.1 christos static void 961 1.10 christos port_init(void) 962 1.1 christos { 963 1.1 christos 964 1.1 christos if (uben) { 965 1.1 christos f2in = stdin; 966 1.1 christos f1in = NULL; 967 1.1 christos f2out = stdout; 968 1.1 christos f1out = NULL; 969 1.1 christos } else { 970 1.1 christos f1in = stdin; 971 1.1 christos f2in = NULL; 972 1.1 christos f1out = stdout; 973 1.1 christos f2out = NULL; 974 1.1 christos } 975 1.10 christos if (uart_dev1[0] != 0) { 976 1.1 christos if ((fd1 = open(uart_dev1, O_RDWR | O_NONBLOCK)) < 0) { 977 1.1 christos printf("Warning, couldn't open output device %s\n", uart_dev1); 978 1.1 christos } else { 979 1.1 christos if (sis_verbose) 980 1.1 christos printf("serial port A on %s\n", uart_dev1); 981 1.1 christos f1in = f1out = fdopen(fd1, "r+"); 982 1.1 christos setbuf(f1out, NULL); 983 1.1 christos f1open = 1; 984 1.1 christos } 985 1.10 christos } 986 1.1 christos if (f1in) ifd1 = fileno(f1in); 987 1.1 christos if (ifd1 == 0) { 988 1.1 christos if (sis_verbose) 989 1.1 christos printf("serial port A on stdin/stdout\n"); 990 1.1 christos if (!dumbio) { 991 1.10 christos #ifdef HAVE_TERMIOS_H 992 1.1 christos tcgetattr(ifd1, &ioc1); 993 1.1 christos iocold1 = ioc1; 994 1.1 christos ioc1.c_lflag &= ~(ICANON | ECHO); 995 1.1 christos ioc1.c_cc[VMIN] = 0; 996 1.1 christos ioc1.c_cc[VTIME] = 0; 997 1.10 christos #endif 998 1.1 christos } 999 1.1 christos f1open = 1; 1000 1.1 christos } 1001 1.1 christos 1002 1.1 christos if (f1out) { 1003 1.1 christos ofd1 = fileno(f1out); 1004 1.1 christos if (!dumbio && ofd1 == 1) setbuf(f1out, NULL); 1005 1.1 christos } 1006 1.1 christos 1007 1.10 christos if (uart_dev2[0] != 0) { 1008 1.1 christos if ((fd2 = open(uart_dev2, O_RDWR | O_NONBLOCK)) < 0) { 1009 1.1 christos printf("Warning, couldn't open output device %s\n", uart_dev2); 1010 1.1 christos } else { 1011 1.1 christos if (sis_verbose) 1012 1.1 christos printf("serial port B on %s\n", uart_dev2); 1013 1.1 christos f2in = f2out = fdopen(fd2, "r+"); 1014 1.1 christos setbuf(f2out, NULL); 1015 1.1 christos f2open = 1; 1016 1.1 christos } 1017 1.10 christos } 1018 1.1 christos if (f2in) ifd2 = fileno(f2in); 1019 1.1 christos if (ifd2 == 0) { 1020 1.1 christos if (sis_verbose) 1021 1.1 christos printf("serial port B on stdin/stdout\n"); 1022 1.1 christos if (!dumbio) { 1023 1.10 christos #ifdef HAVE_TERMIOS_H 1024 1.1 christos tcgetattr(ifd2, &ioc2); 1025 1.1 christos iocold2 = ioc2; 1026 1.1 christos ioc2.c_lflag &= ~(ICANON | ECHO); 1027 1.1 christos ioc2.c_cc[VMIN] = 0; 1028 1.1 christos ioc2.c_cc[VTIME] = 0; 1029 1.10 christos #endif 1030 1.1 christos } 1031 1.1 christos f2open = 1; 1032 1.1 christos } 1033 1.1 christos 1034 1.1 christos if (f2out) { 1035 1.1 christos ofd2 = fileno(f2out); 1036 1.1 christos if (!dumbio && ofd2 == 1) setbuf(f2out, NULL); 1037 1.1 christos } 1038 1.1 christos 1039 1.1 christos wnuma = wnumb = 0; 1040 1.1 christos 1041 1.1 christos } 1042 1.1 christos 1043 1.10 christos static uint32_t 1044 1.10 christos read_uart(uint32_t addr) 1045 1.1 christos { 1046 1.1 christos switch (addr & 0xff) { 1047 1.1 christos 1048 1.1 christos case 0xE0: /* UART 1 */ 1049 1.1 christos #ifndef _WIN32 1050 1.1 christos #ifdef FAST_UART 1051 1.1 christos 1052 1.1 christos if (aind < anum) { 1053 1.1 christos if ((aind + 1) < anum) 1054 1.1 christos mec_irq(4); 1055 1.10 christos return (0x700 | (uint32_t) aq[aind++]); 1056 1.1 christos } else { 1057 1.1 christos if (f1open) { 1058 1.1 christos anum = DO_STDIO_READ(ifd1, aq, UARTBUF); 1059 1.1 christos } 1060 1.1 christos if (anum > 0) { 1061 1.1 christos aind = 0; 1062 1.1 christos if ((aind + 1) < anum) 1063 1.1 christos mec_irq(4); 1064 1.10 christos return (0x700 | (uint32_t) aq[aind++]); 1065 1.1 christos } else { 1066 1.10 christos return (0x600 | (uint32_t) aq[aind]); 1067 1.1 christos } 1068 1.1 christos 1069 1.1 christos } 1070 1.1 christos #else 1071 1.11 christos unsigned tmp = uarta_data; 1072 1.1 christos uarta_data &= ~UART_DR; 1073 1.1 christos uart_stat_reg &= ~UARTA_DR; 1074 1.1 christos return tmp; 1075 1.1 christos #endif 1076 1.1 christos #else 1077 1.5 christos return 0; 1078 1.1 christos #endif 1079 1.1 christos break; 1080 1.1 christos 1081 1.1 christos case 0xE4: /* UART 2 */ 1082 1.1 christos #ifndef _WIN32 1083 1.1 christos #ifdef FAST_UART 1084 1.1 christos if (bind < bnum) { 1085 1.1 christos if ((bind + 1) < bnum) 1086 1.1 christos mec_irq(5); 1087 1.10 christos return (0x700 | (uint32_t) bq[bind++]); 1088 1.1 christos } else { 1089 1.1 christos if (f2open) { 1090 1.1 christos bnum = DO_STDIO_READ(ifd2, bq, UARTBUF); 1091 1.1 christos } 1092 1.1 christos if (bnum > 0) { 1093 1.1 christos bind = 0; 1094 1.1 christos if ((bind + 1) < bnum) 1095 1.1 christos mec_irq(5); 1096 1.10 christos return (0x700 | (uint32_t) bq[bind++]); 1097 1.1 christos } else { 1098 1.10 christos return (0x600 | (uint32_t) bq[bind]); 1099 1.1 christos } 1100 1.1 christos 1101 1.1 christos } 1102 1.1 christos #else 1103 1.11 christos unsigned tmp = uartb_data; 1104 1.1 christos uartb_data &= ~UART_DR; 1105 1.1 christos uart_stat_reg &= ~UARTB_DR; 1106 1.1 christos return tmp; 1107 1.1 christos #endif 1108 1.1 christos #else 1109 1.5 christos return 0; 1110 1.1 christos #endif 1111 1.1 christos break; 1112 1.1 christos 1113 1.1 christos case 0xE8: /* UART status register */ 1114 1.1 christos #ifndef _WIN32 1115 1.1 christos #ifdef FAST_UART 1116 1.1 christos 1117 1.1 christos Ucontrol = 0; 1118 1.1 christos if (aind < anum) { 1119 1.1 christos Ucontrol |= 0x00000001; 1120 1.1 christos } else { 1121 1.1 christos if (f1open) { 1122 1.1 christos anum = DO_STDIO_READ(ifd1, aq, UARTBUF); 1123 1.1 christos } 1124 1.1 christos if (anum > 0) { 1125 1.1 christos Ucontrol |= 0x00000001; 1126 1.1 christos aind = 0; 1127 1.1 christos mec_irq(4); 1128 1.1 christos } 1129 1.1 christos } 1130 1.1 christos if (bind < bnum) { 1131 1.1 christos Ucontrol |= 0x00010000; 1132 1.1 christos } else { 1133 1.1 christos if (f2open) { 1134 1.1 christos bnum = DO_STDIO_READ(ifd2, bq, UARTBUF); 1135 1.1 christos } 1136 1.1 christos if (bnum > 0) { 1137 1.1 christos Ucontrol |= 0x00010000; 1138 1.1 christos bind = 0; 1139 1.1 christos mec_irq(5); 1140 1.1 christos } 1141 1.1 christos } 1142 1.1 christos 1143 1.1 christos Ucontrol |= 0x00060006; 1144 1.5 christos return Ucontrol; 1145 1.1 christos #else 1146 1.5 christos return uart_stat_reg; 1147 1.1 christos #endif 1148 1.1 christos #else 1149 1.5 christos return 0x00060006; 1150 1.1 christos #endif 1151 1.1 christos break; 1152 1.1 christos default: 1153 1.1 christos if (sis_verbose) 1154 1.1 christos printf("Read from unimplemented MEC register (%x)\n", addr); 1155 1.1 christos 1156 1.1 christos } 1157 1.5 christos return 0; 1158 1.1 christos } 1159 1.1 christos 1160 1.1 christos static void 1161 1.10 christos write_uart(uint32_t addr, uint32_t data) 1162 1.1 christos { 1163 1.1 christos unsigned char c; 1164 1.1 christos 1165 1.1 christos c = (unsigned char) data; 1166 1.1 christos switch (addr & 0xff) { 1167 1.1 christos 1168 1.1 christos case 0xE0: /* UART A */ 1169 1.1 christos #ifdef FAST_UART 1170 1.1 christos if (f1open) { 1171 1.1 christos if (wnuma < UARTBUF) 1172 1.1 christos wbufa[wnuma++] = c; 1173 1.1 christos else { 1174 1.1 christos while (wnuma) 1175 1.1 christos wnuma -= fwrite(wbufa, 1, wnuma, f1out); 1176 1.1 christos wbufa[wnuma++] = c; 1177 1.1 christos } 1178 1.1 christos } 1179 1.1 christos mec_irq(4); 1180 1.1 christos #else 1181 1.1 christos if (uart_stat_reg & UARTA_SRE) { 1182 1.1 christos uarta_sreg = c; 1183 1.1 christos uart_stat_reg &= ~UARTA_SRE; 1184 1.1 christos event(uarta_tx, 0, UART_TX_TIME); 1185 1.1 christos } else { 1186 1.1 christos uarta_hreg = c; 1187 1.1 christos uart_stat_reg &= ~UARTA_HRE; 1188 1.1 christos } 1189 1.1 christos #endif 1190 1.1 christos break; 1191 1.1 christos 1192 1.1 christos case 0xE4: /* UART B */ 1193 1.1 christos #ifdef FAST_UART 1194 1.1 christos if (f2open) { 1195 1.1 christos if (wnumb < UARTBUF) 1196 1.1 christos wbufb[wnumb++] = c; 1197 1.1 christos else { 1198 1.1 christos while (wnumb) 1199 1.1 christos wnumb -= fwrite(wbufb, 1, wnumb, f2out); 1200 1.1 christos wbufb[wnumb++] = c; 1201 1.1 christos } 1202 1.1 christos } 1203 1.1 christos mec_irq(5); 1204 1.1 christos #else 1205 1.1 christos if (uart_stat_reg & UARTB_SRE) { 1206 1.1 christos uartb_sreg = c; 1207 1.1 christos uart_stat_reg &= ~UARTB_SRE; 1208 1.1 christos event(uartb_tx, 0, UART_TX_TIME); 1209 1.1 christos } else { 1210 1.1 christos uartb_hreg = c; 1211 1.1 christos uart_stat_reg &= ~UARTB_HRE; 1212 1.1 christos } 1213 1.1 christos #endif 1214 1.1 christos break; 1215 1.1 christos case 0xE8: /* UART status register */ 1216 1.1 christos #ifndef FAST_UART 1217 1.1 christos if (data & UARTA_CLR) { 1218 1.1 christos uart_stat_reg &= 0xFFFF0000; 1219 1.1 christos uart_stat_reg |= UARTA_SRE | UARTA_HRE; 1220 1.1 christos } 1221 1.1 christos if (data & UARTB_CLR) { 1222 1.1 christos uart_stat_reg &= 0x0000FFFF; 1223 1.1 christos uart_stat_reg |= UARTB_SRE | UARTB_HRE; 1224 1.1 christos } 1225 1.1 christos #endif 1226 1.1 christos break; 1227 1.1 christos default: 1228 1.1 christos if (sis_verbose) 1229 1.1 christos printf("Write to unimplemented MEC register (%x)\n", addr); 1230 1.1 christos 1231 1.1 christos } 1232 1.1 christos } 1233 1.1 christos 1234 1.1 christos static void 1235 1.10 christos flush_uart(void) 1236 1.1 christos { 1237 1.1 christos while (wnuma && f1open) 1238 1.1 christos wnuma -= fwrite(wbufa, 1, wnuma, f1out); 1239 1.1 christos while (wnumb && f2open) 1240 1.1 christos wnumb -= fwrite(wbufb, 1, wnumb, f2out); 1241 1.1 christos } 1242 1.1 christos 1243 1.10 christos ATTRIBUTE_UNUSED 1244 1.1 christos static void 1245 1.10 christos uarta_tx(int32_t arg ATTRIBUTE_UNUSED) 1246 1.1 christos { 1247 1.1 christos 1248 1.1 christos while (f1open && fwrite(&uarta_sreg, 1, 1, f1out) != 1); 1249 1.1 christos if (uart_stat_reg & UARTA_HRE) { 1250 1.1 christos uart_stat_reg |= UARTA_SRE; 1251 1.1 christos } else { 1252 1.1 christos uarta_sreg = uarta_hreg; 1253 1.1 christos uart_stat_reg |= UARTA_HRE; 1254 1.1 christos event(uarta_tx, 0, UART_TX_TIME); 1255 1.1 christos } 1256 1.1 christos mec_irq(4); 1257 1.1 christos } 1258 1.1 christos 1259 1.10 christos ATTRIBUTE_UNUSED 1260 1.1 christos static void 1261 1.10 christos uartb_tx(int32_t arg ATTRIBUTE_UNUSED) 1262 1.1 christos { 1263 1.1 christos while (f2open && fwrite(&uartb_sreg, 1, 1, f2out) != 1); 1264 1.1 christos if (uart_stat_reg & UARTB_HRE) { 1265 1.1 christos uart_stat_reg |= UARTB_SRE; 1266 1.1 christos } else { 1267 1.1 christos uartb_sreg = uartb_hreg; 1268 1.1 christos uart_stat_reg |= UARTB_HRE; 1269 1.1 christos event(uartb_tx, 0, UART_TX_TIME); 1270 1.1 christos } 1271 1.1 christos mec_irq(5); 1272 1.1 christos } 1273 1.1 christos 1274 1.10 christos ATTRIBUTE_UNUSED 1275 1.1 christos static void 1276 1.10 christos uart_rx(int32_t arg ATTRIBUTE_UNUSED) 1277 1.1 christos { 1278 1.10 christos int32_t rsize; 1279 1.1 christos char rxd; 1280 1.1 christos 1281 1.1 christos 1282 1.1 christos rsize = 0; 1283 1.1 christos if (f1open) 1284 1.1 christos rsize = DO_STDIO_READ(ifd1, &rxd, 1); 1285 1.1 christos if (rsize > 0) { 1286 1.1 christos uarta_data = UART_DR | rxd; 1287 1.1 christos if (uart_stat_reg & UARTA_HRE) 1288 1.1 christos uarta_data |= UART_THE; 1289 1.1 christos if (uart_stat_reg & UARTA_SRE) 1290 1.1 christos uarta_data |= UART_TSE; 1291 1.1 christos if (uart_stat_reg & UARTA_DR) { 1292 1.1 christos uart_stat_reg |= UARTA_OR; 1293 1.1 christos mec_irq(7); /* UART error interrupt */ 1294 1.1 christos } 1295 1.1 christos uart_stat_reg |= UARTA_DR; 1296 1.1 christos mec_irq(4); 1297 1.1 christos } 1298 1.1 christos rsize = 0; 1299 1.1 christos if (f2open) 1300 1.1 christos rsize = DO_STDIO_READ(ifd2, &rxd, 1); 1301 1.1 christos if (rsize) { 1302 1.1 christos uartb_data = UART_DR | rxd; 1303 1.1 christos if (uart_stat_reg & UARTB_HRE) 1304 1.1 christos uartb_data |= UART_THE; 1305 1.1 christos if (uart_stat_reg & UARTB_SRE) 1306 1.1 christos uartb_data |= UART_TSE; 1307 1.1 christos if (uart_stat_reg & UARTB_DR) { 1308 1.1 christos uart_stat_reg |= UARTB_OR; 1309 1.1 christos mec_irq(7); /* UART error interrupt */ 1310 1.1 christos } 1311 1.1 christos uart_stat_reg |= UARTB_DR; 1312 1.1 christos mec_irq(5); 1313 1.1 christos } 1314 1.1 christos event(uart_rx, 0, UART_RX_TIME); 1315 1.1 christos } 1316 1.1 christos 1317 1.1 christos static void 1318 1.10 christos uart_intr(int32_t arg ATTRIBUTE_UNUSED) 1319 1.1 christos { 1320 1.1 christos read_uart(0xE8); /* Check for UART interrupts every 1000 clk */ 1321 1.1 christos flush_uart(); /* Flush UART ports */ 1322 1.1 christos event(uart_intr, 0, UART_FLUSH_TIME); 1323 1.1 christos } 1324 1.1 christos 1325 1.1 christos 1326 1.1 christos static void 1327 1.10 christos uart_irq_start(void) 1328 1.1 christos { 1329 1.1 christos #ifdef FAST_UART 1330 1.1 christos event(uart_intr, 0, UART_FLUSH_TIME); 1331 1.1 christos #else 1332 1.1 christos #ifndef _WIN32 1333 1.1 christos event(uart_rx, 0, UART_RX_TIME); 1334 1.1 christos #endif 1335 1.1 christos #endif 1336 1.1 christos } 1337 1.1 christos 1338 1.1 christos /* Watch-dog */ 1339 1.1 christos 1340 1.1 christos static void 1341 1.10 christos wdog_intr(int32_t arg ATTRIBUTE_UNUSED) 1342 1.1 christos { 1343 1.1 christos if (wdog_status == disabled) { 1344 1.1 christos wdog_status = stopped; 1345 1.1 christos } else { 1346 1.1 christos 1347 1.1 christos if (wdog_counter) { 1348 1.1 christos wdog_counter--; 1349 1.1 christos event(wdog_intr, 0, wdog_scaler + 1); 1350 1.1 christos } else { 1351 1.1 christos if (wdog_rston) { 1352 1.1 christos printf("Watchdog reset!\n"); 1353 1.1 christos sys_reset(); 1354 1.1 christos mec_ersr = 0xC000; 1355 1.1 christos } else { 1356 1.1 christos mec_irq(15); 1357 1.1 christos wdog_rston = 1; 1358 1.1 christos wdog_counter = wdog_rst_delay; 1359 1.1 christos event(wdog_intr, 0, wdog_scaler + 1); 1360 1.1 christos } 1361 1.1 christos } 1362 1.1 christos } 1363 1.1 christos } 1364 1.1 christos 1365 1.1 christos static void 1366 1.10 christos wdog_start(void) 1367 1.1 christos { 1368 1.1 christos event(wdog_intr, 0, wdog_scaler + 1); 1369 1.1 christos if (sis_verbose) 1370 1.1 christos printf("Watchdog started, scaler = %d, counter = %d\n", 1371 1.1 christos wdog_scaler, wdog_counter); 1372 1.1 christos } 1373 1.1 christos 1374 1.1 christos 1375 1.1 christos /* MEC timers */ 1376 1.1 christos 1377 1.1 christos 1378 1.1 christos static void 1379 1.10 christos rtc_intr(int32_t arg ATTRIBUTE_UNUSED) 1380 1.1 christos { 1381 1.1 christos if (rtc_counter == 0) { 1382 1.1 christos 1383 1.1 christos mec_irq(13); 1384 1.1 christos if (rtc_cr) 1385 1.1 christos rtc_counter = rtc_reload; 1386 1.1 christos else 1387 1.1 christos rtc_se = 0; 1388 1.1 christos } else 1389 1.1 christos rtc_counter -= 1; 1390 1.1 christos if (rtc_se) { 1391 1.1 christos event(rtc_intr, 0, rtc_scaler + 1); 1392 1.1 christos rtc_scaler_start = now(); 1393 1.1 christos rtc_enabled = 1; 1394 1.1 christos } else { 1395 1.1 christos if (sis_verbose) 1396 1.1 christos printf("RTC stopped\n\r"); 1397 1.1 christos rtc_enabled = 0; 1398 1.1 christos } 1399 1.1 christos } 1400 1.1 christos 1401 1.1 christos static void 1402 1.10 christos rtc_start(void) 1403 1.1 christos { 1404 1.1 christos if (sis_verbose) 1405 1.1 christos printf("RTC started (period %d)\n\r", rtc_scaler + 1); 1406 1.1 christos event(rtc_intr, 0, rtc_scaler + 1); 1407 1.1 christos rtc_scaler_start = now(); 1408 1.1 christos rtc_enabled = 1; 1409 1.1 christos } 1410 1.1 christos 1411 1.10 christos static uint32_t 1412 1.10 christos rtc_counter_read(void) 1413 1.1 christos { 1414 1.5 christos return rtc_counter; 1415 1.1 christos } 1416 1.1 christos 1417 1.1 christos static void 1418 1.10 christos rtc_scaler_set(uint32_t val) 1419 1.1 christos { 1420 1.1 christos rtc_scaler = val & 0x0ff; /* eight-bit scaler only */ 1421 1.1 christos } 1422 1.1 christos 1423 1.1 christos static void 1424 1.10 christos rtc_reload_set(uint32_t val) 1425 1.1 christos { 1426 1.1 christos rtc_reload = val; 1427 1.1 christos } 1428 1.1 christos 1429 1.1 christos static void 1430 1.10 christos gpt_intr(int32_t arg ATTRIBUTE_UNUSED) 1431 1.1 christos { 1432 1.1 christos if (gpt_counter == 0) { 1433 1.1 christos mec_irq(12); 1434 1.1 christos if (gpt_cr) 1435 1.1 christos gpt_counter = gpt_reload; 1436 1.1 christos else 1437 1.1 christos gpt_se = 0; 1438 1.1 christos } else 1439 1.1 christos gpt_counter -= 1; 1440 1.1 christos if (gpt_se) { 1441 1.1 christos event(gpt_intr, 0, gpt_scaler + 1); 1442 1.1 christos gpt_scaler_start = now(); 1443 1.1 christos gpt_enabled = 1; 1444 1.1 christos } else { 1445 1.1 christos if (sis_verbose) 1446 1.1 christos printf("GPT stopped\n\r"); 1447 1.1 christos gpt_enabled = 0; 1448 1.1 christos } 1449 1.1 christos } 1450 1.1 christos 1451 1.1 christos static void 1452 1.10 christos gpt_start(void) 1453 1.1 christos { 1454 1.1 christos if (sis_verbose) 1455 1.1 christos printf("GPT started (period %d)\n\r", gpt_scaler + 1); 1456 1.1 christos event(gpt_intr, 0, gpt_scaler + 1); 1457 1.1 christos gpt_scaler_start = now(); 1458 1.1 christos gpt_enabled = 1; 1459 1.1 christos } 1460 1.1 christos 1461 1.10 christos static uint32_t 1462 1.10 christos gpt_counter_read(void) 1463 1.1 christos { 1464 1.5 christos return gpt_counter; 1465 1.1 christos } 1466 1.1 christos 1467 1.1 christos static void 1468 1.10 christos gpt_scaler_set(uint32_t val) 1469 1.1 christos { 1470 1.1 christos gpt_scaler = val & 0x0ffff; /* 16-bit scaler */ 1471 1.1 christos } 1472 1.1 christos 1473 1.1 christos static void 1474 1.10 christos gpt_reload_set(uint32_t val) 1475 1.1 christos { 1476 1.1 christos gpt_reload = val; 1477 1.1 christos } 1478 1.1 christos 1479 1.1 christos static void 1480 1.10 christos timer_ctrl(uint32_t val) 1481 1.1 christos { 1482 1.1 christos 1483 1.1 christos rtc_cr = ((val & TCR_TCRCR) != 0); 1484 1.1 christos if (val & TCR_TCRCL) { 1485 1.1 christos rtc_counter = rtc_reload; 1486 1.1 christos } 1487 1.1 christos if (val & TCR_TCRSL) { 1488 1.1 christos } 1489 1.1 christos rtc_se = ((val & TCR_TCRSE) != 0); 1490 1.1 christos if (rtc_se && (rtc_enabled == 0)) 1491 1.1 christos rtc_start(); 1492 1.1 christos 1493 1.1 christos gpt_cr = (val & TCR_GACR); 1494 1.1 christos if (val & TCR_GACL) { 1495 1.1 christos gpt_counter = gpt_reload; 1496 1.1 christos } 1497 1.1 christos if (val & TCR_GACL) { 1498 1.1 christos } 1499 1.1 christos gpt_se = (val & TCR_GASE) >> 2; 1500 1.1 christos if (gpt_se && (gpt_enabled == 0)) 1501 1.1 christos gpt_start(); 1502 1.1 christos } 1503 1.1 christos 1504 1.5 christos /* Store data in host byte order. MEM points to the beginning of the 1505 1.5 christos emulated memory; WADDR contains the index the emulated memory, 1506 1.5 christos DATA points to words in host byte order to be stored. SZ contains log(2) 1507 1.5 christos of the number of bytes to retrieve, and can be 0 (1 byte), 1 (one half-word), 1508 1.5 christos 2 (one word), or 3 (two words); WS should return the number of 1509 1.5 christos wait-states. */ 1510 1.1 christos 1511 1.5 christos static void 1512 1.10 christos store_bytes (unsigned char *mem, uint32_t waddr, uint32_t *data, int32_t sz, 1513 1.10 christos int32_t *ws) 1514 1.5 christos { 1515 1.5 christos switch (sz) { 1516 1.5 christos case 0: 1517 1.5 christos waddr ^= EBT; 1518 1.5 christos mem[waddr] = *data & 0x0ff; 1519 1.5 christos *ws = mem_ramw_ws + 3; 1520 1.1 christos break; 1521 1.1 christos case 1: 1522 1.5 christos #ifdef HOST_LITTLE_ENDIAN 1523 1.5 christos waddr ^= 2; 1524 1.5 christos #endif 1525 1.5 christos memcpy (&mem[waddr], data, 2); 1526 1.5 christos *ws = mem_ramw_ws + 3; 1527 1.1 christos break; 1528 1.5 christos case 2: 1529 1.5 christos memcpy (&mem[waddr], data, 4); 1530 1.5 christos *ws = mem_ramw_ws; 1531 1.1 christos break; 1532 1.1 christos case 3: 1533 1.5 christos memcpy (&mem[waddr], data, 8); 1534 1.5 christos *ws = 2 * mem_ramw_ws + STD_WS; 1535 1.1 christos break; 1536 1.1 christos } 1537 1.1 christos } 1538 1.1 christos 1539 1.1 christos 1540 1.5 christos /* Memory emulation */ 1541 1.1 christos 1542 1.5 christos int 1543 1.10 christos memory_iread (uint32_t addr, uint32_t *data, uint32_t *ws) 1544 1.1 christos { 1545 1.10 christos uint32_t asi; 1546 1.5 christos if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) { 1547 1.5 christos memcpy (data, &ramb[addr & mem_rammask & ~3], 4); 1548 1.5 christos *ws = mem_ramr_ws; 1549 1.5 christos return 0; 1550 1.5 christos } else if (addr < mem_romsz) { 1551 1.5 christos memcpy (data, &romb[addr & ~3], 4); 1552 1.5 christos *ws = mem_romr_ws; 1553 1.5 christos return 0; 1554 1.1 christos } 1555 1.5 christos 1556 1.5 christos if (sis_verbose) 1557 1.5 christos printf ("Memory exception at %x (illegal address)\n", addr); 1558 1.5 christos if (sregs.psr & 0x080) 1559 1.5 christos asi = 9; 1560 1.5 christos else 1561 1.5 christos asi = 8; 1562 1.5 christos set_sfsr (UIMP_ACC, addr, asi, 1); 1563 1.5 christos *ws = MEM_EX_WS; 1564 1.5 christos return 1; 1565 1.1 christos } 1566 1.1 christos 1567 1.1 christos int 1568 1.10 christos memory_read(int32_t asi, uint32_t addr, void *data, int32_t sz, int32_t *ws) 1569 1.1 christos { 1570 1.10 christos int32_t mexc; 1571 1.1 christos 1572 1.1 christos #ifdef ERRINJ 1573 1.1 christos if (errmec) { 1574 1.1 christos if (sis_verbose) 1575 1.1 christos printf("Inserted MEC error %d\n",errmec); 1576 1.1 christos set_sfsr(errmec, addr, asi, 1); 1577 1.1 christos if (errmec == 5) mecparerror(); 1578 1.1 christos if (errmec == 6) iucomperr(); 1579 1.1 christos errmec = 0; 1580 1.5 christos return 1; 1581 1.1 christos } 1582 1.1 christos #endif 1583 1.1 christos 1584 1.1 christos if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) { 1585 1.5 christos memcpy (data, &ramb[addr & mem_rammask & ~3], 4); 1586 1.1 christos *ws = mem_ramr_ws; 1587 1.5 christos return 0; 1588 1.1 christos } else if ((addr >= MEC_START) && (addr < MEC_END)) { 1589 1.1 christos mexc = mec_read(addr, asi, data); 1590 1.1 christos if (mexc) { 1591 1.1 christos set_sfsr(MEC_ACC, addr, asi, 1); 1592 1.1 christos *ws = MEM_EX_WS; 1593 1.1 christos } else { 1594 1.1 christos *ws = 0; 1595 1.1 christos } 1596 1.5 christos return mexc; 1597 1.1 christos 1598 1.1 christos #ifdef ERA 1599 1.1 christos 1600 1.1 christos } else if (era) { 1601 1.1 christos if ((addr < 0x100000) || 1602 1.1 christos ((addr>= 0x80000000) && (addr < 0x80100000))) { 1603 1.5 christos memcpy (data, &romb[addr & ROM_MASK & ~3], 4); 1604 1.1 christos *ws = 4; 1605 1.5 christos return 0; 1606 1.1 christos } else if ((addr >= 0x10000000) && 1607 1.1 christos (addr < (0x10000000 + (512 << (mec_iocr & 0x0f)))) && 1608 1.1 christos (mec_iocr & 0x10)) { 1609 1.10 christos memcpy (data, &erareg, 4); 1610 1.5 christos return 0; 1611 1.1 christos } 1612 1.1 christos 1613 1.1 christos } else if (addr < mem_romsz) { 1614 1.5 christos memcpy (data, &romb[addr & ~3], 4); 1615 1.5 christos *ws = mem_romr_ws; 1616 1.5 christos return 0; 1617 1.1 christos #else 1618 1.1 christos } else if (addr < mem_romsz) { 1619 1.5 christos memcpy (data, &romb[addr & ~3], 4); 1620 1.1 christos *ws = mem_romr_ws; 1621 1.5 christos return 0; 1622 1.1 christos #endif 1623 1.1 christos 1624 1.1 christos } 1625 1.1 christos 1626 1.5 christos if (sis_verbose) 1627 1.5 christos printf ("Memory exception at %x (illegal address)\n", addr); 1628 1.1 christos set_sfsr(UIMP_ACC, addr, asi, 1); 1629 1.1 christos *ws = MEM_EX_WS; 1630 1.5 christos return 1; 1631 1.1 christos } 1632 1.1 christos 1633 1.1 christos int 1634 1.10 christos memory_write(int32_t asi, uint32_t addr, uint32_t *data, int32_t sz, int32_t *ws) 1635 1.10 christos { 1636 1.10 christos uint32_t waddr; 1637 1.10 christos int32_t mexc; 1638 1.1 christos int i; 1639 1.1 christos int wphit[2]; 1640 1.1 christos 1641 1.1 christos #ifdef ERRINJ 1642 1.1 christos if (errmec) { 1643 1.1 christos if (sis_verbose) 1644 1.1 christos printf("Inserted MEC error %d\n",errmec); 1645 1.1 christos set_sfsr(errmec, addr, asi, 0); 1646 1.1 christos if (errmec == 5) mecparerror(); 1647 1.1 christos if (errmec == 6) iucomperr(); 1648 1.1 christos errmec = 0; 1649 1.5 christos return 1; 1650 1.1 christos } 1651 1.1 christos #endif 1652 1.1 christos 1653 1.1 christos if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) { 1654 1.1 christos if (mem_accprot) { 1655 1.1 christos 1656 1.1 christos waddr = (addr & 0x7fffff) >> 2; 1657 1.1 christos for (i = 0; i < 2; i++) 1658 1.1 christos wphit[i] = 1659 1.1 christos (((asi == 0xa) && (mec_wpr[i] & 1)) || 1660 1.1 christos ((asi == 0xb) && (mec_wpr[i] & 2))) && 1661 1.1 christos ((waddr >= mec_ssa[i]) && ((waddr | (sz == 3)) < mec_sea[i])); 1662 1.1 christos 1663 1.1 christos if (((mem_blockprot) && (wphit[0] || wphit[1])) || 1664 1.1 christos ((!mem_blockprot) && 1665 1.1 christos !((mec_wpr[0] && wphit[0]) || (mec_wpr[1] && wphit[1])) 1666 1.1 christos )) { 1667 1.1 christos if (sis_verbose) 1668 1.1 christos printf("Memory access protection error at 0x%08x\n", addr); 1669 1.1 christos set_sfsr(PROT_EXC, addr, asi, 0); 1670 1.1 christos *ws = MEM_EX_WS; 1671 1.5 christos return 1; 1672 1.1 christos } 1673 1.1 christos } 1674 1.5 christos waddr = addr & mem_rammask; 1675 1.5 christos store_bytes (ramb, waddr, data, sz, ws); 1676 1.5 christos return 0; 1677 1.1 christos } else if ((addr >= MEC_START) && (addr < MEC_END)) { 1678 1.1 christos if ((sz != 2) || (asi != 0xb)) { 1679 1.1 christos set_sfsr(MEC_ACC, addr, asi, 0); 1680 1.1 christos *ws = MEM_EX_WS; 1681 1.5 christos return 1; 1682 1.1 christos } 1683 1.1 christos mexc = mec_write(addr, *data); 1684 1.1 christos if (mexc) { 1685 1.1 christos set_sfsr(MEC_ACC, addr, asi, 0); 1686 1.1 christos *ws = MEM_EX_WS; 1687 1.1 christos } else { 1688 1.1 christos *ws = 0; 1689 1.1 christos } 1690 1.5 christos return mexc; 1691 1.1 christos 1692 1.1 christos #ifdef ERA 1693 1.1 christos 1694 1.1 christos } else if (era) { 1695 1.1 christos if ((erareg & 2) && 1696 1.1 christos ((addr < 0x100000) || ((addr >= 0x80000000) && (addr < 0x80100000)))) { 1697 1.1 christos addr &= ROM_MASK; 1698 1.1 christos *ws = sz == 3 ? 8 : 4; 1699 1.5 christos store_bytes (romb, addr, data, sz, ws); 1700 1.5 christos return 0; 1701 1.1 christos } else if ((addr >= 0x10000000) && 1702 1.1 christos (addr < (0x10000000 + (512 << (mec_iocr & 0x0f)))) && 1703 1.1 christos (mec_iocr & 0x10)) { 1704 1.1 christos erareg = *data & 0x0e; 1705 1.5 christos return 0; 1706 1.1 christos } 1707 1.1 christos 1708 1.1 christos } else if ((addr < mem_romsz) && (mec_memcfg & 0x10000) && (wrp) && 1709 1.1 christos (((mec_memcfg & 0x20000) && (sz > 1)) || 1710 1.1 christos (!(mec_memcfg & 0x20000) && (sz == 0)))) { 1711 1.1 christos 1712 1.1 christos *ws = mem_romw_ws + 1; 1713 1.1 christos if (sz == 3) 1714 1.1 christos *ws += mem_romw_ws + STD_WS; 1715 1.5 christos store_bytes (romb, addr, data, sz, ws); 1716 1.5 christos return 0; 1717 1.1 christos 1718 1.1 christos #else 1719 1.1 christos } else if ((addr < mem_romsz) && (mec_memcfg & 0x10000) && (wrp) && 1720 1.1 christos (((mec_memcfg & 0x20000) && (sz > 1)) || 1721 1.1 christos (!(mec_memcfg & 0x20000) && (sz == 0)))) { 1722 1.1 christos 1723 1.1 christos *ws = mem_romw_ws + 1; 1724 1.1 christos if (sz == 3) 1725 1.1 christos *ws += mem_romw_ws + STD_WS; 1726 1.5 christos store_bytes (romb, addr, data, sz, ws); 1727 1.5 christos return 0; 1728 1.1 christos 1729 1.1 christos #endif 1730 1.1 christos 1731 1.1 christos } 1732 1.1 christos 1733 1.1 christos *ws = MEM_EX_WS; 1734 1.1 christos set_sfsr(UIMP_ACC, addr, asi, 0); 1735 1.5 christos return 1; 1736 1.1 christos } 1737 1.1 christos 1738 1.10 christos static void * 1739 1.10 christos get_mem_ptr(uint32_t addr, uint32_t size) 1740 1.1 christos { 1741 1.1 christos if ((addr + size) < ROM_SZ) { 1742 1.5 christos return &romb[addr]; 1743 1.1 christos } else if ((addr >= mem_ramstart) && ((addr + size) < mem_ramend)) { 1744 1.5 christos return &ramb[addr & mem_rammask]; 1745 1.1 christos } 1746 1.1 christos 1747 1.1 christos #ifdef ERA 1748 1.1 christos else if ((era) && ((addr <0x100000) || 1749 1.1 christos ((addr >= (unsigned) 0x80000000) && ((addr + size) < (unsigned) 0x80100000)))) { 1750 1.5 christos return &romb[addr & ROM_MASK]; 1751 1.1 christos } 1752 1.1 christos #endif 1753 1.1 christos 1754 1.10 christos return (void *) -1; 1755 1.1 christos } 1756 1.1 christos 1757 1.1 christos int 1758 1.10 christos sis_memory_write(uint32_t addr, const void *data, uint32_t length) 1759 1.1 christos { 1760 1.10 christos void *mem; 1761 1.1 christos 1762 1.10 christos if ((mem = get_mem_ptr(addr, length)) == ((void *) -1)) 1763 1.5 christos return 0; 1764 1.1 christos 1765 1.1 christos memcpy(mem, data, length); 1766 1.5 christos return length; 1767 1.1 christos } 1768 1.1 christos 1769 1.1 christos int 1770 1.10 christos sis_memory_read(uint32_t addr, void *data, uint32_t length) 1771 1.1 christos { 1772 1.1 christos char *mem; 1773 1.1 christos 1774 1.10 christos if ((mem = get_mem_ptr(addr, length)) == ((void *) -1)) 1775 1.5 christos return 0; 1776 1.1 christos 1777 1.1 christos memcpy(data, mem, length); 1778 1.5 christos return length; 1779 1.5 christos } 1780 1.5 christos 1781 1.5 christos extern struct pstate sregs; 1782 1.5 christos 1783 1.5 christos void 1784 1.5 christos boot_init (void) 1785 1.5 christos { 1786 1.5 christos mec_write(MEC_WCR, 0); /* zero waitstates */ 1787 1.5 christos mec_write(MEC_TRAPD, 0); /* turn off watch-dog */ 1788 1.5 christos mec_write(MEC_RTC_SCALER, sregs.freq - 1); /* generate 1 MHz RTC tick */ 1789 1.5 christos mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */ 1790 1.5 christos sregs.wim = 2; 1791 1.5 christos sregs.psr = 0x110010e0; 1792 1.5 christos sregs.r[30] = RAM_END; 1793 1.5 christos sregs.r[14] = sregs.r[30] - 96 * 4; 1794 1.5 christos mec_mcr |= 1; /* power-down enabled */ 1795 1.1 christos } 1796