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