/[gxemul]/upstream/0.4.6/src/devices/dev_m8820x.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 /upstream/0.4.6/src/devices/dev_m8820x.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 43 - (show annotations)
Mon Oct 8 16:22:43 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 6378 byte(s)
0.4.6
1 /*
2 * Copyright (C) 2007 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: dev_m8820x.c,v 1.8 2007/06/15 19:11:15 debug Exp $
29 *
30 * COMMENT: M88200/M88204 CMMU (Cache/Memory Management Unit)
31 */
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #include "cpu.h"
38 #include "device.h"
39 #include "emul.h"
40 #include "machine.h"
41 #include "memory.h"
42 #include "misc.h"
43
44
45 #include "m8820x.h"
46 #include "m8820x_pte.h"
47
48 struct m8820x_data {
49 int cmmu_nr;
50 };
51
52
53 /*
54 * m8820x_command():
55 *
56 * Handle M8820x commands written to the System Command Register.
57 */
58 static void m8820x_command(struct cpu *cpu, struct m8820x_data *d)
59 {
60 uint32_t *regs = cpu->cd.m88k.cmmu[d->cmmu_nr]->reg;
61 int cmd = regs[CMMU_SCR];
62 uint32_t sar = regs[CMMU_SAR];
63 int i, super, all;
64
65 switch (cmd) {
66
67 case CMMU_FLUSH_CACHE_CB_LINE:
68 case CMMU_FLUSH_CACHE_INV_LINE:
69 case CMMU_FLUSH_CACHE_INV_ALL:
70 case CMMU_FLUSH_CACHE_CBI_LINE:
71 case CMMU_FLUSH_CACHE_CBI_PAGE:
72 case CMMU_FLUSH_CACHE_CBI_SEGMENT:
73 case CMMU_FLUSH_CACHE_CBI_ALL:
74 /* TODO */
75 break;
76
77 case CMMU_FLUSH_USER_ALL:
78 case CMMU_FLUSH_USER_PAGE:
79 case CMMU_FLUSH_SUPER_ALL:
80 case CMMU_FLUSH_SUPER_PAGE:
81 /* TODO: Segment invalidation. */
82
83 all = super = 0;
84 if (cmd == CMMU_FLUSH_USER_ALL ||
85 cmd == CMMU_FLUSH_SUPER_ALL)
86 all = 1;
87 if (cmd == CMMU_FLUSH_SUPER_ALL ||
88 cmd == CMMU_FLUSH_SUPER_PAGE)
89 super = M8820X_PATC_SUPERVISOR_BIT;
90
91 /* TODO: Don't invalidate EVERYTHING like this! */
92 cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);
93
94 for (i=0; i<N_M88200_PATC_ENTRIES; i++) {
95 uint32_t v = cpu->cd.m88k.cmmu[d->cmmu_nr]
96 ->patc_v_and_control[i];
97 uint32_t p = cpu->cd.m88k.cmmu[d->cmmu_nr]
98 ->patc_p_and_supervisorbit[i];
99
100 /* Already invalid? Then skip this entry. */
101 if (!(v & PG_V))
102 continue;
103
104 /* Super/user mismatch? Then skip the entry. */
105 if ((p & M8820X_PATC_SUPERVISOR_BIT) != super)
106 continue;
107
108 /* If not all pages are to be invalidated, there
109 must be a virtual address match: */
110 if (!all && (sar & 0xfffff000) != (v & 0xfffff000))
111 continue;
112
113 /* Finally, invalidate the entry: */
114 cpu->cd.m88k.cmmu[d->cmmu_nr]->patc_v_and_control[i]
115 = v & ~PG_V;
116 }
117
118 break;
119
120 default:
121 fatal("[ m8820x_command: FATAL ERROR! unimplemented "
122 "command 0x%02x ]\n", cmd);
123 exit(1);
124 }
125 }
126
127
128 DEVICE_ACCESS(m8820x)
129 {
130 uint64_t idata = 0, odata = 0;
131 struct m8820x_data *d = extra;
132 uint32_t *regs = cpu->cd.m88k.cmmu[d->cmmu_nr]->reg;
133 uint32_t *batc = cpu->cd.m88k.cmmu[d->cmmu_nr]->batc;
134
135 if (writeflag == MEM_WRITE)
136 idata = memory_readmax64(cpu, data, len);
137
138 if (writeflag == MEM_READ)
139 odata = regs[relative_addr / sizeof(uint32_t)];
140
141 switch (relative_addr / sizeof(uint32_t)) {
142
143 case CMMU_IDR:
144 if (writeflag == MEM_WRITE) {
145 fatal("m8820x: write to CMMU_IDR: TODO\n");
146 exit(1);
147 }
148 break;
149
150 case CMMU_SCR:
151 if (writeflag == MEM_READ) {
152 fatal("m8820x: read from CMMU_SCR: TODO\n");
153 exit(1);
154 } else {
155 regs[relative_addr / sizeof(uint32_t)] = idata;
156 m8820x_command(cpu, d);
157 }
158 break;
159
160 case CMMU_SSR:
161 if (writeflag == MEM_WRITE) {
162 fatal("m8820x: write to CMMU_SSR: TODO\n");
163 exit(1);
164 }
165 break;
166
167 case CMMU_PFSR:
168 case CMMU_PFAR:
169 case CMMU_SAR:
170 case CMMU_SCTR:
171 case CMMU_SAPR: /* TODO: Invalidate something for */
172 case CMMU_UAPR: /* SAPR and UAPR writes? */
173 /* TODO: Don't invalidate everything. */
174 cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);
175 if (writeflag == MEM_WRITE)
176 regs[relative_addr / sizeof(uint32_t)] = idata;
177 break;
178
179 case CMMU_BWP0:
180 case CMMU_BWP1:
181 case CMMU_BWP2:
182 case CMMU_BWP3:
183 case CMMU_BWP4:
184 case CMMU_BWP5:
185 case CMMU_BWP6:
186 case CMMU_BWP7:
187 if (writeflag == MEM_WRITE) {
188 uint32_t old;
189
190 regs[relative_addr / sizeof(uint32_t)] = idata;
191
192 /* Also write to the specific batc registers: */
193 old = batc[(relative_addr / sizeof(uint32_t))
194 - CMMU_BWP0];
195 batc[(relative_addr / sizeof(uint32_t)) - CMMU_BWP0]
196 = idata;
197 if (old != idata) {
198 /* TODO: Don't invalidate everything? */
199 cpu->invalidate_translation_caches(
200 cpu, 0, INVALIDATE_ALL);
201 }
202 }
203 break;
204
205 case CMMU_CSSP0:
206 /* TODO: Actually care about cache details. */
207 break;
208
209 default:fatal("[ m8820x: unimplemented %s offset 0x%x",
210 writeflag == MEM_WRITE? "write to" : "read from",
211 (int) relative_addr);
212 if (writeflag == MEM_WRITE)
213 fatal(": 0x%x", (int)idata);
214 fatal(" ]\n");
215 exit(1);
216 }
217
218 if (writeflag == MEM_READ)
219 memory_writemax64(cpu, data, len, odata);
220
221 return 1;
222 }
223
224
225 DEVINIT(m8820x)
226 {
227 struct m8820x_data *d;
228
229 CHECK_ALLOCATION(d = malloc(sizeof(struct m8820x_data)));
230 memset(d, 0, sizeof(struct m8820x_data));
231
232 d->cmmu_nr = devinit->addr2;
233
234 memory_device_register(devinit->machine->memory, devinit->name,
235 devinit->addr, M8820X_LENGTH, dev_m8820x_access, (void *)d,
236 DM_DEFAULT, NULL);
237
238 return 1;
239 }
240

  ViewVC Help
Powered by ViewVC 1.1.26