⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mem.c

📁 Spim软件的一些源码。其中有Xspim的
💻 C
📖 第 1 页 / 共 2 页
字号:
  else if ((addr >= stack_bot) && (addr < STACK_TOP))    stack_seg_b [addr - stack_bot] = (BYTE_TYPE) value;  else if ((addr >= K_DATA_BOT) && (addr < k_data_top))    k_data_seg_b [addr - K_DATA_BOT] = (BYTE_TYPE) value;  else    bad_mem_write (addr, value, 0);}voidset_mem_half(mem_addr addr, reg_word value){  data_modified = 1;  if ((addr >= DATA_BOT) && (addr < data_top) && !(addr & 0x1))    data_seg_h [(addr - DATA_BOT) >> 1] = (short) value;  else if ((addr >= stack_bot) && (addr < STACK_TOP) && !(addr & 0x1))    stack_seg_h [(addr - stack_bot) >> 1] = (short) value;  else if ((addr >= K_DATA_BOT) && (addr < k_data_top) && !(addr & 0x1))    k_data_seg_h [(addr - K_DATA_BOT) >> 1] = (short) value;  else    bad_mem_write (addr, value, 0x1);}voidset_mem_word(mem_addr addr, reg_word value){  data_modified = 1;  if ((addr >= DATA_BOT) && (addr < data_top) && !(addr & 0x3))    data_seg [(addr - DATA_BOT) >> 2] = (mem_word) value;  else if ((addr >= stack_bot) && (addr < STACK_TOP) && !(addr & 0x3))    stack_seg [(addr - stack_bot) >> 2] = (mem_word) value;  else if ((addr >= K_DATA_BOT) && (addr < k_data_top) && !(addr & 0x3))    k_data_seg [(addr - K_DATA_BOT) >> 2] = (mem_word) value;  else    bad_mem_write (addr, value, 0x3);}/* Handle the infrequent and erroneous cases in memory accesses. */static instruction *bad_text_read (mem_addr addr){  RAISE_EXCEPTION (ExcCode_IBE, CP0_BadVAddr = addr);  return (inst_decode (0));}static voidbad_text_write (mem_addr addr, instruction *inst){  RAISE_EXCEPTION (ExcCode_IBE, CP0_BadVAddr = addr);  set_mem_word (addr, ENCODING (inst));}static mem_wordbad_mem_read (mem_addr addr, int mask){  mem_word tmp;  if ((addr & mask) != 0)    RAISE_EXCEPTION (ExcCode_AdEL, CP0_BadVAddr = addr)  else if (addr >= TEXT_BOT && addr < text_top)    switch (mask)      {      case 0x0:	tmp = ENCODING (text_seg [(addr - TEXT_BOT) >> 2]);#ifdef BIGENDIAN	tmp = (unsigned)tmp >> (8 * (3 - (addr & 0x3)));#else	tmp = (unsigned)tmp >> (8 * (addr & 0x3));#endif	return (0xff & tmp);      case 0x1:	tmp = ENCODING (text_seg [(addr - TEXT_BOT) >> 2]);#ifdef BIGENDIAN	tmp = (unsigned)tmp >> (8 * (2 - (addr & 0x2)));#else	tmp = (unsigned)tmp >> (8 * (addr & 0x2));#endif	return (0xffff & tmp);      case 0x3:	{	instruction *inst = text_seg [(addr - TEXT_BOT) >> 2];	if (inst == NULL)	  return 0;	else	  return (ENCODING (inst));	}      default:	run_error ("Bad mask (0x%x) in bad_mem_read\n", mask);      }  else if (addr > data_top	   && addr < stack_bot	   /* If more than 16 MB below stack, probably is bad data ref */	   && addr > stack_bot - 16*K*K)    {      /* Grow stack segment */      expand_stack (stack_bot - addr + 4);      return (0);    }  else if (MM_IO_BOT <= addr && addr <= MM_IO_TOP)    return (read_memory_mapped_IO (addr));  else    /* Address out of range */    RAISE_EXCEPTION (ExcCode_DBE, CP0_BadVAddr = addr)  return (0);}static voidbad_mem_write (mem_addr addr, mem_word value, int mask){  mem_word tmp;  if ((addr & mask) != 0)    /* Unaligned address fault */    RAISE_EXCEPTION (ExcCode_AdES, CP0_BadVAddr = addr)    else if (addr >= TEXT_BOT && addr < text_top)  {    switch (mask)    {    case 0x0:      tmp = ENCODING (text_seg [(addr - TEXT_BOT) >> 2]);#ifdef BIGENDIAN      tmp = ((tmp & ~(0xff << (8 * (3 - (addr & 0x3)))))	       | (value & 0xff) << (8 * (3 - (addr & 0x3))));#else      tmp = ((tmp & ~(0xff << (8 * (addr & 0x3))))	       | (value & 0xff) << (8 * (addr & 0x3)));#endif      text_seg [(addr - TEXT_BOT) >> 2] = inst_decode (tmp);      break;    case 0x1:      tmp = ENCODING (text_seg [(addr - TEXT_BOT) >> 2]);#ifdef BIGENDIAN      tmp = ((tmp & ~(0xffff << (8 * (2 - (addr & 0x2)))))	       | (value & 0xffff) << (8 * (2 - (addr & 0x2))));#else      tmp = ((tmp & ~(0xffff << (8 * (addr & 0x2))))	       | (value & 0xffff) << (8 * (addr & 0x2)));#endif      text_seg [(addr - TEXT_BOT) >> 2] = inst_decode (tmp);      break;    case 0x3:      text_seg [(addr - TEXT_BOT) >> 2] = inst_decode (value);      break;    default:      run_error ("Bad mask (0x%x) in bad_mem_read\n", mask);    }    text_modified = 1;  }  else if (addr > data_top	   && addr < stack_bot	   /* If more than 16 MB below stack, probably is bad data ref */	   && addr > stack_bot - 16*K*K)  {    /* Grow stack segment */    expand_stack (stack_bot - addr + 4);    if (addr >= stack_bot)    {      if (mask == 0)	stack_seg_b [addr - stack_bot] = (char)value;      else if (mask == 1)	stack_seg_h [(addr - stack_bot) >> 1] = (short)value;      else	stack_seg [(addr - stack_bot) >> 2] = value;    }    else      RAISE_EXCEPTION (ExcCode_DBE, CP0_BadVAddr = addr)    data_modified = 1;  }  else if (MM_IO_BOT <= addr && addr <= MM_IO_TOP)    write_memory_mapped_IO (addr, value);  else    /* Address out of range */    RAISE_EXCEPTION (ExcCode_DBE, CP0_BadVAddr = addr)}/* Memory-mapped IO routines. */static int recv_control = 0;	/* No input */static int recv_buffer;static int recv_buffer_full_timer = 0;static int trans_control = TRANS_READY;	/* Ready to write */static int trans_buffer;static int trans_buffer_full_timer = 0;/* Check if input is available and output is possible.  If so, update the   memory-mapped control registers and buffers. */voidcheck_memory_mapped_IO (){  if (recv_buffer_full_timer > 0)    {      /* Do not check for more input until this interval expires. */      recv_buffer_full_timer -= 1;    }  else if (console_input_available ())    {      /* Read new char into the buffer and raise an interrupt, if interrupts	 are enabled for device. */      /* assert(recv_buffer_full_timer == 0); */      recv_buffer = get_console_char ();      recv_control |= RECV_READY;      recv_buffer_full_timer = RECV_INTERVAL;      if (recv_control & RECV_INT_ENABLE)	{	  RAISE_INTERRUPT (RECV_INT_LEVEL);	}    }  if (trans_buffer_full_timer > 0)    {      /* Do not allow output until this interval expires. */      trans_buffer_full_timer -= 1;    }  else if (!(trans_control & TRANS_READY))    {      /* Done writing: empty the buffer and raise an interrupt, if interrupts	 are enabled for device. */      /* assert(trans_buffer_full_timer == 0); */      trans_control |= TRANS_READY;      if (trans_control & TRANS_INT_ENABLE)	{	  RAISE_INTERRUPT (TRANS_INT_LEVEL);	}    }}/* Invoked on a write to the memory-mapped IO area. */static voidwrite_memory_mapped_IO (mem_addr addr, mem_word value){  switch (addr)    {    case TRANS_CTRL_ADDR:      /* Program can only set the interrupt enable, not ready, bit. */      if ((value & TRANS_INT_ENABLE) != 0)	{	  /* Enable interrupts: */	  trans_control |= TRANS_INT_ENABLE;	  if (trans_control & TRANS_READY)	    {	      /* Raise interrupt on enabling a ready transmitter */	      RAISE_INTERRUPT (TRANS_INT_LEVEL);	    }	}      else	{	  /* Disable interrupts: */	  trans_control &= ~TRANS_INT_ENABLE;	  CLEAR_INTERRUPT (TRANS_INT_LEVEL); /* Clear IP bit in Cause */	}      break;    case TRANS_BUFFER_ADDR:      /* Ignore write if device is not ready. */      if ((trans_control & TRANS_READY) != 0)	{	  /* Write char: */	  trans_buffer = value & 0xff;	  put_console_char ((char)trans_buffer);	  /* Device is busy for a while: */	  trans_control &= ~TRANS_READY;	  trans_buffer_full_timer = TRANS_LATENCY;          CLEAR_INTERRUPT (TRANS_INT_LEVEL); /* Clear IP bit in Cause */	}      break;    case RECV_CTRL_ADDR:      /* Program can only set the interrupt enable, not ready, bit. */      if ((value & RECV_INT_ENABLE) != 0)	{	  /* Enable interrupts: */	  recv_control |= RECV_INT_ENABLE;	  if (recv_control & RECV_READY)	    {	      /* Raise interrupt on enabling a ready receiver */	      RAISE_INTERRUPT (RECV_INT_LEVEL);	    }	}      else	{	  /* Disable interrupts: */	  recv_control &= ~RECV_INT_ENABLE;	  CLEAR_INTERRUPT (RECV_INT_LEVEL); /* Clear IP bit in Cause */	}      break;    case RECV_BUFFER_ADDR:      /* Nop: program can't change buffer. */      break;    default:      run_error ("Write to unused memory-mapped IO address (0x%x)\n", addr);    }}/* Invoked on a read in the memory-mapped IO area. */static mem_wordread_memory_mapped_IO (mem_addr addr){  switch (addr)    {    case TRANS_CTRL_ADDR:      return (trans_control);    case TRANS_BUFFER_ADDR:      return (trans_buffer & 0xff);    case RECV_CTRL_ADDR:      return (recv_control);    case RECV_BUFFER_ADDR:      recv_control &= ~RECV_READY; /* Buffer now empty */      recv_buffer_full_timer = 0;      CLEAR_INTERRUPT (RECV_INT_LEVEL); /* Clear IP bit in Cause */      return (recv_buffer & 0xff);    default:      run_error ("Read from unused memory-mapped IO address (0x%x)\n", addr);      return (0);    }}/* Misc. routines */voidprint_mem (mem_addr addr){  mem_word value;  if ((addr & 0x3) != 0)    addr &= ~0x3;		/* Address must be word-aligned */  if (TEXT_BOT <= addr && addr < text_top)    print_inst (addr);  else if (DATA_BOT <= addr && addr < data_top)    {      value = read_mem_word (addr);      write_output (message_out, "Data seg @ 0x%08x (%d) = 0x%08x (%d)\n",		    addr, addr, value, value);    }  else if (stack_bot <= addr && addr < STACK_TOP)    {      value = read_mem_word (addr);      write_output (message_out, "Stack seg @ 0x%08x (%d) = 0x%08x (%d)\n",		    addr, addr, value, value);    }  else if (K_TEXT_BOT <= addr && addr < k_text_top)    print_inst (addr);  else if (K_DATA_BOT <= addr && addr < k_data_top)    {      value = read_mem_word (addr);      write_output (message_out,		    "Kernel Data seg @ 0x%08x (%d) = 0x%08x (%d)\n",		    addr, addr, value, value);    }  else    error ("Address 0x%08x (%d) to print_mem is out of bounds\n", addr, addr);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -