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

📄 xscale_copro.c

📁 这是Skyeye 0.9 版本的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
    armmmu.c - Memory Management Unit emulation.
    ARMulator extensions for the ARM7100 family.
    Copyright (C) 1999  Ben Williamson

    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <assert.h>
#include <string.h>
#include "armdefs.h"
//chy 2005-09-19
#include "pxa.h"
extern pxa270_io_t pxa270_io;
//chy 2005-09-19 -----end

typedef struct xscale_mmu_desc_s
{
  int i_tlb;
  cache_desc_t i_cache;

  int d_tlb;
  cache_desc_t main_d_cache;
  cache_desc_t mini_d_cache;
  //int   rb;  xscale has no read buffer
  wb_desc_t wb;
} xscale_mmu_desc_t;

static xscale_mmu_desc_t pxa_mmu_desc = {
  32,
  {32, 32, 32, CACHE_WRITE_BACK},

  32,
  {32, 32, 32, CACHE_WRITE_BACK},
  {32, 2, 8, CACHE_WRITE_BACK},
  {8, 16},			//for byte size, 
};

//chy 2005-09-19 for cp6
#define CR0_ICIP   0
#define CR1_ICMR   1
//chy 2005-09-19 ---end
//----------- for cp14-----------------
#define  CCLKCFG   6
#define  PWRMODE   7
typedef struct xscale_cp14_reg_s
{
  unsigned cclkcfg;		//reg6
  unsigned pwrmode;		//reg7
} xscale_cp14_reg_s;

xscale_cp14_reg_s pxa_cp14_regs;

//--------------------------------------

static fault_t xscale_mmu_write (ARMul_State * state, ARMword va,
				 ARMword data, ARMword datatype);
static fault_t xscale_mmu_read (ARMul_State * state, ARMword va,
				ARMword * data, ARMword datatype);

ARMword xscale_mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value);
ARMword xscale_mmu_mcr (ARMul_State * state, ARMword instr, ARMword value);


//chy 2005-09-19 for xscale pxa27x cp6
unsigned 
xscale_cp6_mrc (ARMul_State * state, unsigned type, ARMword instr,
		 ARMword * data)
{
  unsigned opcode_2 = BITS (5, 7);
  unsigned CRm = BITS (0, 3);
  unsigned reg = BITS (16, 19);
  unsigned result;

  //printf("SKYEYE: xscale_cp6_mrc:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n",opcode_2,CRm,reg,state->Reg[15], instr);

  switch (reg)
    {
    case CR0_ICIP:		// cp 6 reg 0
      //printf("cp6_mrc cr0 ICIP              \n");
      *data = (pxa270_io.icmr & pxa270_io.icpr) & ~pxa270_io.iclr;
      break;
    case CR1_ICMR:		// cp 6 reg 1
      //printf("cp6_mrc cr1 ICMR\n");
      *data = pxa270_io.icmr;
      break;
    default:
      *data = 0;
      printf ("SKYEYE:cp6_mrc unknown cp6 regs!!!!!!\n");
      printf("SKYEYE: xscale_cp6_mrc:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n",opcode_2,CRm,reg,state->Reg[15], instr);
      break;
    }
  return 0;
}
//chy 2005-09-19 end
//xscale cp13 ----------------------------------------------------
unsigned
xscale_cp13_init (ARMul_State * state)
{
  //printf("SKYEYE: xscale_cp13_init: begin\n");
  return 0;
}

unsigned
xscale_cp13_exit (ARMul_State * state)
{
  //printf("SKYEYE: xscale_cp13_exit: begin\n");
  return 0;
}

unsigned
xscale_cp13_ldc (ARMul_State * state, unsigned type, ARMword instr,
		 ARMword data)
{
  printf ("SKYEYE: xscale_cp13_ldc: ERROR isn't existed,");
  SKYEYE_OUTREGS (stderr);
  fprintf (stderr, "\n");
  exit (-1);
}

unsigned
xscale_cp13_stc (ARMul_State * state, unsigned type, ARMword instr,
		 ARMword * data)
{
  printf ("SKYEYE: xscale_cp13_stc: ERROR isn't existed,");
  SKYEYE_OUTREGS (stderr);
  fprintf (stderr, "\n");
  exit (-1);
}

unsigned
xscale_cp13_mrc (ARMul_State * state, unsigned type, ARMword instr,
		 ARMword * data)
{
  printf ("SKYEYE: xscale_cp13_mrc: ERROR isn't existed,");
  SKYEYE_OUTREGS (stderr);
  fprintf (stderr, "\n");
  exit (-1);
}

unsigned
xscale_cp13_mcr (ARMul_State * state, unsigned type, ARMword instr,
		 ARMword data)
{
  printf ("SKYEYE: xscale_cp13_mcr: ERROR isn't existed,");
  SKYEYE_OUTREGS (stderr);
  fprintf (stderr, "\n");
  exit (-1);
}

unsigned
xscale_cp13_cdp (ARMul_State * state, unsigned type, ARMword instr)
{
  printf ("SKYEYE: xscale_cp13_cdp: ERROR isn't existed,");
  SKYEYE_OUTREGS (stderr);
  fprintf (stderr, "\n");
  exit (-1);
}

unsigned
xscale_cp13_read_reg (ARMul_State * state, unsigned reg, ARMword * data)
{
  printf ("SKYEYE: xscale_cp13_read_reg: ERROR isn't existed,");
  SKYEYE_OUTREGS (stderr);
  fprintf (stderr, "\n");
  return 0;
  //exit(-1);
}

unsigned
xscale_cp13_write_reg (ARMul_State * state, unsigned reg, ARMword data)
{
  printf ("SKYEYE: xscale_cp13_write_reg: ERROR isn't existed,");
  SKYEYE_OUTREGS (stderr);
  fprintf (stderr, "\n");
  exit (-1);
}

//------------------------------------------------------------------
//xscale cp14 ----------------------------------------------------
unsigned
xscale_cp14_init (ARMul_State * state)
{
  //printf("SKYEYE: xscale_cp14_init: begin\n");
  pxa_cp14_regs.cclkcfg = 0;
  pxa_cp14_regs.pwrmode = 0;
  return 0;
}

unsigned
xscale_cp14_exit (ARMul_State * state)
{
  //printf("SKYEYE: xscale_cp14_exit: begin\n");
  return 0;
}

unsigned
xscale_cp14_ldc (ARMul_State * state, unsigned type, ARMword instr,
		 ARMword data)
{
  printf ("SKYEYE: xscale_cp14_ldc: ERROR isn't existed, reg15 0x%x\n",
	  state->Reg[15]);
  SKYEYE_OUTREGS (stderr);
  exit (-1);
}

unsigned
xscale_cp14_stc (ARMul_State * state, unsigned type, ARMword instr,
		 ARMword * data)
{
  printf ("SKYEYE: xscale_cp14_stc: ERROR isn't existed, reg15 0x%x\n",
	  state->Reg[15]);
  SKYEYE_OUTREGS (stderr);
  exit (-1);
}

unsigned
xscale_cp14_mrc (ARMul_State * state, unsigned type, ARMword instr,
		 ARMword * data)
{
  unsigned opcode_2 = BITS (5, 7);
  unsigned CRm = BITS (0, 3);
  unsigned reg = BITS (16, 19);
  unsigned result;

  //printf("SKYEYE: xscale_cp14_mrc:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n",opcode_2,CRm,reg,\
  state->Reg[15], instr);

  switch (reg)
    {
    case CCLKCFG:		// cp 14 reg 6
      //printf("cp14_mrc cclkcfg              \n");
      *data = pxa_cp14_regs.cclkcfg;
      break;
    case PWRMODE:		// cp 14 reg 7
      //printf("cp14_mrc pwrmode              \n");
      *data = pxa_cp14_regs.pwrmode;
      break;
    default:
      *data = 0;
      printf ("SKYEYE:cp14_mrc unknown cp14 regs!!!!!!\n");
      break;
    }
  return 0;
}
unsigned xscale_cp14_mcr (ARMul_State * state, unsigned type, ARMword instr,
			  ARMword data)
{
  unsigned opcode_2 = BITS (5, 7);
  unsigned CRm = BITS (0, 3);
  unsigned reg = BITS (16, 19);
  unsigned result;

  //printf("SKYEYE: xscale_cp14_mcr:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n",opcode_2,CRm,reg,\
    state->Reg[15], instr);

  switch (reg)
    {
    case CCLKCFG:		// cp 14 reg 6
      //printf("cp14_mcr cclkcfg              \n");
      pxa_cp14_regs.cclkcfg = data & 0xf;
      break;
      case PWRMODE:		// cp 14 reg 7
	//printf("cp14_mcr pwrmode              \n");
      pxa_cp14_regs.pwrmode = data & 0x3;
      break;
      default:printf ("SKYEYE: cp14_mcr unknown cp14 regs!!!!!!\n");
      break;
    }
  return 0;
}
unsigned xscale_cp14_cdp (ARMul_State * state, unsigned type, ARMword instr)
{
  printf ("SKYEYE: xscale_cp14_cdp: ERROR isn't existed, reg15 0x%x\n",
	  state->Reg[15]);
  SKYEYE_OUTREGS (stderr);
  exit (-1);
}
unsigned xscale_cp14_read_reg (ARMul_State * state, unsigned reg,
			       ARMword * data)
{
  printf ("SKYEYE: xscale_cp14_read_reg: ERROR isn't existed, reg15 0x%x\n",
	  state->Reg[15]);
  SKYEYE_OUTREGS (stderr);
  exit (-1);
}
unsigned xscale_cp14_write_reg (ARMul_State * state, unsigned reg,
				ARMword data)
{
  printf ("SKYEYE: xscale_cp14_write_reg: ERROR isn't existed, reg15 0x%x\n",
	  state->Reg[15]);
  SKYEYE_OUTREGS (stderr);
  exit (-1);
}

//------------------------------------------------------------------
//cp15 -------------------------------------
unsigned xscale_cp15_ldc (ARMul_State * state, unsigned type, ARMword instr,
			  ARMword data)
{
  printf ("SKYEYE: xscale_cp15_ldc: ERROR isn't existed\n");
  SKYEYE_OUTREGS (stderr);
  exit (-1);
}
unsigned xscale_cp15_stc (ARMul_State * state, unsigned type, ARMword instr,
			  ARMword * data)
{
  printf ("SKYEYE: xscale_cp15_stc: ERROR isn't existed\n");
  SKYEYE_OUTREGS (stderr);
  exit (-1);
}
unsigned xscale_cp15_cdp (ARMul_State * state, unsigned type, ARMword instr)
{
  printf ("SKYEYE: xscale_cp15_cdp: ERROR isn't existed\n");
  SKYEYE_OUTREGS (stderr);
  exit (-1);
}
unsigned xscale_cp15_read_reg (ARMul_State * state, unsigned reg,
			       ARMword * data)
{
//chy 2003-09-03: for xsacle_cp15_cp_access_allowed
  if (reg == 15)
    {
      *data = state->mmu.copro_access;
      //printf("SKYEYE: xscale_cp15_read_reg: reg 0x%x,data %x\n",reg,*data);
      return 0;
    }
  printf ("SKYEYE: xscale_cp15_read_reg: reg 0x%x, ERROR isn't existed\n",
	  reg);
  SKYEYE_OUTREGS (stderr);
  exit (-1);
}

//chy 2003-09-03 used by macro CP_ACCESS_ALLOWED in armemu.h
unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg,
					unsigned cpnum)
{
  unsigned data;

  xscale_cp15_read_reg (state, reg, &data);
  //printf("SKYEYE: cp15_cp_access_allowed data %x, cpnum %x, result %x\n", data, cpnum, (data & 1<<cpnum));
  if (data & 1 << cpnum)
    return 1;
  else
    return 0;
}

unsigned xscale_cp15_write_reg (ARMul_State * state, unsigned reg,
				ARMword value)
{
  switch (reg)
    {
    case MMU_FAULT_STATUS:
      //printf("SKYEYE:cp15_write_reg  wrote FS        val 0x%x \n",value);
      state->mmu.fault_status = value & 0x6FF;
      break;
    case MMU_FAULT_ADDRESS:
      //printf("SKYEYE:cp15_write_reg wrote FA         val 0x%x \n",value);
      state->mmu.fault_address = value;
      break;
    default:
      printf
	("SKYEYE: xscale_cp15_write_reg: reg 0x%x R15 %x ERROR isn't existed\n",
	 reg, state->Reg[15]);
      SKYEYE_OUTREGS (stderr);
      exit (-1);
    }
  return 0;
}

int xscale_cp15_init (ARMul_State * state)
{
  xscale_mmu_desc_t *desc;
  cache_desc_t *c_desc;

  state->mmu.control = 0;
  state->mmu.translation_table_base = 0xDEADC0DE;
  state->mmu.domain_access_control = 0xDEADC0DE;
  state->mmu.fault_status = 0;
  state->mmu.fault_address = 0;
  state->mmu.process_id = 0;
  state->mmu.cache_type = 0xB1AA1AA;	//0000 1011 0001 1010 1010 0001 1010 1010
  state->mmu.aux_control = 0;

  desc = &pxa_mmu_desc;

  if (mmu_tlb_init (I_TLB (), desc->i_tlb))
    {
      err_msg ("i_tlb init %d\n", -1);
      goto i_tlb_init_error;
    }

  c_desc = &desc->i_cache;
  if (mmu_cache_init (I_CACHE (), c_desc->width, c_desc->way,
		      c_desc->set, c_desc->w_mode))
    {
      err_msg ("i_cache init %d\n", -1);
      goto i_cache_init_error;
    }

  if (mmu_tlb_init (D_TLB (), desc->d_tlb))
    {
      err_msg ("d_tlb init %d\n", -1);
      goto d_tlb_init_error;
    }

  c_desc = &desc->main_d_cache;
  if (mmu_cache_init (MAIN_D_CACHE (), c_desc->width, c_desc->way,
		      c_desc->set, c_desc->w_mode))
    {
      err_msg ("main_d_cache init %d\n", -1);
      goto main_d_cache_init_error;
    }

  c_desc = &desc->mini_d_cache;
  if (mmu_cache_init (MINI_D_CACHE (), c_desc->width, c_desc->way,
		      c_desc->set, c_desc->w_mode))
    {
      err_msg ("mini_d_cache init %d\n", -1);
      goto mini_d_cache_init_error;
    }

  if (mmu_wb_init (WB (), desc->wb.num, desc->wb.nb))
    {
      err_msg ("wb init %d\n", -1);
      goto wb_init_error;
    }
#if 0
  if (mmu_rb_init (RB (), desc->rb))
    {
      err_msg ("rb init %d\n", -1);
      goto rb_init_error;
    }
#endif

  return 0;
#if 0
rb_init_error:
  mmu_wb_exit (WB ());
#endif
wb_init_error:
  mmu_cache_exit (MINI_D_CACHE ());
mini_d_cache_init_error:
  mmu_cache_exit (MAIN_D_CACHE ());
main_d_cache_init_error:
  mmu_tlb_exit (D_TLB ());
d_tlb_init_error:
  mmu_cache_exit (I_CACHE ());
i_cache_init_error:
  mmu_tlb_exit (I_TLB ());
i_tlb_init_error:
  return -1;
}

void xscale_cp15_exit (ARMul_State * state)
{
  //mmu_rb_exit(RB());
  mmu_wb_exit (WB ());
  mmu_cache_exit (MINI_D_CACHE ());

⌨️ 快捷键说明

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