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