/******************************************************************* TPUDB Project to Create Free Motorola 683xx TPU Debugger tpudb.c - first test (C) Copyright 2000 by Pavel Pisa - Original Author e-mail: pisa@cmp.felk.cvut.cz homepage: http://cmp.felk.cvut.cz/~pisa work: http://www.pikron.com/ This package can be copied and modified under GNU General Public License with all its conditions. See file GPL for details. Under this license nobody can distribute this work and any derived work without full source code for all modules compiled and linked into executable. *******************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include "bdm.h" #include "bdmlib.h" #define __val2mfld(mask,val) (((mask)&~((mask)<<1))*(val)&(mask)) #define __mfld2val(mask,val) (((val)&(mask))/((mask)&~((mask)<<1))) #define val2mfld __val2mfld #define mfld2val __mfld2val #if 0 #define TPU_WR16(adr,val) (*(volatile u_int16_t*)(adr)=(val)) #define TPU_RD16(adr) (*(volatile u_int16_t*)(adr)) #else #define TPU_WR16(adr,val) \ ({ \ if(bdmlib_write_var(adr,BDM_SIZE_WORD,val)<0) \ goto mem_op_error; \ val; \ }) #define TPU_RD16(adr) \ ({ u_int16_t temp_val; \ if(bdmlib_read_var(adr,BDM_SIZE_WORD,&temp_val)<0) \ goto mem_op_error; \ temp_val; \ }) #endif char hashmark=0; /* flag set by "set hash" */ int bdm_autoreset=1; /* automatic reset before load */ int bdm_ttcu=0; /* time to come up for init by rom */ char initname[255]; /* need reimplement !!!!!!!!! */ char bdm_dev_name[255]="/dev/bdm"; /* device name */ /* Numberring of TPU register */ /* First part are aliases for main CPU accesible registers */ #define TPUREG_TSTMSRA 0x0 /* Master Shift Register A */ #define TPUREG_TSTMSRB 0x1 /* Master Shift Register B */ #define TPUREG_TSTSC 0x2 /* Test Module Shift Count */ #define TPU_TSTSCA 0xff00 /* Bits Shifted from TSTMSRA to Tested Module */ #define TPU_TSTSCB 0x00ff /* Bits Shifted from Tested Module to TSTMSRB */ #define TPUREG_TSTRC 0x3 /* Test Module Repetition Count */ #define TPUREG_CREG 0x4 /* Test Submodule Control Register */ #define TPU_TSTBUSY 0x8000 /* Test Submodule Busy Status Bit */ #define TPU_TMARM 0x4000 /* Test Mode Armed Status Bit (latched /TSTME) */ #define TPU_COMP 0x2000 /* Compare Status Bit */ #define TPU_IMBTST 0x1000 /* Intermodule Bus Test (SCANA/SCANB) */ #define TPU_CPUTR 0x0800 /* Scan to CPU Test Register */ #define TPU_QBIT 0x0400 /* Quotient Bit at FREEZE/QUOT Pin */ #define TPU_MUXEL 0x0200 /* Multiplexer Select Bit for MSRB from Int/Ext */ #define TPU_ACUT 0x0010 /* Activate Circuit Under Test */ #define TPU_SCONT 0x0008 /* Start Continuous Operation */ #define TPU_SSHOP 0x0004 /* Start Shifting Operation */ #define TPU_SATO 0x0002 /* Start Automatic Test Operation */ #define TPU_EMT 0x0001 /* Enter test mode */ #define TPUREG_DREG 0x5 /* Distributed Register */ #define TPU_WAIT 0x0700 /* Wait Counter Preset 2-16 SCLK */ #define TPU_MSRAHI 0x0e0 /* MSRA High Bits 18-16 */ #define TPU_MSRAC 0x0010 /* Master Shift Register A Configuration */ #define TPU_MSRBHI 0x00e /* MSRB High Bits 18-16 */ #define TPU_MSRBC 0x0001 /* Master Shift Register B Configuration */ #define TPUREG_MCR 0x6 /* TPU Module Configuration Register */ #define TPU_STOP 0x8000 /* Low-Power Stop Mode Enable */ #define TPU_TCR1P 0x6000 /* Timer Count Register 1 Prescaler Control */ #define TPU_TCR2P 0x1800 /* Timer Count Register 2 Prescaler Control */ #define TPU_EMU 0x0400 /* Emulation Control */ #define TPU_T2CG 0x0200 /* TCR2 Clock/Gate Control */ #define TPU_STF 0x0100 /* Stop Flag */ #define TPU_SUPV 0x0080 /* Supervisor/Unrestricted */ #define TPU_PSCK 0x0040 /* Prescaler Clock */ #define TPU_IARB 0x000f /* Interrupt Arbitration ID */ #define TPUREG_TCR 0x7 /* Test Configuration Register */ #define TPU_INCAD 0x1000 /* Increment Address in uPC at ACUTL */ #define TPU_TCR1C 0x0800 /* TCR1 Clock - TCR2 pin */ #define TPU_ACUTR 0x0600 /* Activate Circuit Under Test Response 1, 0 */ #define TPU_ACUTR_NONE 0 /* None */ #define TPU_ACUTR_STEPTPU 1 /* Run ONE TPU microcycle */ #define TPU_ACUTR_SHEOT 2 /* Scheduler End of Time Slot */ #define TPU_SOSEL 0x0070 /* Scan-Out Select */ #define TPU_SISEL 0x000e /* Scan-in Select */ #define TPU_SxSEL_NONE 0 /* None */ #define TPU_SxSEL_PC 1 /* uPC */ #define TPU_SxSEL_IR 2 /* Microinstruction */ #define TPU_SxSEL_BPLA 3 /* Branch PLA */ #define TPU_SxSEL_PCBR 4 /* uPC Breakpoint */ #define TPU_SxSEL_SPLA 5 /* Scheduler PLA */ #define TPU_SxSEL_CHANBR 6 /* Channel Breakpoint */ #define TPU_TMW 0x0001 /* Test Memory Map */ #define TPUREG_DSCR 0x8 /* Development Support Control Register */ #define TPU_HOT4 0x8000 /* Hang on T4 */ #define TPU_BLC 0x0400 /* Branch Latch Control */ #define TPU_CLKS 0x0200 /* Stop Clocks (to TCRs) */ #define TPU_FRZ 0x0180 /* FREEZE Assertion Response */ #define TPU_CCL 0x0040 /* Channel Conditions Latch */ #define TPU_BMSK 0x003F /* Break cond mask */ #define TPU_BP 0x0020 /* Break mPC == mPC breakpoint register */ #define TPU_BC 0x0010 /* Break if CHAN start or set */ #define TPU_BH 0x0008 /* Break if host service latch set */ #define TPU_BL 0x0004 /* Break if link service latch set */ #define TPU_BM 0x0002 /* Break if MRL set at beginning*/ #define TPU_BT 0x0001 /* Break if TDL set at beginnibg */ #define TPUREG_DSSR 0x9 /* Development Support Status Register */ #define TPU_BKPT 0x0080 /* Breakpoint Asserted Flag */ #define TPU_PCBK 0x0040 /* mPC Breakpoint Flag */ #define TPU_CHBK 0x0020 /* Channel Register Breakpoint Flag */ #define TPU_SRBK 0x0010 /* Service Request Breakpoint Flag */ #define TPU_TPUF 0x0008 /* TPU FREEZE Flag */ #define TPUREG_TICR 0xA /* TPU Interrupt Configuration Register */ #define TPU_CIRL 0x0700 /* Channel Interrupt Request Level */ #define TPU_CIBV 0x00f0 /* Bits [7:4] of Channel Interrupt Base Vector */ #define TPUREG_CIER 0xB /* Channel Interrupt Enable Register */ #define TPUREG_CFSR 0xC /* Channel Function Select Register 0 */ #define TPUREG_HSQR 0xD /* Host Sequence Register 0 */ #define TPUREG_HSRR 0xE /* Host Service Request Register 0 */ #define TPUREG_CPR 0xF /* Channel Priority Register 0 */ #define TPUREG_CISR 0x10 /* Channel Interrupt Status Register */ #define TPUREG_LR 0x11 /* Link Register */ #define TPUREG_SGLR 0x12 /* Service Grant Latch Register */ #define TPUREG_DCNR 0x13 /* Decoded Channel Number Register */ /* Registers not accesible from main CPU */ #define TPUREG_P 0x14 /* Parameter Register (16-bit) */ #define TPUREG_A 0x15 /* Accumulator (16-bit) */ #define TPUREG_DIOB 0x16 /* Data I/O Buffer (16-bit) */ #define TPUREG_SR 0x17 /* Shift Register (16-bit) */ #define TPUREG_ERT 0x18 /* Event Temporary Register (16-b.) */ #define TPUREG_CHAN 0x19 /* Channel Number (4-bit) */ #define TPUREG_DEC 0x1A /* Decrementator Reg (4-bit) */ #define TPUREG_TCR2 0x1B /* Timebase Register 2 (16-bit) */ #define TPUREG_TCR1 0x1C /* Timebase Register 1 (16-bit) */ #define TPUREG_PC 0x1D /* Microprogram Counter (9-bit) */ #define TPUREG_IR 0x1E /* */ #define TPUREG_BPLA 0x1F /* */ #define TPUREG_SPLA 0x20 /* */ #define TPUREG_PCBR 0x21 /* */ #define TPUREG_CHANBR 0x22 /* */ /* Aditional CPU Accessible Registers */ #define TPUREG_DEBPAR 0x23 /* Parameter register at 0xFFFF00 for debugging */ #define TRAMREG_CR 0x24 /* TPURAM Configuration Register */ #define TRAM_STOP 0x8000 /* Low-Power Stop Mode Enable */ #define TRAM_RASP 0x0080 /* TPURAM Array Space */ #define TRAMREG_TST 0x25 /* TPURAM Test Register */ #define TRAMREG_BAR 0x26 /* TPURAM Base Address and Status Register */ #define TRAM_ADDR 0xfff0 /* TPURAM Array Base Address */ #define TRAM_RAMDS 0x0001 /* RAM Array Disable */ #define TPUREG_MAX 0x26 /* Descriptor of TPU register access */ typedef struct tpu_reg_des { int (*reg_rd)(struct tpu_reg_des *des, int indx); int (*reg_wr)(struct tpu_reg_des *des, int indx, int val); int adr; int adr1; int flags; int arr_len; /* array size, 0 .. no array */ int bfld_bits; /* bitfield length, 0 .. no bitfields */ int bfld_arr_len; /* bitfield array */ }tpu_reg_des_t; int tpu_mem_rd16(struct tpu_reg_des *des, int indx); int tpu_mem_wr16(struct tpu_reg_des *des, int indx, int val); int tpu_t1_rd(struct tpu_reg_des *des, int indx); int tpu_t1_wr(struct tpu_reg_des *des, int indx, int val); int tpu_t2_rd(struct tpu_reg_des *des, int indx); int tpu_t2_wr(struct tpu_reg_des *des, int indx, int val); int tpu_reg_rd(int reg, int indx); int tpu_reg_wr(int reg, int indx, int val); int tpu_reg_or(int reg, int indx, int val); int tpu_reg_and(int reg, int indx, int val); #define TPUREG_FL_SH4 1 /* shift value by 4 bits */ #define TPUREG_FL_PMOD 2 /* modification for reg P */ #define TPUREG_FL_DIOB 4 /* modification for reg DIOB */ #define TPUREG_INDX_BFLD (0x1<<24) /* index for bitfields */ /* Descriptors of TPU register access */ tpu_reg_des_t tpu_regs[]={ /* CPU accessible */ [TPUREG_TSTMSRA]= {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFA30,}, [TPUREG_TSTMSRB]= {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFA32,}, [TPUREG_TSTSC] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFA34,}, [TPUREG_TSTRC] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFA36,}, [TPUREG_CREG] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFA38,}, [TPUREG_DREG] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFA3A,}, [TPUREG_MCR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE00,}, [TPUREG_TCR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE02,}, [TPUREG_DSCR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE04,}, [TPUREG_DSSR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE06,}, [TPUREG_TICR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE08,}, [TPUREG_CIER] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE0A, arr_len:0,bfld_bits:1,bfld_arr_len:16,}, [TPUREG_CFSR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE0C, arr_len:4,bfld_bits:4,bfld_arr_len:16,}, [TPUREG_HSQR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE14, arr_len:2,bfld_bits:2,bfld_arr_len:16,}, [TPUREG_HSRR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE18, arr_len:2,bfld_bits:2,bfld_arr_len:16,}, [TPUREG_CPR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE1C, arr_len:2,bfld_bits:2,bfld_arr_len:16,}, [TPUREG_CISR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE20, arr_len:0,bfld_bits:1,bfld_arr_len:16,}, [TPUREG_LR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE22,}, [TPUREG_SGLR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE24,}, [TPUREG_DCNR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE26,}, /* Special TPU - group 1 */ /* internal TPU registers, ounly access possible through forced TPU microengine instructions */ /* adr .. instruction for reg read, adr1 .. instruction for reg write */ [TPUREG_P] = {reg_rd:tpu_t1_rd,reg_wr:tpu_t1_wr,adr:0x3fff,adr1:0x36ff, flags:TPUREG_FL_PMOD,}, [TPUREG_A] = {reg_rd:tpu_t1_rd,reg_wr:tpu_t1_wr,adr:0x327f,adr1:0x361f}, [TPUREG_DIOB] = {reg_rd:tpu_t1_rd,reg_wr:tpu_t1_wr,adr:0,adr1:0, flags:TPUREG_FL_DIOB,}, [TPUREG_SR] = {reg_rd:tpu_t1_rd,reg_wr:tpu_t1_wr,adr:0x347f,adr1:0x363f}, [TPUREG_ERT] = {reg_rd:tpu_t1_rd,reg_wr:tpu_t1_wr,adr:0x3c7f,adr1:0x365f}, [TPUREG_CHAN] = {reg_rd:tpu_t1_rd,reg_wr:tpu_t1_wr,adr:0x267f,adr1:0x373f, flags:TPUREG_FL_SH4,}, [TPUREG_DEC] = {reg_rd:tpu_t1_rd,reg_wr:tpu_t1_wr,adr:0x247f,adr1:0x375f}, [TPUREG_TCR2] = {reg_rd:tpu_t1_rd,reg_wr:tpu_t1_wr,adr:0x387f,adr1:0x379f}, [TPUREG_TCR1] = {reg_rd:tpu_t1_rd,reg_wr:tpu_t1_wr,adr:0x3a7f,adr1:0x37bf}, /* Special TPU - group 2 */ /* access through test subsystem serial scan lines */ /* adr .. number of register bits, adr1 .. TPU scan line selection */ [TPUREG_PC] = {reg_rd:tpu_t2_rd,reg_wr:tpu_t2_wr,adr: 9,adr1:TPU_SxSEL_PC}, [TPUREG_IR] = {reg_rd:NULL,reg_wr:NULL,adr:0,adr1:0}, [TPUREG_BPLA] = {reg_rd:tpu_t2_rd,reg_wr:tpu_t2_wr,adr:16,adr1:TPU_SxSEL_BPLA}, [TPUREG_SPLA] = {reg_rd:tpu_t2_rd,reg_wr:tpu_t2_wr,adr:15,adr1:TPU_SxSEL_SPLA}, [TPUREG_PCBR] = {reg_rd:tpu_t2_rd,reg_wr:tpu_t2_wr,adr: 9,adr1:TPU_SxSEL_PCBR}, [TPUREG_CHANBR] = {reg_rd:tpu_t2_rd,reg_wr:tpu_t2_wr,adr: 4,adr1:TPU_SxSEL_CHANBR}, /* One of parameter registers used for internal registers access */ /* was TPUREG_DEBUR */ [TPUREG_DEBPAR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFF00,}, [TRAMREG_CR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFB00,}, [TRAMREG_TST] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFB02,}, [TRAMREG_BAR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFB04,}, }; /**************************************************************************/ /* Helper function for test register access */ static int use_fetched_reg; static u_int16_t fetched_dscr; static u_int16_t fetched_creg; static u_int16_t fetched_tcr; static u_int16_t stored_diob; static u_int16_t stored_pc; static u_int16_t stored_debpar2; /* was strored_debur2 */ static u_int32_t stored_ir; /* was strored_x1 */ /* was strored_x2 */ static void test_shift_wait(unsigned creg) { int cnt=0x8000; tpu_reg_wr(TPUREG_CREG,0,creg|TPU_SSHOP); /* 4 */ do{ creg=tpu_reg_rd(TPUREG_CREG,0); if(!(creg&TPU_TSTBUSY)) return; /* 0x8000 */ }while(cnt--); fprintf(stderr,"test_shift_wait : stalled busy condition\n"); } /* Write 32 Bit Instruction Register */ static /* was test_shift_1 */ void test_shift_irwr(u_int32_t new_ir ) { u_int16_t dscr; /* [bp-6] */ u_int16_t creg; /* si */ u_int16_t tcr; /* di */ if (!use_fetched_reg){ tpu_reg_wr(TPUREG_TSTMSRB,0,0); tpu_reg_wr(TPUREG_TSTRC,0,0); tpu_reg_wr(TPUREG_DREG,0,0); dscr=tpu_reg_rd(TPUREG_DSCR,0); creg=tpu_reg_rd(TPUREG_CREG,0); tcr=tpu_reg_rd(TPUREG_TCR,0); }else{ creg=fetched_creg; tcr=fetched_tcr; dscr=fetched_dscr; } creg=(creg|TPU_IMBTST)&~TPU_MUXEL; /*!!!!!!!!!!!*/ tpu_reg_wr(TPUREG_CREG,0,creg); if(!(dscr&TPU_HOT4)) /* ???????? */ tpu_reg_wr(TPUREG_DSCR,0,dscr|TPU_HOT4); tcr&=TPU_INCAD | TPU_TCR1C | TPU_TMW; /* 0x1801 */ tpu_reg_wr(TPUREG_TCR,0,tcr | val2mfld(TPU_ACUTR,TPU_ACUTR_STEPTPU) | val2mfld(TPU_SISEL,TPU_SxSEL_IR)); /* 0x204 */ tpu_reg_wr(TPUREG_TSTSC,0,0x1000); tpu_reg_wr(TPUREG_TSTMSRA,0,new_ir&0xffff); test_shift_wait(creg); /* test shift */ tpu_reg_wr(TPUREG_TCR,0,tcr | val2mfld(TPU_ACUTR,TPU_ACUTR_STEPTPU) | val2mfld(TPU_SISEL,TPU_SxSEL_IR)); /* 0x204 */ tpu_reg_wr(TPUREG_TSTSC,0,0x1000); tpu_reg_wr(TPUREG_TSTMSRA,0,(new_ir>>16)&0xffff); test_shift_wait(creg); /* test shift */ if(!(dscr&TPU_HOT4)) /* ???????? */ tpu_reg_wr(TPUREG_DSCR,0,dscr); } /* Read 32 Bit Instruction Register */ static /* was test_shift_2 */ u_int32_t test_shift_irrd(void) { u_int16_t dscr; /* [bp-0a] */ u_int16_t creg; /* si */ u_int16_t tcr; /* di */ u_int16_t ir_lo,ir_hi; if (!use_fetched_reg){ tpu_reg_wr(TPUREG_TSTMSRB,0,0); tpu_reg_wr(TPUREG_TSTRC,0,0); tpu_reg_wr(TPUREG_DREG,0,0); dscr=tpu_reg_rd(TPUREG_DSCR,0); creg=tpu_reg_rd(TPUREG_CREG,0); tcr=tpu_reg_rd(TPUREG_TCR,0); }else{ creg=fetched_creg; tcr=fetched_tcr; dscr=fetched_dscr; } creg=(creg|TPU_IMBTST)&~TPU_MUXEL; /*!!!!!!!!!!!*/ tpu_reg_wr(TPUREG_CREG,0,creg); if(!(dscr&TPU_HOT4)) /* ???????? */ tpu_reg_wr(TPUREG_DSCR,0,dscr|TPU_HOT4); tcr&=TPU_INCAD | TPU_TCR1C | TPU_TMW; /* 0x1801 */ tpu_reg_wr(TPUREG_TCR,0,tcr | val2mfld(TPU_ACUTR,TPU_ACUTR_STEPTPU) | val2mfld(TPU_SOSEL,TPU_SxSEL_IR)); /* 0x220 */ tpu_reg_wr(TPUREG_TSTSC,0,0x0010); test_shift_wait(creg); /* test shift */ ir_lo=tpu_reg_rd(TPUREG_TSTMSRB,0); tpu_reg_wr(TPUREG_TCR,0,tcr | val2mfld(TPU_ACUTR,TPU_ACUTR_STEPTPU) | val2mfld(TPU_SOSEL,TPU_SxSEL_IR) | val2mfld(TPU_SISEL,TPU_SxSEL_IR)); /* 0x224 */ tpu_reg_wr(TPUREG_TSTSC,0,0x1010); tpu_reg_wr(TPUREG_TSTMSRA,0,ir_lo); test_shift_wait(creg); /* test shift */ ir_hi=tpu_reg_rd(TPUREG_TSTMSRB,0); tpu_reg_wr(TPUREG_TCR,0,tcr | val2mfld(TPU_ACUTR,TPU_ACUTR_STEPTPU) | val2mfld(TPU_SISEL,TPU_SxSEL_IR)); /* 0x204 */ tpu_reg_wr(TPUREG_TSTSC,0,0x1000); tpu_reg_wr(TPUREG_TSTMSRA,0,ir_hi); test_shift_wait(creg); /* test shift */ if(!(dscr&TPU_HOT4)) /* ???????? */ tpu_reg_wr(TPUREG_DSCR,0,dscr); return ir_lo|((u_int32_t)ir_hi<<16); } static /* was test_shift_3 */ int test_shift_regrd(int shiftcnt ,int sxsel) { u_int16_t dscr; /* [bp-8] */ u_int16_t creg; /* si */ u_int16_t tcr; /* di */ u_int16_t ret; if (!use_fetched_reg){ tpu_reg_wr(TPUREG_TSTMSRB,0,0); tpu_reg_wr(TPUREG_TSTRC,0,0); tpu_reg_wr(TPUREG_DREG,0,0); dscr=tpu_reg_rd(TPUREG_DSCR,0); creg=tpu_reg_rd(TPUREG_CREG,0); tcr=tpu_reg_rd(TPUREG_TCR,0); }else{ creg=fetched_creg; tcr=fetched_tcr; dscr=fetched_dscr; } creg=(creg|TPU_IMBTST)&~TPU_MUXEL; /*!!!!!!!!!!!*/ tpu_reg_wr(TPUREG_CREG,0,creg); if(!(dscr&TPU_HOT4)) /* ???????? */ tpu_reg_wr(TPUREG_DSCR,0,dscr|TPU_HOT4); tcr&=TPU_INCAD | TPU_TCR1C | TPU_TMW; /* 0x1801 */ tpu_reg_wr(TPUREG_TCR,0,tcr | val2mfld(TPU_ACUTR,TPU_ACUTR_STEPTPU) | val2mfld(TPU_SOSEL,sxsel)); /* (sxsel<<4)|0x200 */ tpu_reg_wr(TPUREG_TSTSC,0,shiftcnt); test_shift_wait(creg); /* test shift */ ret=tpu_reg_rd(TPUREG_TSTMSRB,0)>>(0x10-shiftcnt); tpu_reg_wr(TPUREG_TCR,0,tcr | val2mfld(TPU_ACUTR,TPU_ACUTR_STEPTPU) | val2mfld(TPU_SISEL,sxsel)); /* (sxsel<<1)|0x200 */ tpu_reg_wr(TPUREG_TSTSC,0,shiftcnt<<8); tpu_reg_wr(TPUREG_TSTMSRA,0,ret); test_shift_wait(creg); /* test shift */ if(!(dscr&TPU_HOT4)) /* ???????? */ tpu_reg_wr(TPUREG_DSCR,0,dscr); return ret; } static /* was test_shift_4 */ int test_shift_regwr(int shiftcnt, int sxsel, int val) { u_int16_t dscr; /* di */ u_int16_t creg; /* si */ u_int16_t tcr; /* [bp-6] */ if (!use_fetched_reg){ tpu_reg_wr(TPUREG_TSTMSRB,0,0); tpu_reg_wr(TPUREG_TSTRC,0,0); tpu_reg_wr(TPUREG_DREG,0,0); dscr=tpu_reg_rd(TPUREG_DSCR,0); creg=tpu_reg_rd(TPUREG_CREG,0); tcr=tpu_reg_rd(TPUREG_TCR,0); }else{ creg=fetched_creg; tcr=fetched_tcr; dscr=fetched_dscr; } if(!(dscr&TPU_HOT4)) /* ???????? */ tpu_reg_wr(TPUREG_DSCR,0,dscr|TPU_HOT4); creg=(creg|TPU_IMBTST)&~TPU_MUXEL; /*!!!!!!!!!!!*/ tpu_reg_wr(TPUREG_CREG,0,creg); tcr&=TPU_INCAD | TPU_TCR1C | TPU_TMW; /* 0x1801 */ tpu_reg_wr(TPUREG_TCR,0,tcr | val2mfld(TPU_ACUTR,TPU_ACUTR_STEPTPU) | val2mfld(TPU_SISEL,sxsel)); /* (sxsel<<1)|0x200 */ tpu_reg_wr(TPUREG_TSTSC,0,shiftcnt<<8); tpu_reg_wr(TPUREG_TSTMSRA,0,val); test_shift_wait(creg); /* test shift */ if(!(dscr&TPU_HOT4)) /* ???????? */ tpu_reg_wr(TPUREG_DSCR,0,dscr); return 0; } static /* was test_pha_2 */ void test_forced_inst(u_int32_t new_ir) { test_shift_irwr(new_ir); tpu_reg_or(TPUREG_CREG,0,TPU_ACUT); } static /* was test_pha_1 */ void test_store_ir(void) { stored_debpar2=tpu_reg_rd(TPUREG_DEBPAR,0); stored_pc=tpu_reg_rd(TPUREG_PC,0); stored_ir=test_shift_irrd(); test_forced_inst(0x3ffffc03); stored_diob=tpu_reg_rd(TPUREG_DEBPAR,0); } static /* was test_pha_3 */ void test_restore_ir(void) { tpu_reg_wr(TPUREG_DEBPAR,0,stored_diob); test_forced_inst(0x1ffffc03); tpu_reg_wr(TPUREG_DEBPAR,0,stored_debpar2); tpu_reg_wr(TPUREG_PC,0,stored_pc); test_shift_irwr(stored_ir); } /**************************************************************************/ /* Other supporting routines */ static u_int16_t test_dssrdscr_1; /* 0 => stop, 1 =>run */ static u_int16_t test_dscr_arm; static u_int16_t test_dssr_bkpt; int test_init_1(void) { u_int16_t creg; /* bp-2 */ int cnt=0x1000; tpu_reg_wr(TPUREG_CREG,0,TPU_MUXEL|TPU_EMT); creg=tpu_reg_rd(TPUREG_CREG,0); do{ creg=tpu_reg_rd(TPUREG_CREG,0); }while(!(creg&TPU_EMT)&&(--cnt)); tpu_reg_wr(TPUREG_CIER,0,0); /* disable interrupt generation */ if(!cnt){ fprintf(stderr,"test_init_1 : cannot enter test mode\n"); return -1; } return 0; } int test_init_2(void) { u_int16_t dssr; /* si */ u_int16_t dscr; /* bx */ dssr=tpu_reg_rd(TPUREG_DSSR,0); dscr=tpu_reg_rd(TPUREG_DSCR,0); if((dssr&TPU_BKPT)||(dscr&TPU_HOT4)) test_dssrdscr_1=0; else test_dssrdscr_1=1; test_dscr_arm=dscr&TPU_BMSK; if (dssr&TPU_BKPT) test_dssr_bkpt=1; else test_dssr_bkpt=0; return 0; } int tpu_halt(void) { int i; if(test_dssrdscr_1==0){ /* already halted */ /* return 0; */ } tpu_reg_or(TPUREG_CREG,0,TPU_IMBTST); /* stop microengine */ tpu_reg_wr(TPUREG_DSCR,0,TPU_HOT4|TPU_CLKS|test_dscr_arm); test_dssrdscr_1=0; /* old_cpr = CPR0,CPR1 */ /* CPR0,CPR1 = 0 */ for(i=0;i<5;i++){ if(tpu_reg_rd(TPUREG_DSSR,0)&TPU_BKPT) tpu_reg_and(TPUREG_DSSR,0,~TPU_BKPT); tpu_reg_or(TPUREG_CREG,0,TPU_IMBTST|TPU_ACUT); } /* CPR0,CPR1 = old_cpr */ return 0; } #define TPU_UCODE_LEN 0x200 u_int32_t tpu_ucode_img[TPU_UCODE_LEN]; int tpu_ucode_read(int print) { int adr; u_int32_t ir; adr=0; test_store_ir(); if(print)printf("reading microcode\n"); tpu_reg_wr(TPUREG_PC,0,adr); for(;adrflags&TPUREG_FL_DIOB){ val=stored_diob; /* DIOB read */ }else{ if(des->flags&TPUREG_FL_PMOD) test_forced_inst(0xf403|(des->adr<<16)); /* P read */ else test_forced_inst(0xfc03|(des->adr<<16)); /* rest */ /* read value from mem 0xFFFF00 */ val=tpu_reg_rd(TPUREG_DEBPAR,0); } test_restore_ir(); if(des->flags&TPUREG_FL_SH4) val>>=4; return val; } /* write TPU register - method 1 */ int tpu_t1_wr(struct tpu_reg_des *des, int indx, int val) { int ret; test_store_ir(); if(des->flags&TPUREG_FL_SH4) val<<=4; ret=tpu_reg_wr(TPUREG_DEBPAR,0,val); test_forced_inst(0x1ffffc03); if(des->flags&TPUREG_FL_DIOB){ stored_diob=val; /* DIOB write */ }else{ test_forced_inst(0xffff|(des->adr1<<16)); /* rest */ } test_restore_ir(); return 0; } /* read TPU register - method 2 */ int tpu_t2_rd(struct tpu_reg_des *des, int indx) { return test_shift_regrd(des->adr,des->adr1); } /* write TPU register - method 2 */ int tpu_t2_wr(struct tpu_reg_des *des, int indx, int val) { return test_shift_regwr(des->adr,des->adr1,val); } /* read 16 bit variable from main CPU address space */ int tpu_mem_rd16(struct tpu_reg_des *des, int indx) { u_int16_t val; int adr=des->adr; if(indx){ if(indx>=des->arr_len) return -1; adr+=2*indx; } val=TPU_RD16((caddr_t)adr); return val; mem_op_error: fprintf(stderr,"tpu_mem_rd16 : read from address %06x error\n",adr); fflush(NULL); return -1; } /* write 16 bit variable to main CPU address space */ int tpu_mem_wr16(struct tpu_reg_des *des, int indx, int val) { int adr=des->adr; if(indx){ if(indx>=des->arr_len) return -1; adr+=2*indx; } TPU_WR16((caddr_t)adr,val); return 0; mem_op_error: fprintf(stderr,"tpu_mem_wr16 : write to address %06x error\n",adr); fflush(NULL); return -1; } /* Read TPU register */ int tpu_reg_rd(int reg, int indx) { if((reg>TPUREG_MAX)||(tpu_regs[reg].reg_rd==NULL)) return -1; return tpu_regs[reg].reg_rd(&tpu_regs[reg],indx); } /* Write TPU register */ int tpu_reg_wr(int reg, int indx, int val) { if((reg>TPUREG_MAX)||(tpu_regs[reg].reg_wr==NULL)) return -1; return tpu_regs[reg].reg_wr(&tpu_regs[reg],indx,val); } int tpu_reg_or(int reg, int indx, int val) { int reg_val; reg_val=tpu_reg_rd(reg,indx); reg_val|=val; tpu_reg_wr(reg,indx,reg_val); return reg_val; } int tpu_reg_and(int reg, int indx, int val) { int reg_val; reg_val=tpu_reg_rd(reg,indx); reg_val&=val; tpu_reg_wr(reg,indx,reg_val); return reg_val; } /**************************************************************************/ #define swap_l(x) (x>>24) | ((x>>8)&0xff00) | ((x<<8)&0xff0000) | ((x&0xff)<<24) /* external TPU disassembler */ void DisInst (unsigned long i, FILE * fp); int cpu_stat(void) { int ret; u_int rpc; ret=bdmlib_getstatus(); printf("MCU "); if(ret&BDM_TARGETRESET) printf("Reset "); if(ret&BDM_TARGETSTOPPED) printf("Stopped "); if(ret&BDM_TARGETPOWER) printf("NoPower "); if(ret&BDM_TARGETNC) printf("NoConnect "); printf("\n"); if(ret&BDM_TARGETSTOPPED) { if((ret=bdmlib_get_sys_reg(BDM_REG_RPC, &rpc))<0) return ret; printf("RPC=0x%06x\n",swap_l(rpc)); } return 0; } int main(int argc, char *argv[]) { int ret; bdmlib_setdebug(1); if((ret=bdmlib_open(bdm_dev_name))<0) { printf("bdmlib_open : %s\n",bdmlib_geterror_str(ret)); return 1; }; bdmlib_setioctl(BDM_SPEED,0); if (!(bdmlib_getstatus() & BDM_TARGETSTOPPED)) ret=bdmlib_ioctl(BDM_STOP_CHIP); if(1){ printf("We need to reset target for first run\n"); if((ret=bdmlib_reset())<0){ printf("Cannot reset target - exitting\n"); exit(1); } } if(cpu_stat()<0){ printf("trying to reset !!!!!!!\n"); ret=bdmlib_reset(); cpu_stat(); } bdmlib_set_sys_reg(BDM_REG_DFC, 5); bdmlib_set_sys_reg(BDM_REG_SFC, 5); ret=test_init_1(); printf("test_init_1 returned %d\n",ret); ret=test_init_2(); printf("test_init_2 returned %d\n",ret); printf("test_dssrdscr_1(run)=%d test_dscr_arm=0x%02x test_dssr_bkpt=%d\n", test_dssrdscr_1,test_dscr_arm,test_dssr_bkpt); fflush(NULL); // tpu_halt(); printf("DCNR %04X\n",tpu_reg_rd(TPUREG_DCNR,0)); printf("DSCR %04X\n",tpu_reg_rd(TPUREG_DSCR,0)); // tpu_reg_or(TPUREG_CREG,0,TPU_IMBTST); /* stop microengine */ // tpu_reg_or(TPUREG_DSCR,0,0x8200); /* ???????????? */ printf("P %04X DIOB %04X A %04X SR %04X DEC %01X\n" "ERT %04X TCR1 %04X TCR2 %04X PC %03X CHAN %01X\n", tpu_reg_rd(TPUREG_P,0),tpu_reg_rd(TPUREG_DIOB,0), tpu_reg_rd(TPUREG_A,0),tpu_reg_rd(TPUREG_SR,0), tpu_reg_rd(TPUREG_DEC,0),tpu_reg_rd(TPUREG_ERT,0), tpu_reg_rd(TPUREG_TCR1,0),tpu_reg_rd(TPUREG_TCR2,0), tpu_reg_rd(TPUREG_PC,0),tpu_reg_rd(TPUREG_CHAN,0)); if(0){ printf("TCR2 %04X\n",tpu_reg_rd(TPUREG_TCR2,0)); printf("TCR1 %04X\n",tpu_reg_rd(TPUREG_TCR1,0)); printf("TCR2 %04X\n",tpu_reg_rd(TPUREG_TCR2,0)); tpu_reg_wr(TPUREG_P ,0,0xABCD);tpu_reg_wr(TPUREG_DIOB,0,0xEF01); tpu_reg_wr(TPUREG_A ,0,0x2345);tpu_reg_wr(TPUREG_SR ,0,0x6789); tpu_reg_wr(TPUREG_DEC ,0, 0xA);tpu_reg_wr(TPUREG_ERT ,0,0xBCDE); tpu_reg_wr(TPUREG_TCR1,0,0xF012);tpu_reg_wr(TPUREG_TCR2,0,0x3456); tpu_reg_wr(TPUREG_PC ,0, 0x789);tpu_reg_wr(TPUREG_CHAN,0, 0xB); } { int i; tpu_ucode_read(0); for(i=0;i