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