/[gxemul]/trunk/src/cpus/cpu_arm_coproc.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/src/cpus/cpu_arm_coproc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (hide annotations)
Mon Oct 8 16:19:37 2007 UTC (13 years, 3 months ago) by dpavlin
File MIME type: text/plain
File size: 13837 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1121 2006/02/18 21:03:08 debug Exp $
20051126	Cobalt and PReP now work with the 21143 NIC.
		Continuing on Alpha dyntrans things.
		Fixing some more left-shift-by-24 to unsigned.
20051127	Working on OpenFirmware emulation; major cleanup/redesign.
		Progress on MacPPC emulation: NetBSD detects two CPUs (when
		running with -n 2), framebuffer output (for text) works.
		Adding quick-hack Bandit PCI controller and "gc" interrupt
		controller for MacPPC.
20051128	Changing from a Bandit to a Uni-North controller for macppc.
		Continuing on OpenFirmware and MacPPC emulation in general
		(obio controller, and wdc attached to the obio seems to work).
20051129	More work on MacPPC emulation (adding a dummy ADB controller).
		Continuing the PCI bus cleanup (endianness and tag composition)
		and rewriting all PCI controllers' access functions.
20051130	Various minor PPC dyntrans optimizations.
		Manually inlining some parts of the framebuffer redraw routine.
		Slowly beginning the conversion of the old MIPS emulation into
		dyntrans (but this will take quite some time to get right).
		Generalizing quick_pc_to_pointers.
20051201	Documentation update (David Muse has made available a kernel
		which simplifies Debian/DECstation installation).
		Continuing on the ADB bus controller.
20051202	Beginning a rewrite of the Zilog serial controller (dev_zs).
20051203	Continuing on the zs rewrite (now called dev_z8530); conversion
		to devinit style.
		Reworking some of the input-only vs output-only vs input-output
		details of src/console.c, better warning messages, and adding
		a debug dump.
		Removing the concept of "device state"; it wasn't really used.
		Changing some debug output (-vv should now be used to show all
		details about devices and busses; not shown during normal
		startup anymore).
		Beginning on some SPARC instruction disassembly support.
20051204	Minor PPC updates (WALNUT skeleton stuff).
		Continuing on the MIPS dyntrans rewrite.
		More progress on the ADB controller (a keyboard is "detected"
		by NetBSD and OpenBSD).
		Downgrading OpenBSD/arc as a guest OS from "working" to
		"almost working" in the documentation.
		Progress on Algor emulation ("v3" PCI controller).
20051205	Minor updates.
20051207	Sorting devices according to address; this reduces complexity
		of device lookups from O(n) to O(log n) in memory_rw (but no
		real performance increase (yet) in experiments).
20051210	Beginning the work on native dyntrans backends (by making a
		simple skeleton; so far only for Alpha hosts).
20051211	Some very minor SPARC updates.
20051215	Fixing a bug in the MIPS mul (note: not mult) instruction,
		so it also works with non-64-bit emulation. (Thanks to Alec
		Voropay for noticing the problem.)
20051216	More work on the fake/empty/simple/skeleton/whatever backend;
		performance doesn't increase, so this isn't really worth it,
		but it was probably worth it to prepare for a real backend
		later.
20051219	More instr call statistics gathering and analysis stuff.
20051220	Another fix for MIPS 'mul'. Also converting mul and {d,}cl{o,z}
		to dyntrans.
		memory_ppc.c syntax error fix (noticed by Peter Valchev).
		Beginning to move out machines from src/machine.c into
		individual files in src/machines (in a way similar to the
		autodev system for devices).
20051222	Updating the documentation regarding NetBSD/pmax 3.0.
20051223	- " - NetBSD/cats 3.0.
20051225	- " - NetBSD/hpcmips 3.0.
20051226	Continuing on the machine registry redesign.
		Adding support for ARM rrx (33-bit rotate).
		Fixing some signed/unsigned issues (exposed by gcc -W).
20051227	Fixing the bug which prevented a NetBSD/prep 3.0 install kernel
		from starting (triggered when an mtmsr was the last instruction
		on a page). Unfortunately not enough to get the kernel to run
		as well as the 2.1 kernels did.
20051230	Some dyntrans refactoring.
20051231	Continuing on the machine registry redesign.
20060101-10	Continuing... moving more machines. Moving MD interrupt stuff
		from machine.c into a new src/machines/interrupts.c.
20060114	Adding various mvmeppc machine skeletons.
20060115	Continuing on mvme* stuff. NetBSD/mvmeppc prints boot messages
		(for MVME1600) and reaches the root device prompt, but no
		specific hardware devices are emulated yet.
20060116	Minor updates to the mvme1600 emulation mode; the Eagle PCI bus
		seems to work without much modification, and a 21143 can be
		detected, interrupts might work (but untested so far).
		Adding a fake MK48Txx (mkclock) device, for NetBSD/mvmeppc.
20060121	Adding an aux control register for ARM. (A BIG thank you to
		Olivier Houchard for tracking down this bug.)
20060122	Adding more ARM instructions (smulXY), and dev_iq80321_7seg.
20060124	Adding disassembly of more ARM instructions (mia*, mra/mar),
		and some semi-bogus XScale and i80321 registers.
20060201-02	Various minor updates. Moving the last machines out of
		machine.c.
20060204	Adding a -c command line option, for running debugger commands
		before the simulation starts, but after all files have been
		loaded.
		Minor iq80321-related updates.
20060209	Minor hacks (DEVINIT macro, etc).
		Preparing for the generalization of the 64-bit dyntrans address
		translation subsystem.
20060216	Adding ARM ldrd (double-register load).
20060217	Continuing on various ARM-related stuff.
20060218	More progress on the ATA/wdc emulation for NetBSD/iq80321.
		NetBSD/evbarm can now be installed :-)  Updating the docs, etc.
		Continuing on Algor emulation.

==============  RELEASE 0.3.8  ==============


1 dpavlin 14 /*
2 dpavlin 22 * Copyright (C) 2005-2006 Anders Gavare. All rights reserved.
3 dpavlin 14 *
4     * Redistribution and use in source and binary forms, with or without
5     * modification, are permitted provided that the following conditions are met:
6     *
7     * 1. Redistributions of source code must retain the above copyright
8     * notice, this list of conditions and the following disclaimer.
9     * 2. Redistributions in binary form must reproduce the above copyright
10     * notice, this list of conditions and the following disclaimer in the
11     * documentation and/or other materials provided with the distribution.
12     * 3. The name of the author may not be used to endorse or promote products
13     * derived from this software without specific prior written permission.
14     *
15     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18     * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25     * SUCH DAMAGE.
26     *
27     *
28 dpavlin 22 * $Id: cpu_arm_coproc.c,v 1.22 2006/02/17 18:38:30 debug Exp $
29 dpavlin 14 *
30     * ARM coprocessor emulation.
31     */
32    
33     #include <stdio.h>
34     #include <stdlib.h>
35     #include <string.h>
36 dpavlin 22 #include <unistd.h>
37 dpavlin 14 #include <ctype.h>
38    
39     #include "cpu.h"
40     #include "misc.h"
41     #include "symbol.h"
42    
43 dpavlin 22 #include "i80321reg.h"
44 dpavlin 14
45 dpavlin 22
46 dpavlin 14 /*
47     * arm_coproc_15():
48     *
49     * The system control coprocessor.
50     */
51     void arm_coproc_15(struct cpu *cpu, int opcode1, int opcode2, int l_bit,
52     int crn, int crm, int rd)
53     {
54     uint32_t old_control;
55    
56     /* Some sanity checks: */
57     if (opcode1 != 0) {
58     fatal("arm_coproc_15: opcode1 = %i, should be 0\n", opcode1);
59     exit(1);
60     }
61     if (rd == ARM_PC) {
62     fatal("arm_coproc_15: rd = PC\n");
63     exit(1);
64     }
65    
66     switch (crn) {
67    
68 dpavlin 22 case 0: /*
69     * Main ID register (and Cache Type register, on XScale)
70     *
71     * Writes are supposed to be ignored, according to Intel docs.
72     */
73     switch (opcode2) {
74     case 0: if (l_bit)
75     cpu->cd.arm.r[rd] = cpu->cd.arm.cpu_type.cpu_id;
76     else
77     fatal("[ arm_coproc_15: attempt to write "
78     "to the Main ID register? ]\n");
79     break;
80     case 1: if (l_bit)
81     cpu->cd.arm.r[rd] = cpu->cd.arm.cachetype;
82     else
83     fatal("[ arm_coproc_15: attempt to write "
84     "to the Cache Type register? ]\n");
85     break;
86     default:fatal("[ arm_coproc_15: TODO: cr0, opcode2=%i ]\n",
87 dpavlin 14 opcode2);
88 dpavlin 22 exit(1);
89     }
90 dpavlin 14 break;
91    
92     case 1: /* Control Register: */
93     if (l_bit) {
94 dpavlin 22 /* Load from the normal/aux control register: */
95     switch (opcode2) {
96     case 0: cpu->cd.arm.r[rd] = cpu->cd.arm.control;
97     break;
98     case 1: cpu->cd.arm.r[rd] = cpu->cd.arm.auxctrl;
99     break;
100     default:fatal("Unimplemented opcode2 = %i\n", opcode2);
101     fatal("(opcode1=%i crn=%i crm=%i rd=%i l=%i)\n",
102     opcode1, crn, crm, rd, l_bit);
103     exit(1);
104     }
105 dpavlin 14 return;
106     }
107 dpavlin 22
108     if (opcode2 == 1) {
109     /* Write to auxctrl: */
110     old_control = cpu->cd.arm.auxctrl;
111     cpu->cd.arm.auxctrl = cpu->cd.arm.r[rd];
112     if ((old_control & ARM_AUXCTRL_MD) !=
113     (cpu->cd.arm.auxctrl & ARM_AUXCTRL_MD)) {
114     debug("[ setting the minidata cache attribute"
115     " to 0x%x ]\n", (cpu->cd.arm.auxctrl &
116     ARM_AUXCTRL_MD) >> ARM_AUXCTRL_MD_SHIFT);
117     }
118     if ((old_control & ARM_AUXCTRL_K) !=
119     (cpu->cd.arm.auxctrl & ARM_AUXCTRL_K)) {
120     debug("[ %s write buffer coalescing ]\n",
121     cpu->cd.arm.auxctrl & ARM_AUXCTRL_K?
122     "Disabling" : "Enabling");
123     }
124     return;
125     } else if (opcode2 != 0) {
126     fatal("Unimplemented write, opcode2 = %i\n", opcode2);
127     fatal("(opcode1=%i crn=%i crm=%i rd=%i l=%i)\n",
128     opcode1, crn, crm, rd, l_bit);
129     exit(1);
130     }
131    
132 dpavlin 14 /*
133     * Write to control: Check each bit individually:
134     */
135     old_control = cpu->cd.arm.control;
136     cpu->cd.arm.control = cpu->cd.arm.r[rd];
137     if ((old_control & ARM_CONTROL_MMU) !=
138 dpavlin 18 (cpu->cd.arm.control & ARM_CONTROL_MMU)) {
139 dpavlin 14 debug("[ %s the MMU ]\n", cpu->cd.arm.control &
140     ARM_CONTROL_MMU? "enabling" : "disabling");
141 dpavlin 18 cpu->translate_address =
142     cpu->cd.arm.control & ARM_CONTROL_MMU?
143     arm_translate_address_mmu : arm_translate_address;
144     }
145 dpavlin 14 if ((old_control & ARM_CONTROL_ALIGN) !=
146     (cpu->cd.arm.control & ARM_CONTROL_ALIGN))
147     debug("[ %s alignment checks ]\n", cpu->cd.arm.control &
148     ARM_CONTROL_ALIGN? "enabling" : "disabling");
149     if ((old_control & ARM_CONTROL_CACHE) !=
150     (cpu->cd.arm.control & ARM_CONTROL_CACHE))
151     debug("[ %s the [data] cache ]\n", cpu->cd.arm.control &
152     ARM_CONTROL_CACHE? "enabling" : "disabling");
153     if ((old_control & ARM_CONTROL_WBUFFER) !=
154     (cpu->cd.arm.control & ARM_CONTROL_WBUFFER))
155     debug("[ %s the write buffer ]\n", cpu->cd.arm.control &
156     ARM_CONTROL_WBUFFER? "enabling" : "disabling");
157     if ((old_control & ARM_CONTROL_BIG) !=
158     (cpu->cd.arm.control & ARM_CONTROL_BIG)) {
159     fatal("ERROR: Trying to switch endianness. Not "
160     "supported yet.\n");
161     exit(1);
162     }
163     if ((old_control & ARM_CONTROL_ICACHE) !=
164     (cpu->cd.arm.control & ARM_CONTROL_ICACHE))
165     debug("[ %s the icache ]\n", cpu->cd.arm.control &
166     ARM_CONTROL_ICACHE? "enabling" : "disabling");
167     /* TODO: More bits. */
168     break;
169    
170     case 2: /* Translation Table Base register: */
171     /* NOTE: 16 KB aligned. */
172     if (l_bit)
173     cpu->cd.arm.r[rd] = cpu->cd.arm.ttb & 0xffffc000;
174     else {
175     cpu->cd.arm.ttb = cpu->cd.arm.r[rd];
176     if (cpu->cd.arm.ttb & 0x3fff)
177     fatal("[ WARNING! low bits of new TTB non-"
178     "zero? 0x%08x ]\n", cpu->cd.arm.ttb);
179     cpu->cd.arm.ttb &= 0xffffc000;
180     }
181     break;
182    
183     case 3: /* Domain Access Control Register: */
184     if (l_bit)
185     cpu->cd.arm.r[rd] = cpu->cd.arm.dacr;
186     else
187     cpu->cd.arm.dacr = cpu->cd.arm.r[rd];
188     break;
189    
190     case 5: /* Fault Status Register: */
191     /* Note: Only the lowest 8 bits are defined. */
192     if (l_bit)
193     cpu->cd.arm.r[rd] = cpu->cd.arm.fsr & 0xff;
194     else
195     cpu->cd.arm.fsr = cpu->cd.arm.r[rd] & 0xff;
196     break;
197    
198     case 6: /* Fault Address Register: */
199     if (l_bit)
200     cpu->cd.arm.r[rd] = cpu->cd.arm.far;
201     else
202     cpu->cd.arm.far = cpu->cd.arm.r[rd];
203     break;
204    
205     case 7: /* Cache functions: */
206     if (l_bit) {
207     fatal("[ arm_coproc_15: attempt to read cr7? ]\n");
208     return;
209     }
210     /* debug("[ arm_coproc_15: cache op: TODO ]\n"); */
211     /* TODO: */
212     break;
213    
214     case 8: /* TLB functions: */
215     if (l_bit) {
216     fatal("[ arm_coproc_15: attempt to read cr8? ]\n");
217     return;
218     }
219     /* fatal("[ arm_coproc_15: TLB: op2=%i crm=%i rd=0x%08x ]\n",
220     opcode2, crm, cpu->cd.arm.r[rd]); */
221     if (opcode2 == 0)
222 dpavlin 18 cpu->invalidate_translation_caches(cpu, 0,
223 dpavlin 14 INVALIDATE_ALL);
224     else
225 dpavlin 18 cpu->invalidate_translation_caches(cpu,
226 dpavlin 14 cpu->cd.arm.r[rd], INVALIDATE_VADDR);
227     break;
228    
229 dpavlin 20 case 9: /* Cache lockdown: */
230 dpavlin 22 fatal("[ arm_coproc_15: cache lockdown: TODO ]\n");
231 dpavlin 20 /* TODO */
232     break;
233    
234 dpavlin 14 case 13:/* Process ID Register: */
235     if (opcode2 != 0)
236     fatal("[ arm_coproc_15: PID access, but opcode2 "
237     "= %i? (should be 0) ]\n", opcode2);
238     if (crm != 0)
239     fatal("[ arm_coproc_15: PID access, but crm "
240     "= %i? (should be 0) ]\n", crm);
241     if (l_bit)
242     cpu->cd.arm.r[rd] = cpu->cd.arm.pid;
243     else
244     cpu->cd.arm.pid = cpu->cd.arm.r[rd];
245     if (cpu->cd.arm.pid != 0) {
246     fatal("ARM TODO: pid!=0. Fast Context Switch"
247     " Extension not implemented yet\n");
248     exit(1);
249     }
250     break;
251    
252 dpavlin 22 /* case 14: */
253     /* Breakpoint registers on XScale (possibly others?) */
254     /* TODO */
255     /* break; */
256    
257 dpavlin 18 case 15:/* IMPLEMENTATION DEPENDENT! */
258 dpavlin 22 switch (crm) {
259     case 1: /*
260     * On XScale (and others? TODO), this is the
261     * CoProcessor Access Register. Note/TODO: This isn't
262     * really used throughout the rest of the code yet.
263     */
264     if (l_bit)
265     cpu->cd.arm.r[rd] = cpu->cd.arm.cpar;
266     else
267     cpu->cd.arm.cpar = cpu->cd.arm.r[rd];
268     break;
269     default:fatal("[ arm_coproc_15: TODO: IMPLEMENTATION "
270     "DEPENDENT! ]\n");
271     exit(1);
272     }
273 dpavlin 14 break;
274    
275     default:fatal("arm_coproc_15: unimplemented crn = %i\n", crn);
276     fatal("(opcode1=%i opcode2=%i crm=%i rd=%i l=%i)\n",
277     opcode1, opcode2, crm, rd, l_bit);
278     exit(1);
279     }
280     }
281    
282    
283     /*
284 dpavlin 22 * arm_coproc_i80321_6():
285 dpavlin 14 *
286 dpavlin 22 * Intel 80321 coprocessor 6.
287 dpavlin 14 */
288 dpavlin 22 void arm_coproc_i80321_6(struct cpu *cpu, int opcode1, int opcode2, int l_bit,
289 dpavlin 14 int crn, int crm, int rd)
290     {
291     switch (crm) {
292 dpavlin 22
293     case 0: switch (crn) {
294     case 0: if (l_bit)
295     cpu->cd.arm.r[rd] = cpu->cd.arm.i80321_inten;
296     else
297     cpu->cd.arm.i80321_inten = cpu->cd.arm.r[rd];
298     break;
299     case 4: if (l_bit)
300     cpu->cd.arm.r[rd] = cpu->cd.arm.i80321_isteer;
301     else {
302     cpu->cd.arm.i80321_isteer = cpu->cd.arm.r[rd];
303     if (cpu->cd.arm.r[rd] != 0) {
304     fatal("ARM xscale interrupt steering"
305     " is not yet implemented\n");
306     exit(1);
307     }
308     }
309     break;
310     case 8: if (l_bit)
311     cpu->cd.arm.r[rd] = cpu->cd.arm.i80321_isrc;
312     else {
313     cpu->cd.arm.i80321_isrc = cpu->cd.arm.r[rd];
314     fatal("TODO: XScale int ack?\n");
315     exit(1);
316     }
317     break;
318     default:goto unknown;
319     }
320 dpavlin 14 break;
321 dpavlin 22
322     case 1:
323     /* fatal("TIMER opcode1=%i opcode2=%i crn="
324     "%i crm=%i rd=%i l=%i)\n", opcode1, opcode2, crn, crm, rd, l_bit); */
325    
326 dpavlin 14 switch (crn) {
327     case 0: /* tmr0: */
328 dpavlin 22 if (l_bit)
329     cpu->cd.arm.r[rd] = cpu->cd.arm.tmr0;
330     else
331     cpu->cd.arm.tmr0 = cpu->cd.arm.r[rd];
332 dpavlin 14 break;
333 dpavlin 22 case 1: /* tmr1: */
334     if (l_bit)
335     cpu->cd.arm.r[rd] = cpu->cd.arm.tmr1;
336     else
337     cpu->cd.arm.tmr1 = cpu->cd.arm.r[rd];
338     break;
339 dpavlin 14 case 2: /* tcr0: */
340 dpavlin 22 if (l_bit) {
341     /* NOTE/TODO: Ugly hack: timer increment */
342     cpu->cd.arm.tcr0 ++;
343     cpu->cd.arm.r[rd] = cpu->cd.arm.tcr0;
344     } else {
345     cpu->cd.arm.tcr0 = cpu->cd.arm.r[rd];
346     }
347 dpavlin 14 break;
348 dpavlin 22 case 3: /* tcr1: */
349     if (l_bit) {
350     /* NOTE/TODO: Ugly hack: timer increment */
351     cpu->cd.arm.tcr1 ++;
352     cpu->cd.arm.r[rd] = cpu->cd.arm.tcr1;
353     } else {
354     cpu->cd.arm.tcr1 = cpu->cd.arm.r[rd];
355     }
356     break;
357 dpavlin 14 case 4: /* trr0: */
358 dpavlin 22 if (l_bit)
359     cpu->cd.arm.r[rd] = cpu->cd.arm.trr0;
360     else
361     cpu->cd.arm.trr0 = cpu->cd.arm.r[rd];
362 dpavlin 14 break;
363 dpavlin 22 case 5: /* trr1: */
364     if (l_bit)
365     cpu->cd.arm.r[rd] = cpu->cd.arm.trr1;
366     else
367     cpu->cd.arm.trr1 = cpu->cd.arm.r[rd];
368     break;
369 dpavlin 14 case 6: /* tisr: */
370 dpavlin 22 if (l_bit)
371     cpu->cd.arm.r[rd] = cpu->cd.arm.tisr;
372     else {
373     /* Writing clears interrupts: */
374     cpu->cd.arm.tisr &= ~cpu->cd.arm.r[rd];
375     if (!(cpu->cd.arm.tisr & TISR_TMR0))
376     cpu_interrupt_ack(cpu, 9); /* TMR0 */
377     if (!(cpu->cd.arm.tisr & TISR_TMR1))
378     cpu_interrupt_ack(cpu, 10); /* TMR1 */
379     }
380 dpavlin 14 break;
381 dpavlin 22 case 7: /* wdtcr: */
382     if (l_bit)
383     cpu->cd.arm.r[rd] = cpu->cd.arm.wdtcr;
384     else
385     cpu->cd.arm.wdtcr = cpu->cd.arm.r[rd];
386     break;
387     default:goto unknown;
388 dpavlin 14 }
389     break;
390 dpavlin 22
391     default:goto unknown;
392 dpavlin 14 }
393 dpavlin 22
394     return;
395    
396     unknown:
397     fatal("arm_coproc_i80321_6: unimplemented opcode1=%i opcode2=%i crn="
398     "%i crm=%i rd=%i l=%i)\n", opcode1, opcode2, crn, crm, rd, l_bit);
399     exit(1);
400 dpavlin 14 }
401    
402    
403     /*
404 dpavlin 22 * arm_coproc_xscale_14():
405 dpavlin 14 *
406 dpavlin 22 * XScale coprocessor 14, Performance Monitoring Unit.
407 dpavlin 14 */
408 dpavlin 22 void arm_coproc_xscale_14(struct cpu *cpu, int opcode1, int opcode2, int l_bit,
409 dpavlin 14 int crn, int crm, int rd)
410     {
411 dpavlin 22 if (opcode2 != 0) {
412     fatal("TODO: opcode2 = %i\n", opcode2);
413     goto unknown;
414     }
415    
416 dpavlin 14 switch (crm) {
417 dpavlin 22
418     case 0: switch (crn) {
419     case 0: if (l_bit)
420     cpu->cd.arm.r[rd] = cpu->cd.arm.xsc1_pmnc;
421     else
422     cpu->cd.arm.xsc1_pmnc = cpu->cd.arm.r[rd];
423     break;
424     case 1: if (l_bit)
425     cpu->cd.arm.r[rd] = cpu->cd.arm.xsc1_ccnt;
426     else
427     cpu->cd.arm.xsc1_ccnt = cpu->cd.arm.r[rd];
428     break;
429     case 2: if (l_bit)
430     cpu->cd.arm.r[rd] = cpu->cd.arm.xsc1_pmn0;
431     else
432     cpu->cd.arm.xsc1_pmn0 = cpu->cd.arm.r[rd];
433     break;
434     case 3: if (l_bit)
435     cpu->cd.arm.r[rd] = cpu->cd.arm.xsc1_pmn1;
436     else
437     cpu->cd.arm.xsc1_pmn1 = cpu->cd.arm.r[rd];
438     break;
439     case 7: /* UNIMPLEMENTED!!! TODO */
440     /* Possibly some kind of idle or sleep function. */
441     break;
442     default:goto unknown;
443     }
444 dpavlin 14 break;
445 dpavlin 22
446     case 1: switch (crn) {
447     case 0: if (l_bit)
448     cpu->cd.arm.r[rd] = cpu->cd.arm.xsc2_pmnc;
449     else
450     cpu->cd.arm.xsc2_pmnc = cpu->cd.arm.r[rd];
451     break;
452     case 1: if (l_bit)
453     cpu->cd.arm.r[rd] = cpu->cd.arm.xsc2_ccnt;
454     else
455     cpu->cd.arm.xsc2_ccnt = cpu->cd.arm.r[rd];
456     break;
457     case 4: if (l_bit)
458     cpu->cd.arm.r[rd] = cpu->cd.arm.xsc2_inten;
459     else
460     cpu->cd.arm.xsc2_inten = cpu->cd.arm.r[rd];
461     break;
462     case 5: if (l_bit)
463     cpu->cd.arm.r[rd] = cpu->cd.arm.xsc2_flag;
464     else
465     cpu->cd.arm.xsc2_flag = cpu->cd.arm.r[rd];
466     break;
467     case 8: if (l_bit)
468     cpu->cd.arm.r[rd] = cpu->cd.arm.xsc2_evtsel;
469     else
470     cpu->cd.arm.xsc2_evtsel = cpu->cd.arm.r[rd];
471     break;
472     default:goto unknown;
473     }
474     break;
475    
476     case 2: switch (crn) {
477     case 0: if (l_bit)
478     cpu->cd.arm.r[rd] = cpu->cd.arm.xsc2_pmn0;
479     else
480     cpu->cd.arm.xsc2_pmn0 = cpu->cd.arm.r[rd];
481     break;
482     case 1: if (l_bit)
483     cpu->cd.arm.r[rd] = cpu->cd.arm.xsc2_pmn1;
484     else
485     cpu->cd.arm.xsc2_pmn1 = cpu->cd.arm.r[rd];
486     break;
487     case 2: if (l_bit)
488     cpu->cd.arm.r[rd] = cpu->cd.arm.xsc2_pmn2;
489     else
490     cpu->cd.arm.xsc2_pmn2 = cpu->cd.arm.r[rd];
491     break;
492     case 3: if (l_bit)
493     cpu->cd.arm.r[rd] = cpu->cd.arm.xsc2_pmn3;
494     else
495     cpu->cd.arm.xsc2_pmn3 = cpu->cd.arm.r[rd];
496     break;
497     default:goto unknown;
498     }
499     break;
500    
501     default:goto unknown;
502 dpavlin 14 }
503 dpavlin 22
504     return;
505    
506     unknown:
507     fatal("arm_coproc_xscale_14: unimplemented opcode1=%i opcode2="
508     "%i crn=%i crm=%i rd=%i l=%i)\n", opcode1, opcode2, crn,
509     crm, rd, l_bit);
510     exit(1);
511 dpavlin 14 }
512    

  ViewVC Help
Powered by ViewVC 1.1.26