📄 xscale_copro.c
字号:
/*
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 + -