/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 18 - (show annotations)
Mon Oct 8 16:19:11 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 7726 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1004 2005/10/27 14:01:10 debug Exp $
20051011        Passing -A as the default boot arg for CATS (works fine with
                OpenBSD/cats).
20051012	Fixing the VGA cursor offset bug, and speeding up framebuffer
		redraws if character cells contain the same thing as during
		the last redraw.
20051013	Adding a slow strd ARM instruction hack.
20051017	Minor updates: Adding a dummy i80321 Verde controller (for
		XScale emulation), fixing the disassembly of the ARM "ldrd"
		instruction, adding "support" for less-than-4KB pages for ARM
		(by not adding them to translation tables).
20051020	Continuing on some HPCarm stuff. A NetBSD/hpcarm kernel prints
		some boot messages on an emulated Jornada 720.
		Making dev_ram work better with dyntrans (speeds up some things
		quite a bit).
20051021	Automatically generating some of the most common ARM load/store
		multiple instructions.
20051022	Better statistics gathering for the ARM load/store multiple.
		Various other dyntrans and device updates.
20051023	Various minor updates.
20051024	Continuing; minor device and dyntrans fine-tuning. Adding the
		first "reasonable" instruction combination hacks for ARM (the
		cores of NetBSD/cats' memset and memcpy).
20051025	Fixing a dyntrans-related bug in dev_vga. Also changing the
		dyntrans low/high access notification to only be updated on
		writes, not reads. Hopefully it will be enough. (dev_vga in
		charcell mode now seems to work correctly with both reads and
		writes.)
		Experimenting with gathering dyntrans statistics (which parts
		of emulated RAM that are actually executed), and adding
		instruction combination hacks for cache cleaning and a part of
		NetBSD's scanc() function.
20051026	Adding a bitmap for ARM emulation which indicates if a page is
		(specifically) user accessible; loads and stores with the t-
		flag set can now use the translation arrays, which results in
		a measurable speedup.
20051027	Dyntrans updates; adding an extra bitmap array for 32-bit
		emulation modes, speeding up the check whether a physical page
		has any code translations or not (O(n) -> O(1)). Doing a
		similar reduction of O(n) to O(1) by avoiding the scan through
		the translation entries on a translation update (32-bit mode
		only).
		Various other minor hacks.
20051029	Quick release, without any testing at all.

==============  RELEASE 0.3.6.2  ==============


1 /*
2 * Copyright (C) 2005 Anders Gavare. All rights reserved.
3 *
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 * $Id: cpu_arm_coproc.c,v 1.13 2005/10/26 14:37:02 debug Exp $
29 *
30 * ARM coprocessor emulation.
31 */
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <ctype.h>
37
38 #include "cpu.h"
39 #include "misc.h"
40 #include "symbol.h"
41
42
43 /*
44 * arm_coproc_15():
45 *
46 * The system control coprocessor.
47 */
48 void arm_coproc_15(struct cpu *cpu, int opcode1, int opcode2, int l_bit,
49 int crn, int crm, int rd)
50 {
51 uint32_t old_control;
52
53 /* Some sanity checks: */
54 if (opcode1 != 0) {
55 fatal("arm_coproc_15: opcode1 = %i, should be 0\n", opcode1);
56 exit(1);
57 }
58 if (rd == ARM_PC) {
59 fatal("arm_coproc_15: rd = PC\n");
60 exit(1);
61 }
62
63 switch (crn) {
64
65 case 0: /* Main ID register: */
66 if (opcode2 != 0)
67 fatal("[ arm_coproc_15: TODO: cr0, opcode2=%i ]\n",
68 opcode2);
69 if (l_bit)
70 cpu->cd.arm.r[rd] = cpu->cd.arm.cpu_type.cpu_id;
71 else
72 fatal("[ arm_coproc_15: attempt to write to cr0? ]\n");
73 break;
74
75 case 1: /* Control Register: */
76 if (l_bit) {
77 cpu->cd.arm.r[rd] = cpu->cd.arm.control;
78 return;
79 }
80 /*
81 * Write to control: Check each bit individually:
82 */
83 old_control = cpu->cd.arm.control;
84 cpu->cd.arm.control = cpu->cd.arm.r[rd];
85 if ((old_control & ARM_CONTROL_MMU) !=
86 (cpu->cd.arm.control & ARM_CONTROL_MMU)) {
87 debug("[ %s the MMU ]\n", cpu->cd.arm.control &
88 ARM_CONTROL_MMU? "enabling" : "disabling");
89 cpu->translate_address =
90 cpu->cd.arm.control & ARM_CONTROL_MMU?
91 arm_translate_address_mmu : arm_translate_address;
92 }
93 if ((old_control & ARM_CONTROL_ALIGN) !=
94 (cpu->cd.arm.control & ARM_CONTROL_ALIGN))
95 debug("[ %s alignment checks ]\n", cpu->cd.arm.control &
96 ARM_CONTROL_ALIGN? "enabling" : "disabling");
97 if ((old_control & ARM_CONTROL_CACHE) !=
98 (cpu->cd.arm.control & ARM_CONTROL_CACHE))
99 debug("[ %s the [data] cache ]\n", cpu->cd.arm.control &
100 ARM_CONTROL_CACHE? "enabling" : "disabling");
101 if ((old_control & ARM_CONTROL_WBUFFER) !=
102 (cpu->cd.arm.control & ARM_CONTROL_WBUFFER))
103 debug("[ %s the write buffer ]\n", cpu->cd.arm.control &
104 ARM_CONTROL_WBUFFER? "enabling" : "disabling");
105 if ((old_control & ARM_CONTROL_BIG) !=
106 (cpu->cd.arm.control & ARM_CONTROL_BIG)) {
107 fatal("ERROR: Trying to switch endianness. Not "
108 "supported yet.\n");
109 exit(1);
110 }
111 if ((old_control & ARM_CONTROL_ICACHE) !=
112 (cpu->cd.arm.control & ARM_CONTROL_ICACHE))
113 debug("[ %s the icache ]\n", cpu->cd.arm.control &
114 ARM_CONTROL_ICACHE? "enabling" : "disabling");
115 /* TODO: More bits. */
116 break;
117
118 case 2: /* Translation Table Base register: */
119 /* NOTE: 16 KB aligned. */
120 if (l_bit)
121 cpu->cd.arm.r[rd] = cpu->cd.arm.ttb & 0xffffc000;
122 else {
123 cpu->cd.arm.ttb = cpu->cd.arm.r[rd];
124 if (cpu->cd.arm.ttb & 0x3fff)
125 fatal("[ WARNING! low bits of new TTB non-"
126 "zero? 0x%08x ]\n", cpu->cd.arm.ttb);
127 cpu->cd.arm.ttb &= 0xffffc000;
128 }
129 break;
130
131 case 3: /* Domain Access Control Register: */
132 if (l_bit)
133 cpu->cd.arm.r[rd] = cpu->cd.arm.dacr;
134 else
135 cpu->cd.arm.dacr = cpu->cd.arm.r[rd];
136 break;
137
138 case 5: /* Fault Status Register: */
139 /* Note: Only the lowest 8 bits are defined. */
140 if (l_bit)
141 cpu->cd.arm.r[rd] = cpu->cd.arm.fsr & 0xff;
142 else
143 cpu->cd.arm.fsr = cpu->cd.arm.r[rd] & 0xff;
144 break;
145
146 case 6: /* Fault Address Register: */
147 if (l_bit)
148 cpu->cd.arm.r[rd] = cpu->cd.arm.far;
149 else
150 cpu->cd.arm.far = cpu->cd.arm.r[rd];
151 break;
152
153 case 7: /* Cache functions: */
154 if (l_bit) {
155 fatal("[ arm_coproc_15: attempt to read cr7? ]\n");
156 return;
157 }
158 /* debug("[ arm_coproc_15: cache op: TODO ]\n"); */
159 /* TODO: */
160 break;
161
162 case 8: /* TLB functions: */
163 if (l_bit) {
164 fatal("[ arm_coproc_15: attempt to read cr8? ]\n");
165 return;
166 }
167 /* fatal("[ arm_coproc_15: TLB: op2=%i crm=%i rd=0x%08x ]\n",
168 opcode2, crm, cpu->cd.arm.r[rd]); */
169 if (opcode2 == 0)
170 cpu->invalidate_translation_caches(cpu, 0,
171 INVALIDATE_ALL);
172 else
173 cpu->invalidate_translation_caches(cpu,
174 cpu->cd.arm.r[rd], INVALIDATE_VADDR);
175 break;
176
177 case 13:/* Process ID Register: */
178 if (opcode2 != 0)
179 fatal("[ arm_coproc_15: PID access, but opcode2 "
180 "= %i? (should be 0) ]\n", opcode2);
181 if (crm != 0)
182 fatal("[ arm_coproc_15: PID access, but crm "
183 "= %i? (should be 0) ]\n", crm);
184 if (l_bit)
185 cpu->cd.arm.r[rd] = cpu->cd.arm.pid;
186 else
187 cpu->cd.arm.pid = cpu->cd.arm.r[rd];
188 if (cpu->cd.arm.pid != 0) {
189 fatal("ARM TODO: pid!=0. Fast Context Switch"
190 " Extension not implemented yet\n");
191 exit(1);
192 }
193 break;
194
195 case 15:/* IMPLEMENTATION DEPENDENT! */
196 fatal("[ arm_coproc_15: TODO: IMPLEMENTATION DEPENDENT! ]\n");
197 break;
198
199 default:fatal("arm_coproc_15: unimplemented crn = %i\n", crn);
200 fatal("(opcode1=%i opcode2=%i crm=%i rd=%i l=%i)\n",
201 opcode1, opcode2, crm, rd, l_bit);
202 exit(1);
203 }
204 }
205
206
207 /*****************************************************************************/
208
209
210 /*
211 * arm_coproc_i80321():
212 *
213 * Intel 80321 coprocessor.
214 */
215 void arm_coproc_i80321(struct cpu *cpu, int opcode1, int opcode2, int l_bit,
216 int crn, int crm, int rd)
217 {
218 switch (crm) {
219 case 0: fatal("[ 80321: crm 0: TODO ]\n");
220 break;
221 case 1: fatal("[ 80321: crm 1: TODO ]\n");
222 switch (crn) {
223 case 0: /* tmr0: */
224 break;
225 case 2: /* tcr0: */
226 break;
227 case 4: /* trr0: */
228 break;
229 case 6: /* tisr: */
230 break;
231 default:fatal("arm_coproc_i80321: unimplemented crn = %i\n",
232 crn);
233 fatal("(opcode1=%i opcode2=%i crm=%i rd=%i l=%i)\n",
234 opcode1, opcode2, crm, rd, l_bit);
235 exit(1);
236 }
237 break;
238 default:fatal("arm_coproc_i80321: unimplemented opcode1=%i opcode2=%i"
239 " crn=%i crm=%i rd=%i l=%i)\n", opcode1, opcode2,
240 crn, crm, rd, l_bit);
241 exit(1);
242 }
243 }
244
245
246 /*
247 * arm_coproc_i80321_14():
248 *
249 * Intel 80321 coprocessor 14.
250 */
251 void arm_coproc_i80321_14(struct cpu *cpu, int opcode1, int opcode2, int l_bit,
252 int crn, int crm, int rd)
253 {
254 switch (crm) {
255 case 0: fatal("[ 80321_14: crm 0: TODO ]\n");
256 break;
257 default:fatal("arm_coproc_i80321_14: unimplemented opcode1=%i opcode2="
258 "%i crn=%i crm=%i rd=%i l=%i)\n", opcode1, opcode2,
259 crn, crm, rd, l_bit);
260 exit(1);
261 }
262 }
263

  ViewVC Help
Powered by ViewVC 1.1.26