Annotation of sys/arch/m88k/m88k/m88100_machdep.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: m88100_machdep.c,v 1.3 2007/05/20 20:12:31 miod Exp $ */
2: /*
3: * Mach Operating System
4: * Copyright (c) 1993-1991 Carnegie Mellon University
5: * Copyright (c) 1991 OMRON Corporation
6: * All Rights Reserved.
7: *
8: * Permission to use, copy, modify and distribute this software and its
9: * documentation is hereby granted, provided that both the copyright
10: * notice and this permission notice appear in all copies of the
11: * software, derivative works or modified versions, and any portions
12: * thereof, and that both notices appear in supporting documentation.
13: *
14: * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15: * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
16: * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17: *
18: * Carnegie Mellon requests users of this software to return to
19: *
20: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
21: * School of Computer Science
22: * Carnegie Mellon University
23: * Pittsburgh PA 15213-3890
24: *
25: * any improvements or extensions that they make and grant Carnegie the
26: * rights to redistribute these changes.
27: */
28:
29: #include "assym.h" /* EF_xxx */
30:
31: #include <sys/param.h>
32: #include <sys/systm.h>
33:
34: #include <machine/asm_macro.h>
35: #include <m88k/m88100.h>
36:
37: /*
38: * Data Access Emulation for M88100 exceptions
39: */
40:
41: #define DMT_BYTE 1
42: #define DMT_HALF 2
43: #define DMT_WORD 4
44:
45: const struct {
46: unsigned char offset;
47: unsigned char size;
48: } dmt_en_info[16] = {
49: {0, 0}, {3, DMT_BYTE}, {2, DMT_BYTE}, {2, DMT_HALF},
50: {1, DMT_BYTE}, {0, 0}, {0, 0}, {0, 0},
51: {0, DMT_BYTE}, {0, 0}, {0, 0}, {0, 0},
52: {0, DMT_HALF}, {0, 0}, {0, 0}, {0, DMT_WORD}
53: };
54:
55: #ifdef DATA_DEBUG
56: int data_access_emulation_debug = 0;
57: #define DAE_DEBUG(stuff) \
58: do { \
59: if (data_access_emulation_debug != 0) { \
60: stuff; \
61: } \
62: } while (0)
63: #else
64: #define DAE_DEBUG(stuff)
65: #endif
66:
67: void
68: dae_print(unsigned *eframe)
69: {
70: int x;
71: unsigned dmax, dmdx, dmtx;
72:
73: if (!ISSET(eframe[EF_DMT0], DMT_VALID))
74: return;
75:
76: for (x = 0; x < 3; x++) {
77: dmtx = eframe[EF_DMT0 + x * 3];
78: if (!ISSET(dmtx, DMT_VALID))
79: continue;
80:
81: dmdx = eframe[EF_DMD0 + x * 3];
82: dmax = eframe[EF_DMA0 + x * 3];
83:
84: if (ISSET(dmtx, DMT_WRITE))
85: printf("[DMT%d=%x: st.%c %x to %x as %d %s %s]\n",
86: x, dmtx, dmtx & DMT_DAS ? 's' : 'u', dmdx, dmax,
87: DMT_ENBITS(dmtx),
88: dmtx & DMT_DOUB1 ? "double": "not double",
89: dmtx & DMT_LOCKBAR ? "xmem": "not xmem");
90: else
91: printf("[DMT%d=%x: ld.%c r%d <- %x as %d %s %s]\n",
92: x, dmtx, dmtx & DMT_DAS ? 's' : 'u',
93: DMT_DREGBITS(dmtx), dmax, DMT_ENBITS(dmtx),
94: dmtx & DMT_DOUB1 ? "double": "not double",
95: dmtx & DMT_LOCKBAR ? "xmem": "not xmem");
96: }
97: }
98:
99: void
100: data_access_emulation(unsigned *eframe)
101: {
102: int x;
103: unsigned dmax, dmdx, dmtx;
104: unsigned v, reg;
105:
106: dmtx = eframe[EF_DMT0];
107: if (!ISSET(dmtx, DMT_VALID))
108: return;
109:
110: for (x = 0; x < 3; x++) {
111: dmtx = eframe[EF_DMT0 + x * 3];
112: if (!ISSET(dmtx, DMT_VALID) || ISSET(dmtx, DMT_SKIP))
113: continue;
114:
115: dmdx = eframe[EF_DMD0 + x * 3];
116: dmax = eframe[EF_DMA0 + x * 3];
117:
118: DAE_DEBUG(
119: if (ISSET(dmtx, DMT_WRITE))
120: printf("[DMT%d=%x: st.%c %x to %x as %d %s %s]\n",
121: x, dmtx, dmtx & DMT_DAS ? 's' : 'u', dmdx, dmax,
122: DMT_ENBITS(dmtx),
123: dmtx & DMT_DOUB1 ? "double": "not double",
124: dmtx & DMT_LOCKBAR ? "xmem": "not xmem");
125: else
126: printf("[DMT%d=%x: ld.%c r%d <- %x as %d %s %s]\n",
127: x, dmtx, dmtx & DMT_DAS ? 's' : 'u',
128: DMT_DREGBITS(dmtx), dmax, DMT_ENBITS(dmtx),
129: dmtx & DMT_DOUB1 ? "double": "not double",
130: dmtx & DMT_LOCKBAR ? "xmem": "not xmem")
131: );
132:
133: dmax += dmt_en_info[DMT_ENBITS(dmtx)].offset;
134: reg = DMT_DREGBITS(dmtx);
135:
136: if (!ISSET(dmtx, DMT_LOCKBAR)) {
137: /* the fault is not during an XMEM */
138:
139: if (x == 2 && ISSET(dmtx, DMT_DOUB1)) {
140: /* pipeline 2 (earliest stage) for a double */
141:
142: if (ISSET(dmtx, DMT_WRITE)) {
143: /*
144: * STORE DOUBLE WILL BE REINITIATED
145: * BY rte
146: */
147: } else {
148: /* EMULATE ld.d INSTRUCTION */
149: v = do_load_word(dmax, dmtx & DMT_DAS);
150: if (reg != 0)
151: eframe[EF_R0 + reg] = v;
152: v = do_load_word(dmax ^ 4,
153: dmtx & DMT_DAS);
154: if (reg != 31)
155: eframe[EF_R0 + reg + 1] = v;
156: }
157: } else {
158: /* not pipeline #2 with a double */
159: if (dmtx & DMT_WRITE) {
160: switch (dmt_en_info[DMT_ENBITS(dmtx)].size) {
161: case DMT_BYTE:
162: DAE_DEBUG(
163: printf("[byte %x -> [%x(%c)]\n",
164: dmdx & 0xff, dmax,
165: ISSET(dmtx, DMT_DAS) ? 's' : 'u')
166: );
167: do_store_byte(dmax, dmdx,
168: dmtx & DMT_DAS);
169: break;
170: case DMT_HALF:
171: DAE_DEBUG(
172: printf("[half %x -> [%x(%c)]\n",
173: dmdx & 0xffff, dmax,
174: ISSET(dmtx, DMT_DAS) ? 's' : 'u')
175: );
176: do_store_half(dmax, dmdx,
177: dmtx & DMT_DAS);
178: break;
179: case DMT_WORD:
180: DAE_DEBUG(
181: printf("[word %x -> [%x(%c)]\n",
182: dmdx, dmax,
183: ISSET(dmtx, DMT_DAS) ? 's' : 'u')
184: );
185: do_store_word(dmax, dmdx,
186: dmtx & DMT_DAS);
187: break;
188: }
189: } else {
190: /* else it's a read */
191: switch (dmt_en_info[DMT_ENBITS(dmtx)].size) {
192: case DMT_BYTE:
193: v = do_load_byte(dmax,
194: dmtx & DMT_DAS);
195: if (!ISSET(dmtx, DMT_SIGNED))
196: v &= 0x000000ff;
197: break;
198: case DMT_HALF:
199: v = do_load_half(dmax,
200: dmtx & DMT_DAS);
201: if (!ISSET(dmtx, DMT_SIGNED))
202: v &= 0x0000ffff;
203: break;
204: case DMT_WORD:
205: v = do_load_word(dmax,
206: dmtx & DMT_DAS);
207: break;
208: }
209: DAE_DEBUG(
210: if (reg == 0)
211: printf("[no write to r0 done]\n");
212: else
213: printf("[r%d <- %x]\n", reg, v);
214: );
215: if (reg != 0)
216: eframe[EF_R0 + reg] = v;
217: }
218: }
219: } else {
220: /* if lockbar is set... it's part of an XMEM */
221: /*
222: * According to Motorola's "General Information",
223: * the DMT_DOUB1 bit is never set in this case, as it
224: * should be.
225: * If lockbar is set (as it is if we're here) and if
226: * the write is not set, then it's the same as if DOUB1
227: * was set...
228: */
229: if (!ISSET(dmtx, DMT_WRITE)) {
230: if (x != 2) {
231: /* RERUN xmem WITH DMD(x+1) */
232: x++;
233: dmdx = eframe[EF_DMD0 + x * 3];
234: } else {
235: /* RERUN xmem WITH DMD2 */
236: }
237:
238: if (dmt_en_info[DMT_ENBITS(dmtx)].size ==
239: DMT_WORD) {
240: v = do_xmem_word(dmax, dmdx,
241: dmtx & DMT_DAS);
242: } else {
243: v = do_xmem_byte(dmax, dmdx,
244: dmtx & DMT_DAS);
245: }
246: if (reg != 0)
247: eframe[EF_R0 + reg] = v;
248: } else {
249: if (x == 0) {
250: if (reg != 0)
251: eframe[EF_R0 + reg] = dmdx;
252: eframe[EF_SFIP] = eframe[EF_SNIP];
253: eframe[EF_SNIP] = eframe[EF_SXIP];
254: eframe[EF_SXIP] = 0;
255: /* xmem RERUN ON rte */
256: eframe[EF_DMT0] = 0;
257: return;
258: }
259: }
260: }
261: }
262: eframe[EF_DMT0] = 0;
263: }
264:
265: /*
266: * Routines to patch the kernel code on 88100 systems not affected by
267: * the xxx.usr bug.
268: */
269:
270: void
271: m88100_apply_patches()
272: {
273: #ifdef ERRATA__XXX_USR
274: if (((get_cpu_pid() & PID_VN) >> VN_SHIFT) > 10) {
275: /*
276: * Patch DAE helpers.
277: * before after
278: * branch branch
279: * NOP jmp.n r1
280: * xxx.usr xxx.usr
281: * NOP; NOP; NOP
282: * jmp r1
283: */
284: ((u_int32_t *)(do_load_word))[1] = 0xf400c401;
285: ((u_int32_t *)(do_load_half))[1] = 0xf400c401;
286: ((u_int32_t *)(do_load_byte))[1] = 0xf400c401;
287: ((u_int32_t *)(do_store_word))[1] = 0xf400c401;
288: ((u_int32_t *)(do_store_half))[1] = 0xf400c401;
289: ((u_int32_t *)(do_store_byte))[1] = 0xf400c401;
290: ((u_int32_t *)(do_xmem_word))[1] = 0xf400c401;
291: ((u_int32_t *)(do_xmem_byte))[1] = 0xf400c401;
292: }
293: #endif
294: }
CVSweb