1/*  arminit.c -- ARMulator initialization:  ARM6 Instruction Emulator.
2    Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
17
18#include <string.h>
19
20#include "armdefs.h"
21#include "armemu.h"
22#include "dbg_rdi.h"
23
24/***************************************************************************\
25*                 Definitions for the emulator architecture                 *
26\***************************************************************************/
27
28void ARMul_EmulateInit (void);
29ARMul_State *ARMul_NewState (void);
30void ARMul_Reset (ARMul_State * state);
31ARMword ARMul_DoCycle (ARMul_State * state);
32unsigned ARMul_DoCoPro (ARMul_State * state);
33ARMword ARMul_DoProg (ARMul_State * state);
34ARMword ARMul_DoInstr (ARMul_State * state);
35void ARMul_Abort (ARMul_State * state, ARMword address);
36
37unsigned ARMul_MultTable[32] =
38  { 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
39  10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16
40};
41ARMword ARMul_ImmedTable[4096];	/* immediate DP LHS values */
42char ARMul_BitList[256];	/* number of bits in a byte table */
43
44/***************************************************************************\
45*         Call this routine once to set up the emulator's tables.           *
46\***************************************************************************/
47
48void
49ARMul_EmulateInit (void)
50{
51  unsigned long i, j;
52
53  for (i = 0; i < 4096; i++)
54    {				/* the values of 12 bit dp rhs's */
55      ARMul_ImmedTable[i] = ROTATER (i & 0xffL, (i >> 7L) & 0x1eL);
56    }
57
58  for (i = 0; i < 256; ARMul_BitList[i++] = 0);	/* how many bits in LSM */
59  for (j = 1; j < 256; j <<= 1)
60    for (i = 0; i < 256; i++)
61      if ((i & j) > 0)
62	ARMul_BitList[i]++;
63
64  for (i = 0; i < 256; i++)
65    ARMul_BitList[i] *= 4;	/* you always need 4 times these values */
66
67}
68
69/***************************************************************************\
70*            Returns a new instantiation of the ARMulator's state           *
71\***************************************************************************/
72
73ARMul_State *
74ARMul_NewState (void)
75{
76  ARMul_State *state;
77  unsigned i, j;
78
79  state = (ARMul_State *) malloc (sizeof (ARMul_State));
80  memset (state, 0, sizeof (ARMul_State));
81
82  state->Emulate = RUN;
83  for (i = 0; i < 16; i++)
84    {
85      state->Reg[i] = 0;
86      for (j = 0; j < 7; j++)
87	state->RegBank[j][i] = 0;
88    }
89  for (i = 0; i < 7; i++)
90    state->Spsr[i] = 0;
91
92  /* state->Mode = USER26MODE;  */
93  state->Mode = USER32MODE;
94
95  state->CallDebug = FALSE;
96  state->Debug = FALSE;
97  state->VectorCatch = 0;
98  state->Aborted = FALSE;
99  state->Reseted = FALSE;
100  state->Inted = 3;
101  state->LastInted = 3;
102
103  state->MemDataPtr = NULL;
104  state->MemInPtr = NULL;
105  state->MemOutPtr = NULL;
106  state->MemSparePtr = NULL;
107  state->MemSize = 0;
108
109  state->OSptr = NULL;
110  state->CommandLine = NULL;
111
112  state->CP14R0_CCD = -1;
113  state->LastTime = 0;
114
115  state->EventSet = 0;
116  state->Now = 0;
117  state->EventPtr = (struct EventNode **) malloc ((unsigned) EVENTLISTSIZE *
118						  sizeof (struct EventNode
119							  *));
120  for (i = 0; i < EVENTLISTSIZE; i++)
121    *(state->EventPtr + i) = NULL;
122
123  state->prog32Sig = HIGH;
124  state->data32Sig = HIGH;
125
126  state->lateabtSig = LOW;
127  state->bigendSig = LOW;
128
129  state->is_v4 = LOW;
130  state->is_v5 = LOW;
131  state->is_v5e = LOW;
132  state->is_XScale = LOW;
133  state->is_iWMMXt = LOW;
134  state->is_v6 = LOW;
135
136  ARMul_Reset (state);
137
138  return state;
139}
140
141/***************************************************************************\
142  Call this routine to set ARMulator to model certain processor properities
143\***************************************************************************/
144
145void
146ARMul_SelectProcessor (ARMul_State * state, unsigned properties)
147{
148  if (properties & ARM_Fix26_Prop)
149    {
150      state->prog32Sig = LOW;
151      state->data32Sig = LOW;
152    }
153  else
154    {
155      state->prog32Sig = HIGH;
156      state->data32Sig = HIGH;
157    }
158
159  state->lateabtSig = LOW;
160
161  state->is_v4 = (properties & (ARM_v4_Prop | ARM_v5_Prop)) ? HIGH : LOW;
162  state->is_v5 = (properties & ARM_v5_Prop) ? HIGH : LOW;
163  state->is_v5e = (properties & ARM_v5e_Prop) ? HIGH : LOW;
164  state->is_XScale = (properties & ARM_XScale_Prop) ? HIGH : LOW;
165  state->is_iWMMXt = (properties & ARM_iWMMXt_Prop) ? HIGH : LOW;
166  state->is_ep9312 = (properties & ARM_ep9312_Prop) ? HIGH : LOW;
167  state->is_v6 = (properties & ARM_v6_Prop) ? HIGH : LOW;
168
169  /* Only initialse the coprocessor support once we
170     know what kind of chip we are dealing with.  */
171  ARMul_CoProInit (state);
172}
173
174/***************************************************************************\
175* Call this routine to set up the initial machine state (or perform a RESET *
176\***************************************************************************/
177
178void
179ARMul_Reset (ARMul_State * state)
180{
181  state->NextInstr = 0;
182
183  if (state->prog32Sig)
184    {
185      state->Reg[15] = 0;
186      state->Cpsr = INTBITS | SVC32MODE;
187      state->Mode = SVC32MODE;
188    }
189  else
190    {
191      state->Reg[15] = R15INTBITS | SVC26MODE;
192      state->Cpsr = INTBITS | SVC26MODE;
193      state->Mode = SVC26MODE;
194    }
195
196  ARMul_CPSRAltered (state);
197  state->Bank = SVCBANK;
198
199  FLUSHPIPE;
200
201  state->EndCondition = 0;
202  state->ErrorCode = 0;
203
204  state->Exception = FALSE;
205  state->NresetSig = HIGH;
206  state->NfiqSig = HIGH;
207  state->NirqSig = HIGH;
208  state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
209  state->abortSig = LOW;
210  state->AbortAddr = 1;
211
212  state->NumInstrs = 0;
213  state->NumNcycles = 0;
214  state->NumScycles = 0;
215  state->NumIcycles = 0;
216  state->NumCcycles = 0;
217  state->NumFcycles = 0;
218#ifdef ASIM
219  (void) ARMul_MemoryInit ();
220  ARMul_OSInit (state);
221#endif
222}
223
224
225/***************************************************************************\
226* Emulate the execution of an entire program.  Start the correct emulator   *
227* (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the   *
228* address of the last instruction that is executed.                         *
229\***************************************************************************/
230
231ARMword
232ARMul_DoProg (ARMul_State * state)
233{
234  ARMword pc = 0;
235
236  state->Emulate = RUN;
237  while (state->Emulate != STOP)
238    {
239      state->Emulate = RUN;
240      if (state->prog32Sig && ARMul_MODE32BIT)
241	pc = ARMul_Emulate32 (state);
242      else
243	pc = ARMul_Emulate26 (state);
244    }
245  return (pc);
246}
247
248/***************************************************************************\
249* Emulate the execution of one instruction.  Start the correct emulator     *
250* (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the   *
251* address of the instruction that is executed.                              *
252\***************************************************************************/
253
254ARMword
255ARMul_DoInstr (ARMul_State * state)
256{
257  ARMword pc = 0;
258
259  state->Emulate = ONCE;
260  if (state->prog32Sig && ARMul_MODE32BIT)
261    pc = ARMul_Emulate32 (state);
262  else
263    pc = ARMul_Emulate26 (state);
264
265  return (pc);
266}
267
268/***************************************************************************\
269* This routine causes an Abort to occur, including selecting the correct    *
270* mode, register bank, and the saving of registers.  Call with the          *
271* appropriate vector's memory address (0,4,8 ....)                          *
272\***************************************************************************/
273
274void
275ARMul_Abort (ARMul_State * state, ARMword vector)
276{
277  ARMword temp;
278  int isize = INSN_SIZE;
279  int esize = (TFLAG ? 0 : 4);
280  int e2size = (TFLAG ? -4 : 0);
281
282  state->Aborted = FALSE;
283
284  if (ARMul_OSException (state, vector, ARMul_GetPC (state)))
285    return;
286
287  if (state->prog32Sig)
288    if (ARMul_MODE26BIT)
289      temp = R15PC;
290    else
291      temp = state->Reg[15];
292  else
293    temp = R15PC | ECC | ER15INT | EMODE;
294
295  switch (vector)
296    {
297    case ARMul_ResetV:		/* RESET */
298      SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE, 0);
299      break;
300    case ARMul_UndefinedInstrV:	/* Undefined Instruction */
301      SETABORT (IBIT, state->prog32Sig ? UNDEF32MODE : SVC26MODE, isize);
302      break;
303    case ARMul_SWIV:		/* Software Interrupt */
304      SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE, isize);
305      break;
306    case ARMul_PrefetchAbortV:	/* Prefetch Abort */
307      state->AbortAddr = 1;
308      SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE, esize);
309      break;
310    case ARMul_DataAbortV:	/* Data Abort */
311      SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE, e2size);
312      break;
313    case ARMul_AddrExceptnV:	/* Address Exception */
314      SETABORT (IBIT, SVC26MODE, isize);
315      break;
316    case ARMul_IRQV:		/* IRQ */
317      if (   ! state->is_XScale
318	  || ! state->CPRead[13] (state, 0, & temp)
319	  || (temp & ARMul_CP13_R0_IRQ))
320        SETABORT (IBIT, state->prog32Sig ? IRQ32MODE : IRQ26MODE, esize);
321      break;
322    case ARMul_FIQV:		/* FIQ */
323      if (   ! state->is_XScale
324	  || ! state->CPRead[13] (state, 0, & temp)
325	  || (temp & ARMul_CP13_R0_FIQ))
326        SETABORT (INTBITS, state->prog32Sig ? FIQ32MODE : FIQ26MODE, esize);
327      break;
328    }
329  if (ARMul_MODE32BIT)
330    ARMul_SetR15 (state, vector);
331  else
332    ARMul_SetR15 (state, R15CCINTMODE | vector);
333
334  if (ARMul_ReadWord (state, ARMul_GetPC (state)) == 0)
335    {
336      /* No vector has been installed.  Rather than simulating whatever
337	 random bits might happen to be at address 0x20 onwards we elect
338	 to stop.  */
339      switch (vector)
340	{
341	case ARMul_ResetV: state->EndCondition = RDIError_Reset; break;
342	case ARMul_UndefinedInstrV: state->EndCondition = RDIError_UndefinedInstruction; break;
343	case ARMul_SWIV: state->EndCondition = RDIError_SoftwareInterrupt; break;
344	case ARMul_PrefetchAbortV: state->EndCondition = RDIError_PrefetchAbort; break;
345	case ARMul_DataAbortV: state->EndCondition = RDIError_DataAbort; break;
346	case ARMul_AddrExceptnV: state->EndCondition = RDIError_AddressException; break;
347	case ARMul_IRQV: state->EndCondition = RDIError_IRQ; break;
348	case ARMul_FIQV: state->EndCondition = RDIError_FIQ; break;
349	default: break;
350	}
351      state->Emulate = FALSE;
352    }
353}
354