1bdcaa8d0Smrg/* 2bdcaa8d0Smrg * 3bdcaa8d0Smrg */ 4bdcaa8d0Smrg 5bdcaa8d0Smrg#ifdef HAVE_CONFIG_H 6bdcaa8d0Smrg#include "config.h" 7bdcaa8d0Smrg#endif 8bdcaa8d0Smrg 9bdcaa8d0Smrg/* 10bdcaa8d0Smrg * includes 11bdcaa8d0Smrg */ 12bdcaa8d0Smrg 13bdcaa8d0Smrg#include "rendition.h" 14bdcaa8d0Smrg#include "v1krisc.h" 15bdcaa8d0Smrg#include "vos.h" 16bdcaa8d0Smrg 17bdcaa8d0Smrg 18bdcaa8d0Smrg 19bdcaa8d0Smrg/* 20bdcaa8d0Smrg * defines 21bdcaa8d0Smrg */ 22bdcaa8d0Smrg 23bdcaa8d0Smrg/* RISC registers */ 24bdcaa8d0Smrg#define RISC_FLAG 37 /* RISC flags register */ 25bdcaa8d0Smrg#define RISC_SP 252 /* RISC stack pointer/scratch register */ 26bdcaa8d0Smrg#define RISC_IRA 253 /* RISC register */ 27bdcaa8d0Smrg#define RISC_RA 254 /* RISC program link/scratch register */ 28bdcaa8d0Smrg#define RISC_FP 255 /* RISC frame pointer/scratch register */ 29bdcaa8d0Smrg 30bdcaa8d0Smrg/* RISC opcodes used */ 31bdcaa8d0Smrg#define NOP_INSTR 0x00000000 /* really add immed with D=zero */ 32bdcaa8d0Smrg#define ADDI_OP 0x00 33bdcaa8d0Smrg#define SPRI_OP 0x4f 34bdcaa8d0Smrg#define ADD_OP 0x10 35bdcaa8d0Smrg#define ANDN_OP 0x12 36bdcaa8d0Smrg#define OR_OP 0x15 37bdcaa8d0Smrg#define ADDIFI_OP 0x40 38bdcaa8d0Smrg#define ADDSL8_OP 0x4b 39bdcaa8d0Smrg#define LB_OP 0x70 40bdcaa8d0Smrg#define LH_OP 0x71 41bdcaa8d0Smrg#define LW_OP 0x72 42bdcaa8d0Smrg#define LI_OP 0x76 43bdcaa8d0Smrg#define LUI_OP 0x77 44bdcaa8d0Smrg#define SB_OP 0x78 45bdcaa8d0Smrg#define SH_OP 0x79 46bdcaa8d0Smrg#define SW_OP 0x7a 47bdcaa8d0Smrg#define JMP_OP 0x6c 48bdcaa8d0Smrg 49bdcaa8d0Smrg/* defines for instruction composition */ 50bdcaa8d0Smrg#define INT_INSTR(op, d, s2, s1) \ 51bdcaa8d0Smrg (((vu32)(op)<<24) | ((vu32)(d)<<16) | ((vu32)(s2)<<8) | ((vu32)(s1)&0xff)) 52bdcaa8d0Smrg#define STR_INSTR(op, off8, s2, s1) \ 53bdcaa8d0Smrg (((vu32)(op)<<24) | (((vu32)(off8)&0xff)<<16) | ((vu32)(s2)<<8) | ((vu32)(s1))) 54bdcaa8d0Smrg#define LD_INSTR(op, d, off8, s1) \ 55bdcaa8d0Smrg (((vu32)(op)<<24) | ((vu32)(d)<<16) | (((vu32)(off8)&0xff)<<8) | ((vu32)(s1))) 56bdcaa8d0Smrg#define LI_INSTR(op, d, immed16) \ 57bdcaa8d0Smrg (((vu32)(op)<<24) | ((vu32)(d)<<16) | ((vu32)(immed16)&0xffff)) 58bdcaa8d0Smrg#define BR_INSTR(op, off16, s1) \ 59bdcaa8d0Smrg (((vu32)(op)<<24) | (((vu32)(off16)&0xffff)<<8) | ((vu32)(s1))) 60bdcaa8d0Smrg#define JMP_INSTR(op, addr24) \ 61bdcaa8d0Smrg (((vu32)(op)<<24) | ((vu32)(addr24))) 62bdcaa8d0Smrg 63bdcaa8d0Smrg/* some masks */ 64bdcaa8d0Smrg#define TYPEINSTR 0xf0000000 65bdcaa8d0Smrg#define TYPEBRANCH 0x60000000 66bdcaa8d0Smrg#define HALTBIT 0x00000008 67bdcaa8d0Smrg 68bdcaa8d0Smrg#define VBIOS_DTNR 0x2000 69bdcaa8d0Smrg 70bdcaa8d0Smrg#define READ_BYTE 0 71bdcaa8d0Smrg#define READ_SHORT 1 72bdcaa8d0Smrg#define READ_WORD 2 73bdcaa8d0Smrg 74bdcaa8d0Smrg#define WRITE_BYTE 0 75bdcaa8d0Smrg#define WRITE_SHORT 1 76bdcaa8d0Smrg#define WRITE_WORD 2 77bdcaa8d0Smrg 78bdcaa8d0Smrg#define VERITE_MAX_POLLS 100 79bdcaa8d0Smrg 80bdcaa8d0Smrg 81bdcaa8d0Smrg 82bdcaa8d0Smrg/* 83bdcaa8d0Smrg * local function prototypes 84bdcaa8d0Smrg */ 85bdcaa8d0Smrg 86880c7e28Smrgstatic void verite_iopoll(unsigned long port, vu32 data, vu32 mask); 87880c7e28Smrgstatic void verite_iopoll8(unsigned long port, vu8 data, vu8 mask); 88bdcaa8d0Smrg 89880c7e28Smrgstatic vu32 readRF(unsigned long io_base, vu8 index); 90880c7e28Smrgstatic void writeRF(unsigned long io_base, vu8 index, vu32 data); 91bdcaa8d0Smrg 92880c7e28Smrgstatic vu32 risc_readmem(unsigned long io_base, vu32 addr, vu8 read_type); 93880c7e28Smrgstatic void risc_writemem(unsigned long io_base, vu32 addr, vu32 data, vu8 write_type); 94bdcaa8d0Smrg 95bdcaa8d0Smrg#if 0 96880c7e28Smrgstatic void risc_step(unsigned long io_base, vu32 count); 97bdcaa8d0Smrg#endif 98880c7e28Smrgstatic void risc_forcestep(unsigned long io_base, vu32 instruction); 99880c7e28Smrgstatic void risc_continue(unsigned long io_base); 100bdcaa8d0Smrg 101bdcaa8d0Smrg 102bdcaa8d0Smrg 103bdcaa8d0Smrg/* 104bdcaa8d0Smrg * functions 105bdcaa8d0Smrg */ 106bdcaa8d0Smrg 107bdcaa8d0Smrg/* 108bdcaa8d0Smrg * void v1k_start(ScrnInfoPtr pScreenInfo, vu32 pc) 109bdcaa8d0Smrg * 110bdcaa8d0Smrg * Start the RISC with its PC set to |pc|. 111bdcaa8d0Smrg */ 112bdcaa8d0Smrgvoid 113bdcaa8d0Smrgv1k_start(ScrnInfoPtr pScreenInfo, vu32 pc) 114bdcaa8d0Smrg{ 115bdcaa8d0Smrg renditionPtr pRendition = RENDITIONPTR(pScreenInfo); 116880c7e28Smrg unsigned long io_base=pRendition->board.io_base; 117bdcaa8d0Smrg 118bdcaa8d0Smrg v1k_stop(pScreenInfo); 119bdcaa8d0Smrg risc_forcestep(io_base, NOP_INSTR); 120bdcaa8d0Smrg risc_forcestep(io_base, NOP_INSTR); 121bdcaa8d0Smrg risc_forcestep(io_base, NOP_INSTR); 122bdcaa8d0Smrg risc_forcestep(io_base, JMP_INSTR(JMP_OP, pc>>2)); 123bdcaa8d0Smrg risc_forcestep(io_base, NOP_INSTR); 124bdcaa8d0Smrg 125bdcaa8d0Smrg v1k_continue(pScreenInfo); 126bdcaa8d0Smrg} 127bdcaa8d0Smrg 128bdcaa8d0Smrg 129bdcaa8d0Smrg 130bdcaa8d0Smrg/* 131bdcaa8d0Smrg * void v1k_continue(ScrnInfoPtr pScreenInfo) 132bdcaa8d0Smrg * 133bdcaa8d0Smrg * Let the RISC do its work. 134bdcaa8d0Smrg */ 135bdcaa8d0Smrgvoid 136bdcaa8d0Smrgv1k_continue(ScrnInfoPtr pScreenInfo) 137bdcaa8d0Smrg{ 138bdcaa8d0Smrg renditionPtr pRendition = RENDITIONPTR(pScreenInfo); 139bdcaa8d0Smrg 140bdcaa8d0Smrg risc_continue(pRendition->board.io_base); 141bdcaa8d0Smrg} 142bdcaa8d0Smrg 143bdcaa8d0Smrg 144bdcaa8d0Smrg 145bdcaa8d0Smrg/* 146bdcaa8d0Smrg * void v1k_stop(ScrnInfoPtr pScreenInfo) 147bdcaa8d0Smrg * 148bdcaa8d0Smrg * Stop the RISC. 149bdcaa8d0Smrg */ 150bdcaa8d0Smrgvoid 151bdcaa8d0Smrgv1k_stop(ScrnInfoPtr pScreenInfo) 152bdcaa8d0Smrg{ 153bdcaa8d0Smrg renditionPtr pRendition = RENDITIONPTR(pScreenInfo); 154bdcaa8d0Smrg vu8 debugreg, statusreg; 155880c7e28Smrg unsigned long io_base=pRendition->board.io_base; 156bdcaa8d0Smrg vu16 STATUS = 0x4A; /* v2x00 io register offset */ 157bdcaa8d0Smrg int c; 158bdcaa8d0Smrg 159bdcaa8d0Smrg debugreg=verite_in8(io_base+DEBUGREG); 160bdcaa8d0Smrg 161bdcaa8d0Smrg if (pRendition->board.chip == V2000_DEVICE){ 162bdcaa8d0Smrg c=0; 163bdcaa8d0Smrg do { 164bdcaa8d0Smrg/* if(!(c%10000))ErrorF("#S1# !0x%x! -- ",verite_in8(io_base+STATUS)); */ 165bdcaa8d0Smrg statusreg = verite_in8(io_base+STATUS); 166bdcaa8d0Smrg if ((statusreg & 0x8C) == 0x8C) 167bdcaa8d0Smrg break; 168bdcaa8d0Smrg } while (c++<0xfffff); 169bdcaa8d0Smrg if (c >= 0xfffff) 170bdcaa8d0Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 171bdcaa8d0Smrg ("Status timeout (1)\n")); 172bdcaa8d0Smrg 173bdcaa8d0Smrg verite_out8(io_base+DEBUGREG, debugreg|HOLDRISC); 174bdcaa8d0Smrg 175bdcaa8d0Smrg if (pRendition->board.chip == V2000_DEVICE){ 176bdcaa8d0Smrg c=0; 177bdcaa8d0Smrg do { 178bdcaa8d0Smrg/* if(!(c%10000))ErrorF("#S2# !0x%x! -- ",verite_in8(io_base+STATUS)); */ 179bdcaa8d0Smrg statusreg = verite_in8(io_base+STATUS); 180bdcaa8d0Smrg if (statusreg & HOLDRISC) break; 181bdcaa8d0Smrg } while (c++<0xfffff); 182bdcaa8d0Smrg if (c >= 0xfffff) 183bdcaa8d0Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, 184bdcaa8d0Smrg ("Status timeout (2)\n")); 185bdcaa8d0Smrg } 186bdcaa8d0Smrg } 187bdcaa8d0Smrg else { 188bdcaa8d0Smrg /* V1000 stop */ 189bdcaa8d0Smrg verite_out8(io_base+DEBUGREG, debugreg|HOLDRISC); 190bdcaa8d0Smrg 191bdcaa8d0Smrg verite_iopoll(io_base+STATEDATA, 0, 0); /* short pause */ 192bdcaa8d0Smrg verite_iopoll(io_base+STATEDATA, 0, 0); /* short pause */ 193bdcaa8d0Smrg verite_iopoll(io_base+STATEDATA, 0, 0); /* short pause */ 194bdcaa8d0Smrg } 195bdcaa8d0Smrg} 196bdcaa8d0Smrg 197bdcaa8d0Smrg 198bdcaa8d0Smrg 199bdcaa8d0Smrg/* 200bdcaa8d0Smrg * void v1k_flushicache(ScrnInfoPtr pScreenInfo) 201bdcaa8d0Smrg * 202bdcaa8d0Smrg * Returns with Icache on, also flushes Pixel engine line buffers 203bdcaa8d0Smrg * in the Dcache. 204bdcaa8d0Smrg */ 205bdcaa8d0Smrgvoid 206bdcaa8d0Smrgv1k_flushicache(ScrnInfoPtr pScreenInfo) 207bdcaa8d0Smrg{ 208bdcaa8d0Smrg renditionPtr pRendition = RENDITIONPTR(pScreenInfo); 209bdcaa8d0Smrg vu32 c, p1, p2; 210880c7e28Smrg unsigned long io_base=pRendition->board.io_base; 211bdcaa8d0Smrg 212bdcaa8d0Smrg /* first flush store accumulation buffers so data is all in memory */ 213bdcaa8d0Smrg p1=risc_readmem(io_base, 0, READ_WORD); 214bdcaa8d0Smrg p2=risc_readmem(io_base, 8, READ_WORD); 215bdcaa8d0Smrg risc_writemem(io_base, 0, p1, WRITE_WORD); 216bdcaa8d0Smrg risc_writemem(io_base, 8, p2, WRITE_WORD); 217bdcaa8d0Smrg (void)risc_readmem(io_base, 0, READ_WORD); 218bdcaa8d0Smrg (void)risc_readmem(io_base, 8, READ_WORD); 219bdcaa8d0Smrg 220bdcaa8d0Smrg /* now force a spr Sync,zero to cause the pixel engine line buffers 221bdcaa8d0Smrg * to be flushed. */ 222bdcaa8d0Smrg risc_forcestep(io_base, INT_INSTR(SPRI_OP, 0, 0, 31)); /* spri Sync,zero */ 223bdcaa8d0Smrg risc_forcestep(io_base, NOP_INSTR); 224bdcaa8d0Smrg risc_forcestep(io_base, NOP_INSTR); 225bdcaa8d0Smrg risc_forcestep(io_base, NOP_INSTR); 226bdcaa8d0Smrg 227bdcaa8d0Smrg 228bdcaa8d0Smrg writeRF(io_base, RISC_RA, ICACHE_ONOFF_MASK); /* load mask */ 229bdcaa8d0Smrg /* set bits */ 230bdcaa8d0Smrg risc_forcestep(io_base, INT_INSTR(OR_OP, RISC_FLAG, RISC_FLAG, RISC_RA)); 231bdcaa8d0Smrg risc_forcestep(io_base, NOP_INSTR); /* clear hazard */ 232bdcaa8d0Smrg risc_forcestep(io_base, NOP_INSTR); 233bdcaa8d0Smrg risc_forcestep(io_base, NOP_INSTR); 234bdcaa8d0Smrg 235bdcaa8d0Smrg /* flush ICache */ 236bdcaa8d0Smrg for (c=0; c<ICACHESIZE*2; c+=ICACHELINESIZE) 237bdcaa8d0Smrg risc_forcestep(io_base, JMP_INSTR(JMP_OP, c>>2)); /* jmp NextCacheLine. */ 238bdcaa8d0Smrg 239bdcaa8d0Smrg writeRF(io_base, RISC_RA, ICACHE_ONOFF_MASK); /* load mask */ 240bdcaa8d0Smrg /* clear bits */ 241bdcaa8d0Smrg risc_forcestep(io_base, INT_INSTR(ANDN_OP, RISC_FLAG, RISC_FLAG, RISC_RA)); 242bdcaa8d0Smrg risc_forcestep(io_base, NOP_INSTR); /* jump back to PC=0 */ 243bdcaa8d0Smrg risc_forcestep(io_base, JMP_INSTR(JMP_OP, 0)); 244bdcaa8d0Smrg risc_forcestep(io_base, NOP_INSTR); 245bdcaa8d0Smrg} 246bdcaa8d0Smrg 247bdcaa8d0Smrg 248bdcaa8d0Smrg 249bdcaa8d0Smrg/* 250bdcaa8d0Smrg * void v1k_softreset(ScrnInfoPtr pScreenInfo) 251bdcaa8d0Smrg * 252bdcaa8d0Smrg * Soft Reset RISC. 253bdcaa8d0Smrg */ 254bdcaa8d0Smrgvoid 255bdcaa8d0Smrgv1k_softreset(ScrnInfoPtr pScreenInfo) 256bdcaa8d0Smrg{ 257bdcaa8d0Smrg renditionPtr pRendition = RENDITIONPTR(pScreenInfo); 258880c7e28Smrg unsigned long io_base=pRendition->board.io_base; 259bdcaa8d0Smrg 260bdcaa8d0Smrg verite_out8(io_base+DEBUGREG, SOFTRESET|HOLDRISC); 261bdcaa8d0Smrg verite_out8(io_base+STATEINDEX, STATEINDEX_PC); 262bdcaa8d0Smrg verite_iopoll(io_base+STATEDATA, 0, 0xffffffff); 263bdcaa8d0Smrg verite_iopoll(io_base+STATEDATA, 0, 0xffffffff); 264bdcaa8d0Smrg verite_iopoll(io_base+STATEDATA, 0, 0xffffffff); 265bdcaa8d0Smrg 266bdcaa8d0Smrg verite_out8(io_base+DEBUGREG, HOLDRISC); 267bdcaa8d0Smrg verite_iopoll(io_base+STATEDATA, 0, 0); 268bdcaa8d0Smrg verite_iopoll(io_base+STATEDATA, 0, 0); 269bdcaa8d0Smrg verite_iopoll(io_base+STATEDATA, 0, 0); 270bdcaa8d0Smrg 271bdcaa8d0Smrg /* turn icache on */ 272bdcaa8d0Smrg risc_forcestep(io_base, LI_INSTR(LI_OP, RISC_RA, ICACHE_ONOFF_MASK&0xffff)); 273bdcaa8d0Smrg risc_forcestep(io_base, INT_INSTR(ADDIFI_OP, RISC_FLAG, RISC_RA, 274bdcaa8d0Smrg ICACHE_ONOFF_MASK>>16)); 275bdcaa8d0Smrg /* clear any interrupts */ 276bdcaa8d0Smrg verite_out8(io_base+INTR, 0xff); 277bdcaa8d0Smrg /* byte swap mode=word */ 278bdcaa8d0Smrg verite_out8(io_base+MEMENDIAN, MEMENDIAN_NO); 279bdcaa8d0Smrg} 280bdcaa8d0Smrg 281bdcaa8d0Smrg 282bdcaa8d0Smrg 283bdcaa8d0Smrg/* 284bdcaa8d0Smrgvoid 285bdcaa8d0Smrgv1k_getriscprocs(verite_board_desc *boardDesc) 286bdcaa8d0Smrg{ 287bdcaa8d0Smrg boardDesc->risc_procs.risc_softreset = v1krisc_softreset; 288bdcaa8d0Smrg boardDesc->risc_procs.risc_flushicache = v1krisc_flushicache; 289bdcaa8d0Smrg boardDesc->risc_procs.risc_start = v1krisc_start; 290bdcaa8d0Smrg boardDesc->risc_procs.risc_stop = v1krisc_stop; 291bdcaa8d0Smrg boardDesc->risc_procs.risc_continue = v1krisc_continue; 292bdcaa8d0Smrg return; 293bdcaa8d0Smrg} 294bdcaa8d0Smrg*/ 295bdcaa8d0Smrg 296bdcaa8d0Smrg 297bdcaa8d0Smrg 298bdcaa8d0Smrg/* 299bdcaa8d0Smrg * local functions 300bdcaa8d0Smrg */ 301bdcaa8d0Smrg 302bdcaa8d0Smrg/* 303880c7e28Smrg * static void verite_iopoll(unsigned long port, vu32 data, vu32 mask) 304bdcaa8d0Smrg * 305bdcaa8d0Smrg * Loop on IO read until expected data is read or VERITE_MAX_POLLS is reached. 306bdcaa8d0Smrg */ 307bdcaa8d0Smrgstatic void 308880c7e28Smrgverite_iopoll(unsigned long port, vu32 data, vu32 mask) 309bdcaa8d0Smrg{ 310bdcaa8d0Smrg vu32 c; 311bdcaa8d0Smrg 312bdcaa8d0Smrg c=0; 313bdcaa8d0Smrg do { 314bdcaa8d0Smrg c++; 315bdcaa8d0Smrg if ((verite_in32(port)&mask) == (data&mask)) 316bdcaa8d0Smrg break; 317bdcaa8d0Smrg } while (c <= VERITE_MAX_POLLS); 318bdcaa8d0Smrg} 319bdcaa8d0Smrg 320bdcaa8d0Smrg 321bdcaa8d0Smrg 322bdcaa8d0Smrg/* 323880c7e28Smrg * static void verite_iopoll8(unsigned long port, vu8 data, vu8 mask) 324bdcaa8d0Smrg * 325bdcaa8d0Smrg * Loop on IO read until expected data is read or VERITE_MAX_POLLS is reached. 326bdcaa8d0Smrg */ 327bdcaa8d0Smrgstatic void 328880c7e28Smrgverite_iopoll8(unsigned long port, vu8 data, vu8 mask) 329bdcaa8d0Smrg{ 330bdcaa8d0Smrg vu32 c; 331bdcaa8d0Smrg 332bdcaa8d0Smrg c=0; 333bdcaa8d0Smrg do { 334bdcaa8d0Smrg c++; 335bdcaa8d0Smrg if ((verite_in8(port)&mask) == (data&mask)) 336bdcaa8d0Smrg break; 337bdcaa8d0Smrg } while (c <= VERITE_MAX_POLLS); 338bdcaa8d0Smrg} 339bdcaa8d0Smrg 340bdcaa8d0Smrg 341bdcaa8d0Smrg 342bdcaa8d0Smrg/* 343880c7e28Smrg * static vu32 readRF(unsigned long io_base, vu8 index) 344bdcaa8d0Smrg * 345bdcaa8d0Smrg * Reads data from register file. 346bdcaa8d0Smrg */ 347bdcaa8d0Smrgstatic vu32 348880c7e28SmrgreadRF(unsigned long io_base, vu8 index) 349bdcaa8d0Smrg{ 350bdcaa8d0Smrg vu32 data, instr; 351bdcaa8d0Smrg vu8 debug, stateindex; 352bdcaa8d0Smrg 353bdcaa8d0Smrg debug=verite_in8(io_base+DEBUGREG); 354bdcaa8d0Smrg stateindex=verite_in8(io_base+STATEINDEX); 355bdcaa8d0Smrg 356bdcaa8d0Smrg /* force RISC instruction: add zero,zero,index 357bdcaa8d0Smrg * S1 reg address = reg index to read 358bdcaa8d0Smrg * write to the DEC_IR, but no need to step it! */ 359bdcaa8d0Smrg verite_out8(io_base+DEBUGREG, debug|HOLDRISC); 360bdcaa8d0Smrg 361bdcaa8d0Smrg instr=INT_INSTR(ADD_OP, 0, 0, index); 362bdcaa8d0Smrg verite_out32(io_base+STATEDATA, instr); 363bdcaa8d0Smrg 364bdcaa8d0Smrg /* wait for instruction to get to RISC IR. */ 365bdcaa8d0Smrg verite_out8(io_base+STATEINDEX, STATEINDEX_IR); /* point at DEC_IR */ 366bdcaa8d0Smrg verite_iopoll(io_base+STATEDATA, instr, 0xffffffff); 367bdcaa8d0Smrg 368bdcaa8d0Smrg verite_out8(io_base+STATEINDEX, STATEINDEX_S1); /* point at RISCS1 */ 369bdcaa8d0Smrg verite_iopoll(io_base+STATEINDEX, 0, 0); /* short pause */ 370bdcaa8d0Smrg data=verite_in32(io_base+STATEDATA); /* read RF */ 371bdcaa8d0Smrg 372bdcaa8d0Smrg verite_out8(io_base+STATEINDEX, stateindex); /* restore state_index */ 373bdcaa8d0Smrg verite_out8(io_base+DEBUGREG, debug); /* restore debug */ 374bdcaa8d0Smrg 375bdcaa8d0Smrg return data; 376bdcaa8d0Smrg} 377bdcaa8d0Smrg 378bdcaa8d0Smrg 379bdcaa8d0Smrg 380bdcaa8d0Smrg/* 381880c7e28Smrg * static void writeRF(unsigned long io_base, vu8 index, vu32 data) 382bdcaa8d0Smrg * 383bdcaa8d0Smrg * Set RF register, being careful on how to set regs below 64. 384bdcaa8d0Smrg */ 385bdcaa8d0Smrgstatic void 386880c7e28SmrgwriteRF(unsigned long io_base, vu8 index, vu32 data) 387bdcaa8d0Smrg{ 388bdcaa8d0Smrg vu8 special=0; 389bdcaa8d0Smrg 390bdcaa8d0Smrg if (index < 64) { /* constants or HW regs */ 391bdcaa8d0Smrg special=index; /* keep track of special register */ 392bdcaa8d0Smrg index=RISC_SP; /* use |sp| as tmp, since it gets restored */ 393bdcaa8d0Smrg } 394bdcaa8d0Smrg 395bdcaa8d0Smrg if (!(data & 0xff000000)) { /* only 16 or 24 LSBs */ 396bdcaa8d0Smrg /* Set 16 LS bits. */ 397bdcaa8d0Smrg risc_forcestep(io_base, LI_INSTR(LI_OP,index,data&0xffff)); 398bdcaa8d0Smrg if (data & 0x00ff0000) /* need all 24 LS bits? */ 399bdcaa8d0Smrg risc_forcestep(io_base, INT_INSTR(ADDIFI_OP,index,index,data>>16) ); 400bdcaa8d0Smrg } 401bdcaa8d0Smrg else { /* else, do all 32 bits */ 402bdcaa8d0Smrg risc_forcestep(io_base, LI_INSTR(LUI_OP, index, data>>16)); 403bdcaa8d0Smrg risc_forcestep(io_base, INT_INSTR(ADDSL8_OP, index, index, (data>>8)&0xff)); 404bdcaa8d0Smrg risc_forcestep(io_base, INT_INSTR(ADDI_OP, index, index, data&0xff)); 405bdcaa8d0Smrg } 406bdcaa8d0Smrg 407bdcaa8d0Smrg if (special) { 408bdcaa8d0Smrg /* move data to special register */ 409bdcaa8d0Smrg risc_forcestep(io_base, INT_INSTR(ADD_OP, special, 0, RISC_SP)); 410bdcaa8d0Smrg /* clear hazard */ 411bdcaa8d0Smrg risc_forcestep(io_base, NOP_INSTR); 412bdcaa8d0Smrg risc_forcestep(io_base, NOP_INSTR); 413bdcaa8d0Smrg risc_forcestep(io_base, NOP_INSTR); 414bdcaa8d0Smrg } 415bdcaa8d0Smrg} 416bdcaa8d0Smrg 417bdcaa8d0Smrg 418bdcaa8d0Smrg 419bdcaa8d0Smrg/* 420880c7e28Smrg * static vu32 risc_readmem(unsigned long io_base, vu32 addr, vu8 read_type) 421bdcaa8d0Smrg * 422bdcaa8d0Smrg * NOTE: Assumes RISC is in hold mode. 423bdcaa8d0Smrg */ 424bdcaa8d0Smrgstatic vu32 425880c7e28Smrgrisc_readmem(unsigned long io_base, vu32 addr, vu8 read_type) 426bdcaa8d0Smrg{ 427bdcaa8d0Smrg vu32 data; 428bdcaa8d0Smrg 429bdcaa8d0Smrg writeRF(io_base, RISC_RA, addr); /* point to memory */ 430bdcaa8d0Smrg if (READ_BYTE == read_type) /* read memory */ 431bdcaa8d0Smrg risc_forcestep(io_base, LD_INSTR(LB_OP, RISC_SP, 0, RISC_RA)); 432bdcaa8d0Smrg else 433bdcaa8d0Smrg if (READ_SHORT == read_type) 434bdcaa8d0Smrg risc_forcestep(io_base, LD_INSTR(LH_OP, RISC_SP, 0, RISC_RA)); 435bdcaa8d0Smrg else 436bdcaa8d0Smrg risc_forcestep(io_base, LD_INSTR(LW_OP, RISC_SP, 0, RISC_RA)); 437bdcaa8d0Smrg 438bdcaa8d0Smrg risc_forcestep(io_base, NOP_INSTR); /* need nop's */ 439bdcaa8d0Smrg risc_forcestep(io_base, NOP_INSTR); /* need nop's */ 440bdcaa8d0Smrg data=readRF(io_base, RISC_SP); /* get data */ 441bdcaa8d0Smrg 442bdcaa8d0Smrg return data; 443bdcaa8d0Smrg} 444bdcaa8d0Smrg 445bdcaa8d0Smrg 446bdcaa8d0Smrg 447bdcaa8d0Smrg/* 448880c7e28Smrg * static vu32 risc_writemem(unsigned long io_base, vu32 addr, vu32 data, vu8 write_type) 449bdcaa8d0Smrg * 450bdcaa8d0Smrg * NOTE: Assumes RISC is in hold mode. 451bdcaa8d0Smrg */ 452bdcaa8d0Smrgstatic void 453880c7e28Smrgrisc_writemem(unsigned long io_base, vu32 addr, vu32 data, vu8 write_type) 454bdcaa8d0Smrg{ 455bdcaa8d0Smrg writeRF(io_base, RISC_RA, addr); /* point to memory */ 456bdcaa8d0Smrg writeRF(io_base, RISC_FP, data); /* set data */ 457bdcaa8d0Smrg if (WRITE_BYTE == write_type) /* write memory */ 458bdcaa8d0Smrg risc_forcestep(io_base, STR_INSTR(SB_OP, 0, RISC_FP, RISC_RA)); 459bdcaa8d0Smrg else 460bdcaa8d0Smrg if (WRITE_SHORT == write_type) 461bdcaa8d0Smrg risc_forcestep(io_base, STR_INSTR(SH_OP, 0, RISC_FP, RISC_RA)); 462bdcaa8d0Smrg else 463bdcaa8d0Smrg risc_forcestep(io_base, STR_INSTR(SW_OP, 0, RISC_FP, RISC_RA)); 464bdcaa8d0Smrg} 465bdcaa8d0Smrg 466bdcaa8d0Smrg 467bdcaa8d0Smrg#if 0 468bdcaa8d0Smrg/* 469880c7e28Smrg * static void risc_step(unsigned long io_base, vu32 count) 470bdcaa8d0Smrg * 471bdcaa8d0Smrg * Single step the RISC. NOTE: Do not force instruction into RISCIR! 472bdcaa8d0Smrg */ 473bdcaa8d0Smrgstatic void 474880c7e28Smrgrisc_step(unsigned long io_base, vu32 count) 475bdcaa8d0Smrg{ 476bdcaa8d0Smrg vu32 c, d; 477bdcaa8d0Smrg vu8 debugreg; 478bdcaa8d0Smrg 479bdcaa8d0Smrg /* RISC is already held; just single step it */ 480bdcaa8d0Smrg 481bdcaa8d0Smrg for (c=0; c<count; c++) { 482bdcaa8d0Smrg debugreg=verite_in8(io_base+DEBUGREG); 483bdcaa8d0Smrg verite_out8(io_base+DEBUGREG, debugreg|STEPRISC); 484bdcaa8d0Smrg 485bdcaa8d0Smrg for (d=0; d<1000; d++) 486bdcaa8d0Smrg if(0 == (verite_in8(io_base+DEBUGREG)&STEPRISC)) 487bdcaa8d0Smrg break; 488bdcaa8d0Smrg 489bdcaa8d0Smrg if (1000 == d) 490bdcaa8d0Smrg return; /* stall occurred, we're done */ 491bdcaa8d0Smrg } 492bdcaa8d0Smrg} 493bdcaa8d0Smrg#endif 494bdcaa8d0Smrg 495bdcaa8d0Smrg 496bdcaa8d0Smrg/* 497880c7e28Smrg * static void risc_forcestep(unsigned long io_base, vu32 instruction) 498bdcaa8d0Smrg * 499bdcaa8d0Smrg * Single step RISC; force instruction; assumes RISC held. 500bdcaa8d0Smrg */ 501bdcaa8d0Smrgstatic void 502880c7e28Smrgrisc_forcestep(unsigned long io_base, vu32 instruction) 503bdcaa8d0Smrg{ 504bdcaa8d0Smrg vu32 c; 505bdcaa8d0Smrg vu8 debugreg, stateindex; 506bdcaa8d0Smrg 507bdcaa8d0Smrg 508bdcaa8d0Smrg debugreg=verite_in8(io_base+DEBUGREG); 509bdcaa8d0Smrg stateindex=verite_in8(io_base+STATEINDEX); 510bdcaa8d0Smrg verite_out8(io_base+STATEINDEX, STATEINDEX_IR); 511bdcaa8d0Smrg verite_iopoll8(io_base+STATEINDEX, STATEINDEX_IR, 0xff); /* wait */ 512bdcaa8d0Smrg verite_out32(io_base+STATEDATA, instruction); /* load instruction */ 513bdcaa8d0Smrg verite_iopoll(io_base+STATEDATA, instruction, 0xffffffff); /* wait */ 514bdcaa8d0Smrg verite_out8(io_base+DEBUGREG, debugreg|HOLDRISC|STEPRISC); /* step */ 515bdcaa8d0Smrg verite_iopoll(io_base+STATEDATA, 0, 0); /* short pause */ 516bdcaa8d0Smrg 517bdcaa8d0Smrg for (c=0; c<VERITE_MAX_POLLS; c++) 518bdcaa8d0Smrg if (HOLDRISC == (verite_in8(io_base+DEBUGREG) & (HOLDRISC|STEPRISC))) 519bdcaa8d0Smrg break; 520bdcaa8d0Smrg 521bdcaa8d0Smrg /* restore */ 522bdcaa8d0Smrg verite_out8(io_base+STATEINDEX, stateindex); 523bdcaa8d0Smrg} 524bdcaa8d0Smrg 525bdcaa8d0Smrg 526bdcaa8d0Smrg 527bdcaa8d0Smrg/* 528880c7e28Smrg * static void risc_continue(unsigned long io_base) 529bdcaa8d0Smrg * 530bdcaa8d0Smrg * Turn off hold bit. 531bdcaa8d0Smrg */ 532bdcaa8d0Smrgstatic void 533880c7e28Smrgrisc_continue(unsigned long io_base) 534bdcaa8d0Smrg{ 535bdcaa8d0Smrg vu8 debugreg; 536bdcaa8d0Smrg 537bdcaa8d0Smrg debugreg=verite_in8(io_base+DEBUGREG); 538bdcaa8d0Smrg verite_out8(io_base+DEBUGREG, debugreg&(~HOLDRISC)); 539bdcaa8d0Smrg verite_iopoll(io_base+STATEDATA, 0, 0); /* short pause */ 540bdcaa8d0Smrg} 541bdcaa8d0Smrg 542bdcaa8d0Smrg 543bdcaa8d0Smrg 544bdcaa8d0Smrg/* 545bdcaa8d0Smrg * end of file v1krisc.c 546bdcaa8d0Smrg */ 547