📄 erc32.c
字号:
/* * This file is part of SIS. * * SIS, SPARC instruction simulator V2.5 Copyright (C) 1995 Jiri Gaisler, * European Space Agency * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 675 * Mass Ave, Cambridge, MA 02139, USA. * *//* The control space devices */#include <sys/types.h>#include <stdio.h>#include <termios.h>#include <sys/fcntl.h>#include <sys/file.h>#include <unistd.h>#include "sis.h"#include "end.h"#include "sim-config.h"extern int ctrl_c;extern int32 sis_verbose;extern int32 sparclite, sparclite_board;extern int rom8,wrp,uben;extern char uart_dev1[], uart_dev2[];int dumbio = 0; /* normal, smart, terminal oriented IO by default *//* MEC registers */#define MEC_START 0x01f80000#define MEC_END 0x01f80100/* Memory exception waitstates */#define MEM_EX_WS 1/* ERC32 always adds one waitstate during RAM std */#define STD_WS 1#ifdef ERRINJextern int errmec;#endif/* The target's byte order is big-endian by default until we load a little-endian program. */int current_target_byte_order = BIG_ENDIAN;#define MEC_WS 0 /* Waitstates per MEC access (0 ws) */#define MOK 0/* MEC register addresses */#define MEC_MCR 0x000#define MEC_SFR 0x004#define MEC_PWDR 0x008#define MEC_MEMCFG 0x010#define MEC_IOCR 0x014#define MEC_WCR 0x018#define MEC_MAR0 0x020#define MEC_MAR1 0x024#define MEC_SSA1 0x020#define MEC_SEA1 0x024#define MEC_SSA2 0x028#define MEC_SEA2 0x02C#define MEC_ISR 0x044#define MEC_IPR 0x048#define MEC_IMR 0x04C#define MEC_ICR 0x050#define MEC_IFR 0x054#define MEC_WDOG 0x060#define MEC_TRAPD 0x064#define MEC_RTC_COUNTER 0x080#define MEC_RTC_RELOAD 0x080#define MEC_RTC_SCALER 0x084#define MEC_GPT_COUNTER 0x088#define MEC_GPT_RELOAD 0x088#define MEC_GPT_SCALER 0x08C#define MEC_TIMER_CTRL 0x098#define MEC_SFSR 0x0A0#define MEC_FFAR 0x0A4#define MEC_ERSR 0x0B0#define MEC_DBG 0x0C0#define MEC_TCR 0x0D0#define MEC_BRK 0x0C4#define MEC_WPR 0x0C8#define MEC_UARTA 0x0E0#define MEC_UARTB 0x0E4#define MEC_UART_CTRL 0x0E8#define SIM_LOAD 0x0F0/* Memory exception causes */#define PROT_EXC 0x3#define UIMP_ACC 0x4#define MEC_ACC 0x6#define WATCH_EXC 0xa#define BREAK_EXC 0xb/* Size of UART buffers (bytes) */#define UARTBUF 1024/* Number of simulator ticks between flushing the UARTS. *//* For good performance, keep above 1000 */#define UART_FLUSH_TIME 3000/* MEC timer control register bits */#define TCR_GACR 1#define TCR_GACL 2#define TCR_GASE 4#define TCR_GASL 8#define TCR_TCRCR 0x100#define TCR_TCRCL 0x200#define TCR_TCRSE 0x400#define TCR_TCRSL 0x800/* New uart defines */#define UART_TX_TIME 1000#define UART_RX_TIME 1000#define UARTA_DR 0x1#define UARTA_SRE 0x2#define UARTA_HRE 0x4#define UARTA_OR 0x40#define UARTA_CLR 0x80#define UARTB_DR 0x10000#define UARTB_SRE 0x20000#define UARTB_HRE 0x40000#define UARTB_OR 0x400000#define UARTB_CLR 0x800000#define UART_DR 0x100#define UART_TSE 0x200#define UART_THE 0x400/* MEC registers */static char fname[256];static int32 find = 0;static uint32 mec_ssa[2]; /* Write protection start address */static uint32 mec_sea[2]; /* Write protection end address */static uint32 mec_wpr[2]; /* Write protection control fields */static uint32 mec_sfsr;static uint32 mec_ffar;static uint32 mec_ipr;static uint32 mec_imr;static uint32 mec_isr;static uint32 mec_icr;static uint32 mec_ifr;static uint32 mec_mcr; /* MEC control register */static uint32 mec_memcfg; /* Memory control register */static uint32 mec_wcr; /* MEC waitstate register */static uint32 mec_iocr; /* MEC IO control register */static uint32 posted_irq;static uint32 mec_ersr; /* MEC error and status register */static uint32 mec_tcr; /* MEC test comtrol register */static uint32 rtc_counter;static uint32 rtc_reload;static uint32 rtc_scaler;static uint32 rtc_scaler_start;static uint32 rtc_enabled;static uint32 rtc_cr;static uint32 rtc_se;static uint32 gpt_counter;static uint32 gpt_reload;static uint32 gpt_scaler;static uint32 gpt_scaler_start;static uint32 gpt_enabled;static uint32 gpt_cr;static uint32 gpt_se;static uint32 wdog_scaler;static uint32 wdog_counter;static uint32 wdog_rst_delay;static uint32 wdog_rston;enum wdog_type { init, disabled, enabled, stopped};static enum wdog_type wdog_status;/* ROM size 1024 Kbyte */#define ROM_SZ 0x100000#define ROM_MASK 0x0fffff/* RAM size 4 Mbyte */#define RAM_START 0x02000000#define RAM_END 0x02400000#define RAM_MASK 0x003fffff/* SPARClite boards all seem to have RAM at the same place. */#define RAM_START_SLITE 0x40000000#define RAM_END_SLITE 0x40400000#define RAM_MASK_SLITE 0x003fffff/* Memory support variables */static uint32 mem_ramr_ws; /* RAM read waitstates */static uint32 mem_ramw_ws; /* RAM write waitstates */static uint32 mem_romr_ws; /* ROM read waitstates */static uint32 mem_romw_ws; /* ROM write waitstates */static uint32 mem_ramstart; /* RAM start */static uint32 mem_ramend; /* RAM end */static uint32 mem_rammask; /* RAM address mask */static uint32 mem_ramsz; /* RAM size */static uint32 mem_romsz; /* ROM size */static uint32 mem_accprot; /* RAM write protection enabled */static uint32 mem_blockprot; /* RAM block write protection enabled */static unsigned char romb[ROM_SZ];static unsigned char ramb[RAM_END - RAM_START];/* UART support variables */static int32 fd1, fd2; /* file descriptor for input file */static int32 Ucontrol; /* UART status register */static unsigned char aq[UARTBUF], bq[UARTBUF];static int32 anum, aind = 0;static int32 bnum, bind = 0;static char wbufa[UARTBUF], wbufb[UARTBUF];static unsigned wnuma;static unsigned wnumb;static FILE *f1in, *f1out, *f2in, *f2out;static struct termios ioc1, ioc2, iocold1, iocold2;static int f1open = 0, f2open = 0;static char uarta_sreg, uarta_hreg, uartb_sreg, uartb_hreg;static uint32 uart_stat_reg;static uint32 uarta_data, uartb_data;#ifdef ERAint era = 0;int erareg;#endif/* Forward declarations */static void decode_ersr PARAMS ((void));#ifdef ERRINJstatic void iucomperr PARAMS ((void));#endifstatic void mecparerror PARAMS ((void));static void decode_memcfg PARAMS ((void));static void decode_wcr PARAMS ((void));static void decode_mcr PARAMS ((void));static void close_port PARAMS ((void));static void mec_reset PARAMS ((void));static void mec_intack PARAMS ((int32 level));static void chk_irq PARAMS ((void));static void mec_irq PARAMS ((int32 level));static void set_sfsr PARAMS ((uint32 fault, uint32 addr, uint32 asi, uint32 read));static int32 mec_read PARAMS ((uint32 addr, uint32 asi, uint32 *data));static int mec_write PARAMS ((uint32 addr, uint32 data));static void port_init PARAMS ((void));static uint32 read_uart PARAMS ((uint32 addr));static void write_uart PARAMS ((uint32 addr, uint32 data));static void flush_uart PARAMS ((void));static void uarta_tx PARAMS ((void));static void uartb_tx PARAMS ((void));static void uart_rx PARAMS ((caddr_t arg));static void uart_intr PARAMS ((caddr_t arg));static void uart_irq_start PARAMS ((void));static void wdog_intr PARAMS ((caddr_t arg));static void wdog_start PARAMS ((void));static void rtc_intr PARAMS ((caddr_t arg));static void rtc_start PARAMS ((void));static uint32 rtc_counter_read PARAMS ((void));static void rtc_scaler_set PARAMS ((uint32 val));static void rtc_reload_set PARAMS ((uint32 val));static void gpt_intr PARAMS ((caddr_t arg));static void gpt_start PARAMS ((void));static uint32 gpt_counter_read PARAMS ((void));static void gpt_scaler_set PARAMS ((uint32 val));static void gpt_reload_set PARAMS ((uint32 val));static void timer_ctrl PARAMS ((uint32 val));static unsigned char * get_mem_ptr PARAMS ((uint32 addr, uint32 size));static void fetch_bytes PARAMS ((int asi, unsigned char *mem, uint32 *data, int sz));static void store_bytes PARAMS ((unsigned char *mem, uint32 *data, int sz));extern int ext_irl;/* One-time init */voidinit_sim(){ port_init();}/* Power-on reset init */voidreset(){ mec_reset(); uart_irq_start(); wdog_start();}static voiddecode_ersr(){ if (mec_ersr & 0x01) { if (!(mec_mcr & 0x20)) { if (mec_mcr & 0x40) { sys_reset(); mec_ersr = 0x8000; if (sis_verbose) printf("Error manager reset - IU in error mode\n"); } else { sys_halt(); mec_ersr |= 0x2000; if (sis_verbose) printf("Error manager halt - IU in error mode\n"); } } else mec_irq(1); } if (mec_ersr & 0x04) { if (!(mec_mcr & 0x200)) { if (mec_mcr & 0x400) { sys_reset(); mec_ersr = 0x8000; if (sis_verbose) printf("Error manager reset - IU comparison error\n"); } else { sys_halt(); mec_ersr |= 0x2000; if (sis_verbose) printf("Error manager halt - IU comparison error\n"); } } else mec_irq(1); } if (mec_ersr & 0x20) { if (!(mec_mcr & 0x2000)) { if (mec_mcr & 0x4000) { sys_reset(); mec_ersr = 0x8000; if (sis_verbose) printf("Error manager reset - MEC hardware error\n"); } else { sys_halt(); mec_ersr |= 0x2000; if (sis_verbose) printf("Error manager halt - MEC hardware error\n"); } } else mec_irq(1); }}#ifdef ERRINJstatic voidiucomperr(){ mec_ersr |= 0x04; decode_ersr();}#endifstatic voidmecparerror(){ mec_ersr |= 0x20; decode_ersr();}/* IU error mode manager */voiderror_mode(pc) uint32 pc;{ mec_ersr |= 0x1; decode_ersr();}/* Check memory settings */static voiddecode_memcfg(){ if (rom8) mec_memcfg &= ~0x20000; else mec_memcfg |= 0x20000; mem_ramsz = (256 * 1024) << ((mec_memcfg >> 10) & 7); mem_romsz = (128 * 1024) << ((mec_memcfg >> 18) & 7); if (sparclite_board) { mem_ramstart = RAM_START_SLITE; mem_ramend = RAM_END_SLITE; mem_rammask = RAM_MASK_SLITE; } else { mem_ramstart = RAM_START; mem_ramend = RAM_END; mem_rammask = RAM_MASK; } if (sis_verbose) printf("RAM start: 0x%x, RAM size: %d K, ROM size: %d K\n", mem_ramstart, mem_ramsz >> 10, mem_romsz >> 10);}static voiddecode_wcr(){ mem_ramr_ws = mec_wcr & 3; mem_ramw_ws = (mec_wcr >> 2) & 3; mem_romr_ws = (mec_wcr >> 4) & 0x0f; if (rom8) { if (mem_romr_ws > 0 ) mem_romr_ws--; mem_romr_ws = 5 + (4*mem_romr_ws); } mem_romw_ws = (mec_wcr >> 8) & 0x0f; if (sis_verbose) printf("Waitstates = RAM read: %d, RAM write: %d, ROM read: %d, ROM write: %d\n", mem_ramr_ws, mem_ramw_ws, mem_romr_ws, mem_romw_ws);}static voiddecode_mcr(){ mem_accprot = (mec_wpr[0] | mec_wpr[1]); mem_blockprot = (mec_mcr >> 3) & 1; if (sis_verbose && mem_accprot) printf("Memory block write protection enabled\n"); if (mec_mcr & 0x08000) { mec_ersr |= 0x20; decode_ersr(); } if (sis_verbose && (mec_mcr & 2)) printf("Software reset enabled\n"); if (sis_verbose && (mec_mcr & 1)) printf("Power-down mode enabled\n");}/* Flush ports when simulator stops */voidsim_halt(){#ifdef FAST_UART flush_uart();#endif}intsim_stop(SIM_DESC sd){ ctrl_c = 1; return 1;}static voidclose_port(){ if (f1open && f1in != stdin) fclose(f1in); if (f2open && f2in != stdin) fclose(f2in);}voidexit_sim(){ close_port();}static voidmec_reset(){ int i; find = 0; for (i = 0; i < 2; i++) mec_ssa[i] = mec_sea[i] = mec_wpr[i] = 0; mec_mcr = 0x01350014; mec_iocr = 0; mec_sfsr = 0x078; mec_ffar = 0; mec_ipr = 0; mec_imr = 0x7ffe; mec_isr = 0; mec_icr = 0; mec_ifr = 0; mec_memcfg = 0x10000; mec_wcr = -1; mec_ersr = 0; /* MEC error and status register */ mec_tcr = 0; /* MEC test comtrol register */ decode_memcfg(); decode_wcr(); decode_mcr(); posted_irq = 0; wnuma = wnumb = 0; anum = aind = bnum = bind = 0; uart_stat_reg = UARTA_SRE | UARTA_HRE | UARTB_SRE | UARTB_HRE; uarta_data = uartb_data = UART_THE | UART_TSE; rtc_counter = 0xffffffff; rtc_reload = 0xffffffff; rtc_scaler = 0xff; rtc_enabled = 0; rtc_cr = 0; rtc_se = 0; gpt_counter = 0xffffffff; gpt_reload = 0xffffffff; gpt_scaler = 0xffff; gpt_enabled = 0; gpt_cr = 0; gpt_se = 0; wdog_scaler = 255; wdog_rst_delay = 255; wdog_counter = 0xffff; wdog_rston = 0; wdog_status = init;#ifdef ERA erareg = 0;#endif}static voidmec_intack(level) int32 level;{ int irq_test; if (sis_verbose) printf("interrupt %d acknowledged\n", level); irq_test = mec_tcr & 0x80000; if ((irq_test) && (mec_ifr & (1 << level))) mec_ifr &= ~(1 << level); else mec_ipr &= ~(1 << level); chk_irq();}static voidchk_irq(){ int32 i; uint32 itmp; int old_irl; old_irl = ext_irl; if (mec_tcr & 0x80000) itmp = mec_ifr; else itmp = 0; itmp = ((mec_ipr | itmp) & ~mec_imr) & 0x0fffe; ext_irl = 0; if (itmp != 0) { for (i = 15; i > 0; i--) { if (((itmp >> i) & 1) != 0) { if ((sis_verbose) && (i > old_irl)) printf("IU irl: %d\n", i); ext_irl = i; set_int(i, mec_intack, i); break; } } }}static voidmec_irq(level) int32 level;{ mec_ipr |= (1 << level); chk_irq();}static voidset_sfsr(fault, addr, asi, read) uint32 fault; uint32 addr; uint32 asi; uint32 read;{ if ((asi == 0xa) || (asi == 0xb)) { mec_ffar = addr; mec_sfsr = (fault << 3) | (!read << 15); mec_sfsr |= ((mec_sfsr & 1) ^ 1) | (mec_sfsr & 1); switch (asi) { case 0xa: mec_sfsr |= 0x0004; break; case 0xb: mec_sfsr |= 0x1004; break; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -