1 /* Simulator for the moxie processor
2    Copyright (C) 2008-2024 Free Software Foundation, Inc.
3    Contributed by Anthony Green
4 
5 This file is part of GDB, the GNU debugger.
6 
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 /* This must come before any other includes.  */
21 #include "defs.h"
22 
23 #include <fcntl.h>
24 #include <signal.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/param.h>
28 #include <unistd.h>
29 #include "bfd.h"
30 #include "libiberty.h"
31 #include "sim/sim.h"
32 
33 #include "sim-main.h"
34 #include "sim-base.h"
35 #include "sim-options.h"
36 #include "sim-io.h"
37 #include "sim-signal.h"
38 #include "target-newlib-syscall.h"
39 
40 #include "moxie-sim.h"
41 
42 /* Extract the signed 10-bit offset from a 16-bit branch
43    instruction.  */
44 #define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
45 
46 #define EXTRACT_WORD(addr) \
47   ((sim_core_read_aligned_1 (scpu, cia, read_map, addr) << 24) \
48    + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+1) << 16) \
49    + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+2) << 8) \
50    + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+3)))
51 
52 #define EXTRACT_OFFSET(addr)                                                    \
53   (unsigned int)                                                                \
54   (((signed short)                                                              \
55     ((sim_core_read_aligned_1 (scpu, cia, read_map, addr) << 8)                 \
56      + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+1))) << 16) >> 16)
57 
58 static unsigned long
moxie_extract_unsigned_integer(const unsigned char * addr,int len)59 moxie_extract_unsigned_integer (const unsigned char *addr, int len)
60 {
61   unsigned long retval;
62   unsigned char * p;
63   unsigned char * startaddr = (unsigned char *)addr;
64   unsigned char * endaddr = startaddr + len;
65 
66   if (len > (int) sizeof (unsigned long))
67     printf ("That operation is not available on integers of more than %zu bytes.",
68               sizeof (unsigned long));
69 
70   /* Start at the most significant end of the integer, and work towards
71      the least significant.  */
72   retval = 0;
73 
74   for (p = endaddr; p > startaddr;)
75     retval = (retval << 8) | * -- p;
76 
77   return retval;
78 }
79 
80 static void
moxie_store_unsigned_integer(unsigned char * addr,int len,unsigned long val)81 moxie_store_unsigned_integer (unsigned char *addr, int len, unsigned long val)
82 {
83   unsigned char * p;
84   unsigned char * startaddr = (unsigned char *)addr;
85   unsigned char * endaddr = startaddr + len;
86 
87   for (p = endaddr; p > startaddr;)
88     {
89       * -- p = val & 0xff;
90       val >>= 8;
91     }
92 }
93 
94 /* The machine state.
95 
96    This state is maintained in host byte order.  The fetch/store
97    register functions must translate between host byte order and the
98    target processor byte order.  Keeping this data in target byte
99    order simplifies the register read/write functions.  Keeping this
100    data in native order improves the performance of the simulator.
101    Simulation speed is deemed more important.  */
102 
103 #define NUM_MOXIE_REGS 17 /* Including PC */
104 #define NUM_MOXIE_SREGS 256 /* The special registers */
105 #define PC_REGNO     16
106 
107 /* The ordering of the moxie_regset structure is matched in the
108    gdb/config/moxie/tm-moxie.h file in the REGISTER_NAMES macro.  */
109 /* TODO: This should be moved to sim-main.h:_sim_cpu.  */
110 struct moxie_regset
111 {
112   int32_t      regs[NUM_MOXIE_REGS + 1]; /* primary registers */
113   int32_t      sregs[256];           /* special registers */
114   int32_t      cc;                   /* the condition code reg */
115   unsigned long long insts;                /* instruction counter */
116 };
117 
118 #define CC_GT  1<<0
119 #define CC_LT  1<<1
120 #define CC_EQ  1<<2
121 #define CC_GTU 1<<3
122 #define CC_LTU 1<<4
123 
124 /* TODO: This should be moved to sim-main.h:moxie_sim_cpu.  */
125 union
126 {
127   struct moxie_regset asregs;
128   int32_t asints [1];                   /* but accessed larger... */
129 } cpu;
130 
131 static void
set_initial_gprs(void)132 set_initial_gprs (void)
133 {
134   int i;
135 
136   /* Set up machine just out of reset.  */
137   cpu.asregs.regs[PC_REGNO] = 0;
138 
139   /* Clean out the register contents.  */
140   for (i = 0; i < NUM_MOXIE_REGS; i++)
141     cpu.asregs.regs[i] = 0;
142   for (i = 0; i < NUM_MOXIE_SREGS; i++)
143     cpu.asregs.sregs[i] = 0;
144 }
145 
146 /* Write a 1 byte value to memory.  */
147 
148 static INLINE void
wbat(sim_cpu * scpu,int32_t pc,int32_t x,int32_t v)149 wbat (sim_cpu *scpu, int32_t pc, int32_t x, int32_t v)
150 {
151   address_word cia = CPU_PC_GET (scpu);
152 
153   sim_core_write_aligned_1 (scpu, cia, write_map, x, v);
154 }
155 
156 /* Write a 2 byte value to memory.  */
157 
158 static INLINE void
wsat(sim_cpu * scpu,int32_t pc,int32_t x,int32_t v)159 wsat (sim_cpu *scpu, int32_t pc, int32_t x, int32_t v)
160 {
161   address_word cia = CPU_PC_GET (scpu);
162 
163   sim_core_write_aligned_2 (scpu, cia, write_map, x, v);
164 }
165 
166 /* Write a 4 byte value to memory.  */
167 
168 static INLINE void
wlat(sim_cpu * scpu,int32_t pc,int32_t x,int32_t v)169 wlat (sim_cpu *scpu, int32_t pc, int32_t x, int32_t v)
170 {
171   address_word cia = CPU_PC_GET (scpu);
172 
173   sim_core_write_aligned_4 (scpu, cia, write_map, x, v);
174 }
175 
176 /* Read 2 bytes from memory.  */
177 
178 static INLINE int
rsat(sim_cpu * scpu,int32_t pc,int32_t x)179 rsat (sim_cpu *scpu, int32_t pc, int32_t x)
180 {
181   address_word cia = CPU_PC_GET (scpu);
182 
183   return (sim_core_read_aligned_2 (scpu, cia, read_map, x));
184 }
185 
186 /* Read 1 byte from memory.  */
187 
188 static INLINE int
rbat(sim_cpu * scpu,int32_t pc,int32_t x)189 rbat (sim_cpu *scpu, int32_t pc, int32_t x)
190 {
191   address_word cia = CPU_PC_GET (scpu);
192 
193   return (sim_core_read_aligned_1 (scpu, cia, read_map, x));
194 }
195 
196 /* Read 4 bytes from memory.  */
197 
198 static INLINE int
rlat(sim_cpu * scpu,int32_t pc,int32_t x)199 rlat (sim_cpu *scpu, int32_t pc, int32_t x)
200 {
201   address_word cia = CPU_PC_GET (scpu);
202 
203   return (sim_core_read_aligned_4 (scpu, cia, read_map, x));
204 }
205 
206 #define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
207 
208 static unsigned int
convert_target_flags(unsigned int tflags)209 convert_target_flags (unsigned int tflags)
210 {
211   unsigned int hflags = 0x0;
212 
213   CHECK_FLAG(0x0001, O_WRONLY);
214   CHECK_FLAG(0x0002, O_RDWR);
215   CHECK_FLAG(0x0008, O_APPEND);
216   CHECK_FLAG(0x0200, O_CREAT);
217   CHECK_FLAG(0x0400, O_TRUNC);
218   CHECK_FLAG(0x0800, O_EXCL);
219   CHECK_FLAG(0x2000, O_SYNC);
220 
221   if (tflags != 0x0)
222     fprintf (stderr,
223                "Simulator Error: problem converting target open flags for host.  0x%x\n",
224                tflags);
225 
226   return hflags;
227 }
228 
229 /* TODO: Split this up into finger trace levels than just insn.  */
230 #define MOXIE_TRACE_INSN(str) \
231   TRACE_INSN (scpu, "0x%08x, %s, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x", \
232                 opc, str, cpu.asregs.regs[0], cpu.asregs.regs[1], \
233                 cpu.asregs.regs[2], cpu.asregs.regs[3], cpu.asregs.regs[4], \
234                 cpu.asregs.regs[5], cpu.asregs.regs[6], cpu.asregs.regs[7], \
235                 cpu.asregs.regs[8], cpu.asregs.regs[9], cpu.asregs.regs[10], \
236                 cpu.asregs.regs[11], cpu.asregs.regs[12], cpu.asregs.regs[13], \
237                 cpu.asregs.regs[14], cpu.asregs.regs[15])
238 
239 void
sim_engine_run(SIM_DESC sd,int next_cpu_nr,int nr_cpus,int siggnal)240 sim_engine_run (SIM_DESC sd,
241                     int next_cpu_nr, /* ignore  */
242                     int nr_cpus, /* ignore  */
243                     int siggnal) /* ignore  */
244 {
245   int32_t pc, opc;
246   unsigned short inst;
247   sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
248   address_word cia = CPU_PC_GET (scpu);
249 
250   pc = cpu.asregs.regs[PC_REGNO];
251 
252   /* Run instructions here. */
253   do
254     {
255       opc = pc;
256 
257       /* Fetch the instruction at pc.  */
258       inst = (sim_core_read_aligned_1 (scpu, cia, read_map, pc) << 8)
259           + sim_core_read_aligned_1 (scpu, cia, read_map, pc+1);
260 
261       /* Decode instruction.  */
262       if (inst & (1 << 15))
263           {
264             if (inst & (1 << 14))
265               {
266                 /* This is a Form 3 instruction.  */
267                 int opcode = (inst >> 10 & 0xf);
268 
269                 switch (opcode)
270                     {
271                     case 0x00: /* beq */
272                       {
273                         MOXIE_TRACE_INSN ("beq");
274                         if (cpu.asregs.cc & CC_EQ)
275                           pc += INST2OFFSET(inst);
276                       }
277                       break;
278                     case 0x01: /* bne */
279                       {
280                         MOXIE_TRACE_INSN ("bne");
281                         if (! (cpu.asregs.cc & CC_EQ))
282                           pc += INST2OFFSET(inst);
283                       }
284                       break;
285                     case 0x02: /* blt */
286                       {
287                         MOXIE_TRACE_INSN ("blt");
288                         if (cpu.asregs.cc & CC_LT)
289                           pc += INST2OFFSET(inst);
290                       }                   break;
291                     case 0x03: /* bgt */
292                       {
293                         MOXIE_TRACE_INSN ("bgt");
294                         if (cpu.asregs.cc & CC_GT)
295                           pc += INST2OFFSET(inst);
296                       }
297                       break;
298                     case 0x04: /* bltu */
299                       {
300                         MOXIE_TRACE_INSN ("bltu");
301                         if (cpu.asregs.cc & CC_LTU)
302                           pc += INST2OFFSET(inst);
303                       }
304                       break;
305                     case 0x05: /* bgtu */
306                       {
307                         MOXIE_TRACE_INSN ("bgtu");
308                         if (cpu.asregs.cc & CC_GTU)
309                           pc += INST2OFFSET(inst);
310                       }
311                       break;
312                     case 0x06: /* bge */
313                       {
314                         MOXIE_TRACE_INSN ("bge");
315                         if (cpu.asregs.cc & (CC_GT | CC_EQ))
316                           pc += INST2OFFSET(inst);
317                       }
318                       break;
319                     case 0x07: /* ble */
320                       {
321                         MOXIE_TRACE_INSN ("ble");
322                         if (cpu.asregs.cc & (CC_LT | CC_EQ))
323                           pc += INST2OFFSET(inst);
324                       }
325                       break;
326                     case 0x08: /* bgeu */
327                       {
328                         MOXIE_TRACE_INSN ("bgeu");
329                         if (cpu.asregs.cc & (CC_GTU | CC_EQ))
330                           pc += INST2OFFSET(inst);
331                       }
332                       break;
333                     case 0x09: /* bleu */
334                       {
335                         MOXIE_TRACE_INSN ("bleu");
336                         if (cpu.asregs.cc & (CC_LTU | CC_EQ))
337                           pc += INST2OFFSET(inst);
338                       }
339                       break;
340                     default:
341                       {
342                         MOXIE_TRACE_INSN ("SIGILL3");
343                         sim_engine_halt (sd, scpu, NULL, pc, sim_stopped, SIM_SIGILL);
344                         break;
345                       }
346                     }
347               }
348             else
349               {
350                 /* This is a Form 2 instruction.  */
351                 int opcode = (inst >> 12 & 0x3);
352                 switch (opcode)
353                     {
354                     case 0x00: /* inc */
355                       {
356                         int a = (inst >> 8) & 0xf;
357                         unsigned av = cpu.asregs.regs[a];
358                         unsigned v = (inst & 0xff);
359 
360                         MOXIE_TRACE_INSN ("inc");
361                         cpu.asregs.regs[a] = av + v;
362                       }
363                       break;
364                     case 0x01: /* dec */
365                       {
366                         int a = (inst >> 8) & 0xf;
367                         unsigned av = cpu.asregs.regs[a];
368                         unsigned v = (inst & 0xff);
369 
370                         MOXIE_TRACE_INSN ("dec");
371                         cpu.asregs.regs[a] = av - v;
372                       }
373                       break;
374                     case 0x02: /* gsr */
375                       {
376                         int a = (inst >> 8) & 0xf;
377                         unsigned v = (inst & 0xff);
378 
379                         MOXIE_TRACE_INSN ("gsr");
380                         cpu.asregs.regs[a] = cpu.asregs.sregs[v];
381                       }
382                       break;
383                     case 0x03: /* ssr */
384                       {
385                         int a = (inst >> 8) & 0xf;
386                         unsigned v = (inst & 0xff);
387 
388                         MOXIE_TRACE_INSN ("ssr");
389                         cpu.asregs.sregs[v] = cpu.asregs.regs[a];
390                       }
391                       break;
392                     default:
393                       MOXIE_TRACE_INSN ("SIGILL2");
394                       sim_engine_halt (sd, scpu, NULL, pc, sim_stopped, SIM_SIGILL);
395                       break;
396                     }
397               }
398           }
399       else
400           {
401             /* This is a Form 1 instruction.  */
402             int opcode = inst >> 8;
403             switch (opcode)
404               {
405               case 0x00: /* bad */
406                 opc = opcode;
407                 MOXIE_TRACE_INSN ("SIGILL0");
408                 sim_engine_halt (sd, scpu, NULL, pc, sim_stopped, SIM_SIGILL);
409                 break;
410               case 0x01: /* ldi.l (immediate) */
411                 {
412                     int reg = (inst >> 4) & 0xf;
413                     unsigned int val = EXTRACT_WORD(pc+2);
414 
415                     MOXIE_TRACE_INSN ("ldi.l");
416                     cpu.asregs.regs[reg] = val;
417                     pc += 4;
418                 }
419                 break;
420               case 0x02: /* mov (register-to-register) */
421                 {
422                     int dest  = (inst >> 4) & 0xf;
423                     int src = (inst ) & 0xf;
424 
425                     MOXIE_TRACE_INSN ("mov");
426                     cpu.asregs.regs[dest] = cpu.asregs.regs[src];
427                 }
428                 break;
429               case 0x03: /* jsra */
430                 {
431                     unsigned int fn = EXTRACT_WORD(pc+2);
432                     unsigned int sp = cpu.asregs.regs[1];
433 
434                     MOXIE_TRACE_INSN ("jsra");
435                     /* Save a slot for the static chain.  */
436                     sp -= 4;
437 
438                     /* Push the return address.  */
439                     sp -= 4;
440                     wlat (scpu, opc, sp, pc + 6);
441 
442                     /* Push the current frame pointer.  */
443                     sp -= 4;
444                     wlat (scpu, opc, sp, cpu.asregs.regs[0]);
445 
446                     /* Uncache the stack pointer and set the pc and $fp.  */
447                     cpu.asregs.regs[1] = sp;
448                     cpu.asregs.regs[0] = sp;
449                     pc = fn - 2;
450                 }
451                 break;
452               case 0x04: /* ret */
453                 {
454                     unsigned int sp = cpu.asregs.regs[0];
455 
456                     MOXIE_TRACE_INSN ("ret");
457 
458                     /* Pop the frame pointer.  */
459                     cpu.asregs.regs[0] = rlat (scpu, opc, sp);
460                     sp += 4;
461 
462                     /* Pop the return address.  */
463                     pc = rlat (scpu, opc, sp) - 2;
464                     sp += 4;
465 
466                     /* Skip over the static chain slot.  */
467                     sp += 4;
468 
469                     /* Uncache the stack pointer.  */
470                     cpu.asregs.regs[1] = sp;
471                 }
472                 break;
473               case 0x05: /* add.l */
474                 {
475                     int a = (inst >> 4) & 0xf;
476                     int b = inst & 0xf;
477                     unsigned av = cpu.asregs.regs[a];
478                     unsigned bv = cpu.asregs.regs[b];
479 
480                     MOXIE_TRACE_INSN ("add.l");
481                     cpu.asregs.regs[a] = av + bv;
482                 }
483                 break;
484               case 0x06: /* push */
485                 {
486                     int a = (inst >> 4) & 0xf;
487                     int b = inst & 0xf;
488                     int sp = cpu.asregs.regs[a] - 4;
489 
490                     MOXIE_TRACE_INSN ("push");
491                     wlat (scpu, opc, sp, cpu.asregs.regs[b]);
492                     cpu.asregs.regs[a] = sp;
493                 }
494                 break;
495               case 0x07: /* pop */
496                 {
497                     int a = (inst >> 4) & 0xf;
498                     int b = inst & 0xf;
499                     int sp = cpu.asregs.regs[a];
500 
501                     MOXIE_TRACE_INSN ("pop");
502                     cpu.asregs.regs[b] = rlat (scpu, opc, sp);
503                     cpu.asregs.regs[a] = sp + 4;
504                 }
505                 break;
506               case 0x08: /* lda.l */
507                 {
508                     int reg = (inst >> 4) & 0xf;
509                     unsigned int addr = EXTRACT_WORD(pc+2);
510 
511                     MOXIE_TRACE_INSN ("lda.l");
512                     cpu.asregs.regs[reg] = rlat (scpu, opc, addr);
513                     pc += 4;
514                 }
515                 break;
516               case 0x09: /* sta.l */
517                 {
518                     int reg = (inst >> 4) & 0xf;
519                     unsigned int addr = EXTRACT_WORD(pc+2);
520 
521                     MOXIE_TRACE_INSN ("sta.l");
522                     wlat (scpu, opc, addr, cpu.asregs.regs[reg]);
523                     pc += 4;
524                 }
525                 break;
526               case 0x0a: /* ld.l (register indirect) */
527                 {
528                     int src  = inst & 0xf;
529                     int dest = (inst >> 4) & 0xf;
530                     int xv;
531 
532                     MOXIE_TRACE_INSN ("ld.l");
533                     xv = cpu.asregs.regs[src];
534                     cpu.asregs.regs[dest] = rlat (scpu, opc, xv);
535                 }
536                 break;
537               case 0x0b: /* st.l */
538                 {
539                     int dest = (inst >> 4) & 0xf;
540                     int val  = inst & 0xf;
541 
542                     MOXIE_TRACE_INSN ("st.l");
543                     wlat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
544                 }
545                 break;
546               case 0x0c: /* ldo.l */
547                 {
548                     unsigned int addr = EXTRACT_OFFSET(pc+2);
549                     int a = (inst >> 4) & 0xf;
550                     int b = inst & 0xf;
551 
552                     MOXIE_TRACE_INSN ("ldo.l");
553                     addr += cpu.asregs.regs[b];
554                     cpu.asregs.regs[a] = rlat (scpu, opc, addr);
555                     pc += 2;
556                 }
557                 break;
558               case 0x0d: /* sto.l */
559                 {
560                     unsigned int addr = EXTRACT_OFFSET(pc+2);
561                     int a = (inst >> 4) & 0xf;
562                     int b = inst & 0xf;
563 
564                     MOXIE_TRACE_INSN ("sto.l");
565                     addr += cpu.asregs.regs[a];
566                     wlat (scpu, opc, addr, cpu.asregs.regs[b]);
567                     pc += 2;
568                 }
569                 break;
570               case 0x0e: /* cmp */
571                 {
572                     int a  = (inst >> 4) & 0xf;
573                     int b  = inst & 0xf;
574                     int cc = 0;
575                     int va = cpu.asregs.regs[a];
576                     int vb = cpu.asregs.regs[b];
577 
578                     MOXIE_TRACE_INSN ("cmp");
579                     if (va == vb)
580                       cc = CC_EQ;
581                     else
582                       {
583                         cc |= (va < vb ? CC_LT : 0);
584                         cc |= (va > vb ? CC_GT : 0);
585                         cc |= ((unsigned int) va < (unsigned int) vb ? CC_LTU : 0);
586                         cc |= ((unsigned int) va > (unsigned int) vb ? CC_GTU : 0);
587                       }
588 
589                     cpu.asregs.cc = cc;
590                 }
591                 break;
592               case 0x0f: /* nop */
593                 break;
594               case 0x10: /* sex.b */
595                 {
596                     int a = (inst >> 4) & 0xf;
597                     int b = inst & 0xf;
598                     signed char bv = cpu.asregs.regs[b];
599 
600                     MOXIE_TRACE_INSN ("sex.b");
601                     cpu.asregs.regs[a] = (int) bv;
602                 }
603                 break;
604               case 0x11: /* sex.s */
605                 {
606                     int a = (inst >> 4) & 0xf;
607                     int b = inst & 0xf;
608                     signed short bv = cpu.asregs.regs[b];
609 
610                     MOXIE_TRACE_INSN ("sex.s");
611                     cpu.asregs.regs[a] = (int) bv;
612                 }
613                 break;
614               case 0x12: /* zex.b */
615                 {
616                     int a = (inst >> 4) & 0xf;
617                     int b = inst & 0xf;
618                     signed char bv = cpu.asregs.regs[b];
619 
620                     MOXIE_TRACE_INSN ("zex.b");
621                     cpu.asregs.regs[a] = (int) bv & 0xff;
622                 }
623                 break;
624               case 0x13: /* zex.s */
625                 {
626                     int a = (inst >> 4) & 0xf;
627                     int b = inst & 0xf;
628                     signed short bv = cpu.asregs.regs[b];
629 
630                     MOXIE_TRACE_INSN ("zex.s");
631                     cpu.asregs.regs[a] = (int) bv & 0xffff;
632                 }
633                 break;
634               case 0x14: /* umul.x */
635                 {
636                     int a = (inst >> 4) & 0xf;
637                     int b = inst & 0xf;
638                     unsigned av = cpu.asregs.regs[a];
639                     unsigned bv = cpu.asregs.regs[b];
640                     unsigned long long r =
641                       (unsigned long long) av * (unsigned long long) bv;
642 
643                     MOXIE_TRACE_INSN ("umul.x");
644                     cpu.asregs.regs[a] = r >> 32;
645                 }
646                 break;
647               case 0x15: /* mul.x */
648                 {
649                     int a = (inst >> 4) & 0xf;
650                     int b = inst & 0xf;
651                     unsigned av = cpu.asregs.regs[a];
652                     unsigned bv = cpu.asregs.regs[b];
653                     signed long long r =
654                       (signed long long) av * (signed long long) bv;
655 
656                     MOXIE_TRACE_INSN ("mul.x");
657                     cpu.asregs.regs[a] = r >> 32;
658                 }
659                 break;
660               case 0x16: /* bad */
661               case 0x17: /* bad */
662               case 0x18: /* bad */
663                 {
664                     opc = opcode;
665                     MOXIE_TRACE_INSN ("SIGILL0");
666                     sim_engine_halt (sd, scpu, NULL, pc, sim_stopped, SIM_SIGILL);
667                     break;
668                 }
669               case 0x19: /* jsr */
670                 {
671                     unsigned int fn = cpu.asregs.regs[(inst >> 4) & 0xf];
672                     unsigned int sp = cpu.asregs.regs[1];
673 
674                     MOXIE_TRACE_INSN ("jsr");
675 
676                     /* Save a slot for the static chain.  */
677                     sp -= 4;
678 
679                     /* Push the return address.  */
680                     sp -= 4;
681                     wlat (scpu, opc, sp, pc + 2);
682 
683                     /* Push the current frame pointer.  */
684                     sp -= 4;
685                     wlat (scpu, opc, sp, cpu.asregs.regs[0]);
686 
687                     /* Uncache the stack pointer and set the fp & pc.  */
688                     cpu.asregs.regs[1] = sp;
689                     cpu.asregs.regs[0] = sp;
690                     pc = fn - 2;
691                 }
692                 break;
693               case 0x1a: /* jmpa */
694                 {
695                     unsigned int tgt = EXTRACT_WORD(pc+2);
696 
697                     MOXIE_TRACE_INSN ("jmpa");
698                     pc = tgt - 2;
699                 }
700                 break;
701               case 0x1b: /* ldi.b (immediate) */
702                 {
703                     int reg = (inst >> 4) & 0xf;
704                     unsigned int val = EXTRACT_WORD(pc+2);
705 
706                     MOXIE_TRACE_INSN ("ldi.b");
707                     cpu.asregs.regs[reg] = val;
708                     pc += 4;
709                 }
710                 break;
711               case 0x1c: /* ld.b (register indirect) */
712                 {
713                     int src  = inst & 0xf;
714                     int dest = (inst >> 4) & 0xf;
715                     int xv;
716 
717                     MOXIE_TRACE_INSN ("ld.b");
718                     xv = cpu.asregs.regs[src];
719                     cpu.asregs.regs[dest] = rbat (scpu, opc, xv);
720                 }
721                 break;
722               case 0x1d: /* lda.b */
723                 {
724                     int reg = (inst >> 4) & 0xf;
725                     unsigned int addr = EXTRACT_WORD(pc+2);
726 
727                     MOXIE_TRACE_INSN ("lda.b");
728                     cpu.asregs.regs[reg] = rbat (scpu, opc, addr);
729                     pc += 4;
730                 }
731                 break;
732               case 0x1e: /* st.b */
733                 {
734                     int dest = (inst >> 4) & 0xf;
735                     int val  = inst & 0xf;
736 
737                     MOXIE_TRACE_INSN ("st.b");
738                     wbat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
739                 }
740                 break;
741               case 0x1f: /* sta.b */
742                 {
743                     int reg = (inst >> 4) & 0xf;
744                     unsigned int addr = EXTRACT_WORD(pc+2);
745 
746                     MOXIE_TRACE_INSN ("sta.b");
747                     wbat (scpu, opc, addr, cpu.asregs.regs[reg]);
748                     pc += 4;
749                 }
750                 break;
751               case 0x20: /* ldi.s (immediate) */
752                 {
753                     int reg = (inst >> 4) & 0xf;
754 
755                     unsigned int val = EXTRACT_WORD(pc+2);
756 
757                     MOXIE_TRACE_INSN ("ldi.s");
758                     cpu.asregs.regs[reg] = val;
759                     pc += 4;
760                 }
761                 break;
762               case 0x21: /* ld.s (register indirect) */
763                 {
764                     int src  = inst & 0xf;
765                     int dest = (inst >> 4) & 0xf;
766                     int xv;
767 
768                     MOXIE_TRACE_INSN ("ld.s");
769                     xv = cpu.asregs.regs[src];
770                     cpu.asregs.regs[dest] = rsat (scpu, opc, xv);
771                 }
772                 break;
773               case 0x22: /* lda.s */
774                 {
775                     int reg = (inst >> 4) & 0xf;
776                     unsigned int addr = EXTRACT_WORD(pc+2);
777 
778                     MOXIE_TRACE_INSN ("lda.s");
779                     cpu.asregs.regs[reg] = rsat (scpu, opc, addr);
780                     pc += 4;
781                 }
782                 break;
783               case 0x23: /* st.s */
784                 {
785                     int dest = (inst >> 4) & 0xf;
786                     int val  = inst & 0xf;
787 
788                     MOXIE_TRACE_INSN ("st.s");
789                     wsat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
790                 }
791                 break;
792               case 0x24: /* sta.s */
793                 {
794                     int reg = (inst >> 4) & 0xf;
795                     unsigned int addr = EXTRACT_WORD(pc+2);
796 
797                     MOXIE_TRACE_INSN ("sta.s");
798                     wsat (scpu, opc, addr, cpu.asregs.regs[reg]);
799                     pc += 4;
800                 }
801                 break;
802               case 0x25: /* jmp */
803                 {
804                     int reg = (inst >> 4) & 0xf;
805 
806                     MOXIE_TRACE_INSN ("jmp");
807                     pc = cpu.asregs.regs[reg] - 2;
808                 }
809                 break;
810               case 0x26: /* and */
811                 {
812                     int a = (inst >> 4) & 0xf;
813                     int b = inst & 0xf;
814                     int av, bv;
815 
816                     MOXIE_TRACE_INSN ("and");
817                     av = cpu.asregs.regs[a];
818                     bv = cpu.asregs.regs[b];
819                     cpu.asregs.regs[a] = av & bv;
820                 }
821                 break;
822               case 0x27: /* lshr */
823                 {
824                     int a = (inst >> 4) & 0xf;
825                     int b = inst & 0xf;
826                     int av = cpu.asregs.regs[a];
827                     int bv = cpu.asregs.regs[b];
828 
829                     MOXIE_TRACE_INSN ("lshr");
830                     cpu.asregs.regs[a] = (unsigned) ((unsigned) av >> bv);
831                 }
832                 break;
833               case 0x28: /* ashl */
834                 {
835                     int a = (inst >> 4) & 0xf;
836                     int b = inst & 0xf;
837                     int av = cpu.asregs.regs[a];
838                     int bv = cpu.asregs.regs[b];
839 
840                     MOXIE_TRACE_INSN ("ashl");
841                     cpu.asregs.regs[a] = av << bv;
842                 }
843                 break;
844               case 0x29: /* sub.l */
845                 {
846                     int a = (inst >> 4) & 0xf;
847                     int b = inst & 0xf;
848                     unsigned av = cpu.asregs.regs[a];
849                     unsigned bv = cpu.asregs.regs[b];
850 
851                     MOXIE_TRACE_INSN ("sub.l");
852                     cpu.asregs.regs[a] = av - bv;
853                 }
854                 break;
855               case 0x2a: /* neg */
856                 {
857                     int a  = (inst >> 4) & 0xf;
858                     int b  = inst & 0xf;
859                     int bv = cpu.asregs.regs[b];
860 
861                     MOXIE_TRACE_INSN ("neg");
862                     cpu.asregs.regs[a] = - bv;
863                 }
864                 break;
865               case 0x2b: /* or */
866                 {
867                     int a = (inst >> 4) & 0xf;
868                     int b = inst & 0xf;
869                     int av, bv;
870 
871                     MOXIE_TRACE_INSN ("or");
872                     av = cpu.asregs.regs[a];
873                     bv = cpu.asregs.regs[b];
874                     cpu.asregs.regs[a] = av | bv;
875                 }
876                 break;
877               case 0x2c: /* not */
878                 {
879                     int a = (inst >> 4) & 0xf;
880                     int b = inst & 0xf;
881                     int bv = cpu.asregs.regs[b];
882 
883                     MOXIE_TRACE_INSN ("not");
884                     cpu.asregs.regs[a] = 0xffffffff ^ bv;
885                 }
886                 break;
887               case 0x2d: /* ashr */
888                 {
889                     int a  = (inst >> 4) & 0xf;
890                     int b  = inst & 0xf;
891                     int av = cpu.asregs.regs[a];
892                     int bv = cpu.asregs.regs[b];
893 
894                     MOXIE_TRACE_INSN ("ashr");
895                     cpu.asregs.regs[a] = av >> bv;
896                 }
897                 break;
898               case 0x2e: /* xor */
899                 {
900                     int a = (inst >> 4) & 0xf;
901                     int b = inst & 0xf;
902                     int av, bv;
903 
904                     MOXIE_TRACE_INSN ("xor");
905                     av = cpu.asregs.regs[a];
906                     bv = cpu.asregs.regs[b];
907                     cpu.asregs.regs[a] = av ^ bv;
908                 }
909                 break;
910               case 0x2f: /* mul.l */
911                 {
912                     int a = (inst >> 4) & 0xf;
913                     int b = inst & 0xf;
914                     unsigned av = cpu.asregs.regs[a];
915                     unsigned bv = cpu.asregs.regs[b];
916 
917                     MOXIE_TRACE_INSN ("mul.l");
918                     cpu.asregs.regs[a] = av * bv;
919                 }
920                 break;
921               case 0x30: /* swi */
922                 {
923                     unsigned int inum = EXTRACT_WORD(pc+2);
924 
925                     MOXIE_TRACE_INSN ("swi");
926                     /* Set the special registers appropriately.  */
927                     cpu.asregs.sregs[2] = 3; /* MOXIE_EX_SWI */
928                   cpu.asregs.sregs[3] = inum;
929                     switch (inum)
930                       {
931                       case TARGET_NEWLIB_SYS_exit:
932                         {
933                           sim_engine_halt (sd, scpu, NULL, pc, sim_exited,
934                                                cpu.asregs.regs[2]);
935                           break;
936                         }
937                       case TARGET_NEWLIB_SYS_open:
938                         {
939                           char fname[1024];
940                           int mode = (int) convert_target_flags ((unsigned) cpu.asregs.regs[3]);
941                           int fd;
942                           sim_core_read_buffer (sd, scpu, read_map, fname,
943                                                       cpu.asregs.regs[2], 1024);
944                           fd = sim_io_open (sd, fname, mode);
945                           /* FIXME - set errno */
946                           cpu.asregs.regs[2] = fd;
947                           break;
948                         }
949                       case TARGET_NEWLIB_SYS_read:
950                         {
951                           int fd = cpu.asregs.regs[2];
952                           unsigned len = (unsigned) cpu.asregs.regs[4];
953                           char *buf = malloc (len);
954                           cpu.asregs.regs[2] = sim_io_read (sd, fd, buf, len);
955                           sim_core_write_buffer (sd, scpu, write_map, buf,
956                                                        cpu.asregs.regs[3], len);
957                           free (buf);
958                           break;
959                         }
960                       case TARGET_NEWLIB_SYS_write:
961                         {
962                           char *str;
963                           /* String length is at 0x12($fp) */
964                           unsigned count, len = (unsigned) cpu.asregs.regs[4];
965                           str = malloc (len);
966                           sim_core_read_buffer (sd, scpu, read_map, str,
967                                                       cpu.asregs.regs[3], len);
968                           count = sim_io_write (sd, cpu.asregs.regs[2], str, len);
969                           free (str);
970                           cpu.asregs.regs[2] = count;
971                           break;
972                         }
973                       case TARGET_NEWLIB_SYS_unlink:
974                         {
975                           char fname[1024];
976                           int fd;
977                           sim_core_read_buffer (sd, scpu, read_map, fname,
978                                                       cpu.asregs.regs[2], 1024);
979                           fd = sim_io_unlink (sd, fname);
980                           /* FIXME - set errno */
981                           cpu.asregs.regs[2] = fd;
982                           break;
983                         }
984                       case 0xffffffff: /* Linux System Call */
985                         {
986                           unsigned int handler = cpu.asregs.sregs[1];
987                           unsigned int sp = cpu.asregs.regs[1];
988 
989                           /* Save a slot for the static chain.  */
990                           sp -= 4;
991 
992                           /* Push the return address.  */
993                           sp -= 4;
994                           wlat (scpu, opc, sp, pc + 6);
995 
996                           /* Push the current frame pointer.  */
997                           sp -= 4;
998                           wlat (scpu, opc, sp, cpu.asregs.regs[0]);
999 
1000                           /* Uncache the stack pointer and set the fp & pc.  */
1001                           cpu.asregs.regs[1] = sp;
1002                           cpu.asregs.regs[0] = sp;
1003                           pc = handler - 6;
1004                         }
1005                       default:
1006                         break;
1007                       }
1008                     pc += 4;
1009                 }
1010                 break;
1011               case 0x31: /* div.l */
1012                 {
1013                     int a = (inst >> 4) & 0xf;
1014                     int b = inst & 0xf;
1015                     int av = cpu.asregs.regs[a];
1016                     int bv = cpu.asregs.regs[b];
1017 
1018                     MOXIE_TRACE_INSN ("div.l");
1019                     cpu.asregs.regs[a] = av / bv;
1020                 }
1021                 break;
1022               case 0x32: /* udiv.l */
1023                 {
1024                     int a = (inst >> 4) & 0xf;
1025                     int b = inst & 0xf;
1026                     unsigned int av = cpu.asregs.regs[a];
1027                     unsigned int bv = cpu.asregs.regs[b];
1028 
1029                     MOXIE_TRACE_INSN ("udiv.l");
1030                     cpu.asregs.regs[a] = (av / bv);
1031                 }
1032                 break;
1033               case 0x33: /* mod.l */
1034                 {
1035                     int a = (inst >> 4) & 0xf;
1036                     int b = inst & 0xf;
1037                     int av = cpu.asregs.regs[a];
1038                     int bv = cpu.asregs.regs[b];
1039 
1040                     MOXIE_TRACE_INSN ("mod.l");
1041                     cpu.asregs.regs[a] = av % bv;
1042                 }
1043                 break;
1044               case 0x34: /* umod.l */
1045                 {
1046                     int a = (inst >> 4) & 0xf;
1047                     int b = inst & 0xf;
1048                     unsigned int av = cpu.asregs.regs[a];
1049                     unsigned int bv = cpu.asregs.regs[b];
1050 
1051                     MOXIE_TRACE_INSN ("umod.l");
1052                     cpu.asregs.regs[a] = (av % bv);
1053                 }
1054                 break;
1055               case 0x35: /* brk */
1056                 MOXIE_TRACE_INSN ("brk");
1057                 sim_engine_halt (sd, scpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
1058                 pc -= 2; /* Adjust pc */
1059                 break;
1060               case 0x36: /* ldo.b */
1061                 {
1062                     unsigned int addr = EXTRACT_OFFSET(pc+2);
1063                     int a = (inst >> 4) & 0xf;
1064                     int b = inst & 0xf;
1065 
1066                     MOXIE_TRACE_INSN ("ldo.b");
1067                     addr += cpu.asregs.regs[b];
1068                     cpu.asregs.regs[a] = rbat (scpu, opc, addr);
1069                     pc += 2;
1070                 }
1071                 break;
1072               case 0x37: /* sto.b */
1073                 {
1074                     unsigned int addr = EXTRACT_OFFSET(pc+2);
1075                     int a = (inst >> 4) & 0xf;
1076                     int b = inst & 0xf;
1077 
1078                     MOXIE_TRACE_INSN ("sto.b");
1079                     addr += cpu.asregs.regs[a];
1080                     wbat (scpu, opc, addr, cpu.asregs.regs[b]);
1081                     pc += 2;
1082                 }
1083                 break;
1084               case 0x38: /* ldo.s */
1085                 {
1086                     unsigned int addr = EXTRACT_OFFSET(pc+2);
1087                     int a = (inst >> 4) & 0xf;
1088                     int b = inst & 0xf;
1089 
1090                     MOXIE_TRACE_INSN ("ldo.s");
1091                     addr += cpu.asregs.regs[b];
1092                     cpu.asregs.regs[a] = rsat (scpu, opc, addr);
1093                     pc += 2;
1094                 }
1095                 break;
1096               case 0x39: /* sto.s */
1097                 {
1098                     unsigned int addr = EXTRACT_OFFSET(pc+2);
1099                     int a = (inst >> 4) & 0xf;
1100                     int b = inst & 0xf;
1101 
1102                     MOXIE_TRACE_INSN ("sto.s");
1103                     addr += cpu.asregs.regs[a];
1104                     wsat (scpu, opc, addr, cpu.asregs.regs[b]);
1105                     pc += 2;
1106                 }
1107                 break;
1108               default:
1109                 opc = opcode;
1110                 MOXIE_TRACE_INSN ("SIGILL1");
1111                 sim_engine_halt (sd, scpu, NULL, pc, sim_stopped, SIM_SIGILL);
1112                 break;
1113               }
1114           }
1115 
1116       cpu.asregs.insts++;
1117       pc += 2;
1118       cpu.asregs.regs[PC_REGNO] = pc;
1119 
1120       if (sim_events_tick (sd))
1121           sim_events_process (sd);
1122 
1123     } while (1);
1124 }
1125 
1126 static int
moxie_reg_store(SIM_CPU * scpu,int rn,const void * memory,int length)1127 moxie_reg_store (SIM_CPU *scpu, int rn, const void *memory, int length)
1128 {
1129   if (rn < NUM_MOXIE_REGS && rn >= 0)
1130     {
1131       if (length == 4)
1132           {
1133             long ival;
1134 
1135             /* misalignment safe */
1136             ival = moxie_extract_unsigned_integer (memory, 4);
1137             cpu.asints[rn] = ival;
1138           }
1139 
1140       return 4;
1141     }
1142   else
1143     return 0;
1144 }
1145 
1146 static int
moxie_reg_fetch(SIM_CPU * scpu,int rn,void * memory,int length)1147 moxie_reg_fetch (SIM_CPU *scpu, int rn, void *memory, int length)
1148 {
1149   if (rn < NUM_MOXIE_REGS && rn >= 0)
1150     {
1151       if (length == 4)
1152           {
1153             long ival = cpu.asints[rn];
1154 
1155             /* misalignment-safe */
1156             moxie_store_unsigned_integer (memory, 4, ival);
1157           }
1158 
1159       return 4;
1160     }
1161   else
1162     return 0;
1163 }
1164 
1165 static sim_cia
moxie_pc_get(sim_cpu * cpu)1166 moxie_pc_get (sim_cpu *cpu)
1167 {
1168   return MOXIE_SIM_CPU (cpu)->registers[PCIDX];
1169 }
1170 
1171 static void
moxie_pc_set(sim_cpu * cpu,sim_cia pc)1172 moxie_pc_set (sim_cpu *cpu, sim_cia pc)
1173 {
1174   MOXIE_SIM_CPU (cpu)->registers[PCIDX] = pc;
1175 }
1176 
1177 static void
free_state(SIM_DESC sd)1178 free_state (SIM_DESC sd)
1179 {
1180   if (STATE_MODULES (sd) != NULL)
1181     sim_module_uninstall (sd);
1182   sim_cpu_free_all (sd);
1183   sim_state_free (sd);
1184 }
1185 
1186 SIM_DESC
sim_open(SIM_OPEN_KIND kind,host_callback * cb,struct bfd * abfd,char * const * argv)1187 sim_open (SIM_OPEN_KIND kind, host_callback *cb,
1188             struct bfd *abfd, char * const *argv)
1189 {
1190   int i;
1191   SIM_DESC sd = sim_state_alloc (kind, cb);
1192   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
1193 
1194   /* Set default options before parsing user options.  */
1195   current_target_byte_order = BFD_ENDIAN_BIG;
1196 
1197   /* The cpu data is kept in a separately allocated chunk of memory.  */
1198   if (sim_cpu_alloc_all_extra (sd, 0, sizeof (struct moxie_sim_cpu))
1199       != SIM_RC_OK)
1200     {
1201       free_state (sd);
1202       return 0;
1203     }
1204 
1205   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
1206     {
1207       free_state (sd);
1208       return 0;
1209     }
1210 
1211   /* The parser will print an error message for us, so we silently return.  */
1212   if (sim_parse_args (sd, argv) != SIM_RC_OK)
1213     {
1214       free_state (sd);
1215       return 0;
1216     }
1217 
1218   sim_do_command(sd," memory region 0x00000000,0x4000000") ;
1219   sim_do_command(sd," memory region 0xE0000000,0x10000") ;
1220 
1221   /* Check for/establish the a reference program image.  */
1222   if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
1223     {
1224       free_state (sd);
1225       return 0;
1226     }
1227 
1228   /* Configure/verify the target byte order and other runtime
1229      configuration options.  */
1230   if (sim_config (sd) != SIM_RC_OK)
1231     {
1232       sim_module_uninstall (sd);
1233       return 0;
1234     }
1235 
1236   if (sim_post_argv_init (sd) != SIM_RC_OK)
1237     {
1238       /* Uninstall the modules to avoid memory leaks,
1239            file descriptor leaks, etc.  */
1240       sim_module_uninstall (sd);
1241       return 0;
1242     }
1243 
1244   /* CPU specific initialization.  */
1245   for (i = 0; i < MAX_NR_PROCESSORS; ++i)
1246     {
1247       SIM_CPU *cpu = STATE_CPU (sd, i);
1248 
1249       CPU_REG_FETCH (cpu) = moxie_reg_fetch;
1250       CPU_REG_STORE (cpu) = moxie_reg_store;
1251       CPU_PC_FETCH (cpu) = moxie_pc_get;
1252       CPU_PC_STORE (cpu) = moxie_pc_set;
1253 
1254       set_initial_gprs ();    /* Reset the GPR registers.  */
1255     }
1256 
1257   return sd;
1258 }
1259 
1260 /* Load the device tree blob.  */
1261 
1262 static void
load_dtb(SIM_DESC sd,const char * filename)1263 load_dtb (SIM_DESC sd, const char *filename)
1264 {
1265   int size = 0;
1266   FILE *f = fopen (filename, "rb");
1267   char *buf;
1268   sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1269 
1270   /* Don't warn as the sim works fine w/out a device tree.  */
1271   if (f == NULL)
1272     return;
1273   fseek (f, 0, SEEK_END);
1274   size = ftell(f);
1275   fseek (f, 0, SEEK_SET);
1276   buf = alloca (size);
1277   if (size != fread (buf, 1, size, f))
1278     {
1279       sim_io_eprintf (sd, "ERROR: error reading ``%s''.\n", filename);
1280       fclose (f);
1281       return;
1282     }
1283   sim_core_write_buffer (sd, scpu, write_map, buf, 0xE0000000, size);
1284   cpu.asregs.sregs[9] = 0xE0000000;
1285   fclose (f);
1286 }
1287 
1288 SIM_RC
sim_create_inferior(SIM_DESC sd,struct bfd * prog_bfd,char * const * argv,char * const * env)1289 sim_create_inferior (SIM_DESC sd, struct bfd *prog_bfd,
1290                          char * const *argv, char * const *env)
1291 {
1292   char * const *avp;
1293   int argc, i, tp;
1294   sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
1295 
1296   if (prog_bfd != NULL)
1297     cpu.asregs.regs[PC_REGNO] = bfd_get_start_address (prog_bfd);
1298 
1299   /* Copy args into target memory.  */
1300   avp = argv;
1301   for (argc = 0; avp && *avp; avp++)
1302     argc++;
1303 
1304   /* Target memory looks like this:
1305      0x00000000 zero word
1306      0x00000004 argc word
1307      0x00000008 start of argv
1308      .
1309      0x0000???? end of argv
1310      0x0000???? zero word
1311      0x0000???? start of data pointed to by argv  */
1312 
1313   wlat (scpu, 0, 0, 0);
1314   wlat (scpu, 0, 4, argc);
1315 
1316   /* tp is the offset of our first argv data.  */
1317   tp = 4 + 4 + argc * 4 + 4;
1318 
1319   for (i = 0; i < argc; i++)
1320     {
1321       /* Set the argv value.  */
1322       wlat (scpu, 0, 4 + 4 + i * 4, tp);
1323 
1324       /* Store the string.  */
1325       sim_core_write_buffer (sd, scpu, write_map, argv[i],
1326                                    tp, strlen(argv[i])+1);
1327       tp += strlen (argv[i]) + 1;
1328     }
1329 
1330   wlat (scpu, 0, 4 + 4 + i * 4, 0);
1331 
1332   load_dtb (sd, DTB);
1333 
1334   return SIM_RC_OK;
1335 }
1336