/[gxemul]/upstream/0.4.4/src/cpus/cpu_alpha_palcode.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.4/src/cpus/cpu_alpha_palcode.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 35 - (show annotations)
Mon Oct 8 16:21:26 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 10172 byte(s)
0.4.4
1 /*
2 * Copyright (C) 2005-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: cpu_alpha_palcode.c,v 1.16 2006/12/30 13:30:53 debug Exp $
29 *
30 * Alpha PALcode-related functionality.
31 *
32 * (See http://www.alphalinux.org/docs/alphaahb.html for good descriptions
33 * of many PALcode functions.)
34 */
35
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <ctype.h>
41
42 #include "misc.h"
43
44
45 #ifndef ENABLE_ALPHA
46
47
48 #include "cpu_alpha.h"
49
50
51 void alpha_palcode_name(uint32_t palcode, char *buf, size_t buflen)
52 { buf[0]='\0'; }
53 void alpha_palcode(struct cpu *cpu, uint32_t palcode) { }
54
55
56 #else /* ENABLE_ALPHA */
57
58
59 #include "alpha_prom.h"
60 #include "console.h"
61 #include "cpu.h"
62 #include "machine.h"
63 #include "memory.h"
64 #include "symbol.h"
65
66
67 /*
68 * alpha_palcode_name():
69 *
70 * Return the name of a PALcode number, as a string.
71 */
72 void alpha_palcode_name(uint32_t palcode, char *buf, size_t buflen)
73 {
74 switch (palcode) {
75 case 0x10: snprintf(buf, buflen, "PAL_OSF1_rdmces"); break;
76 case 0x11: snprintf(buf, buflen, "PAL_OSF1_wrmces"); break;
77 case 0x2b: snprintf(buf, buflen, "PAL_OSF1_wrfen"); break;
78 case 0x2d: snprintf(buf, buflen, "PAL_OSF1_wrvptptr"); break;
79 case 0x30: snprintf(buf, buflen, "PAL_OSF1_swpctx"); break;
80 case 0x31: snprintf(buf, buflen, "PAL_OSF1_wrval"); break;
81 case 0x32: snprintf(buf, buflen, "PAL_OSF1_rdval"); break;
82 case 0x33: snprintf(buf, buflen, "PAL_OSF1_tbi"); break;
83 case 0x34: snprintf(buf, buflen, "PAL_OSF1_wrent"); break;
84 case 0x35: snprintf(buf, buflen, "PAL_OSF1_swpipl"); break;
85 case 0x36: snprintf(buf, buflen, "PAL_OSF1_rdps"); break;
86 case 0x37: snprintf(buf, buflen, "PAL_OSF1_wrkgp"); break;
87 case 0x38: snprintf(buf, buflen, "PAL_OSF1_wrusp"); break;
88 case 0x39: snprintf(buf, buflen, "PAL_OSF1_wrperfmon"); break;
89 case 0x3a: snprintf(buf, buflen, "PAL_OSF1_rdusp"); break;
90 case 0x3c: snprintf(buf, buflen, "PAL_OSF1_whami"); break;
91 case 0x3d: snprintf(buf, buflen, "PAL_OSF1_retsys"); break;
92 case 0x3f: snprintf(buf, buflen, "PAL_OSF1_rti"); break;
93 case 0x81: snprintf(buf, buflen, "PAL_bugchk"); break;
94 case 0x83: snprintf(buf, buflen, "PAL_OSF1_callsys"); break;
95 case 0x86: snprintf(buf, buflen, "PAL_OSF1_imb"); break;
96 case 0x92: snprintf(buf, buflen, "PAL_OSF1_urti"); break;
97 case 0x3fffffe: snprintf(buf, buflen, "GXemul_PROM"); break;
98 default:snprintf(buf, buflen, "UNKNOWN 0x%"PRIx32, palcode);
99 }
100 }
101
102
103 /*
104 * alpha_prom_call():
105 */
106 void alpha_prom_call(struct cpu *cpu)
107 {
108 uint64_t addr, a1 = cpu->cd.alpha.r[ALPHA_A1];
109 uint64_t a2 = cpu->cd.alpha.r[ALPHA_A2], a3 = cpu->cd.alpha.r[ALPHA_A3];
110 uint64_t len;
111 char *s = "";
112
113 switch (cpu->cd.alpha.r[ALPHA_A0]) {
114
115 case PROM_R_PUTS:
116 /* a1 = channel, a2 = ptr to buf, a3 = len */
117 for (addr = a2; addr < a2 + a3; addr ++) {
118 unsigned char ch;
119 cpu->memory_rw(cpu, cpu->mem, addr, &ch, sizeof(ch),
120 MEM_READ, CACHE_DATA | NO_EXCEPTIONS);
121 console_putchar(cpu->machine->main_console_handle, ch);
122 }
123 cpu->cd.alpha.r[ALPHA_V0] = a3;
124 break;
125
126 case PROM_R_GETENV:
127 /* a1 = variable id, a2 = char *buf, a3 = bufsize */
128 switch (a1) {
129 case PROM_E_BOOTED_DEV:
130 s = ""; /* TODO */
131 break;
132 case PROM_E_BOOTED_FILE:
133 s = cpu->machine->boot_kernel_filename;
134 break;
135 case PROM_E_BOOTED_OSFLAGS:
136 s = cpu->machine->boot_string_argument;
137 break;
138 case PROM_E_TTY_DEV:
139 s = ""; /* TODO */
140 break;
141 default:fatal("[ Alpha PALcode: GXemul PROM getenv %i: TODO "
142 "]\n", cpu->cd.alpha.r[ALPHA_A1]);
143 cpu->running = 0;
144 }
145 /* Copy at most a3 bytes. */
146 len = a3;
147 if (strlen(s) < len)
148 len = strlen(s) + 1;
149 store_buf(cpu, a2, s, len);
150 break;
151
152 default:fatal("[ Alpha PALcode: GXemul PROM call, a0=0x%"PRIx64" ]\n",
153 (uint64_t) cpu->cd.alpha.r[ALPHA_A0]);
154 cpu->running = 0;
155 }
156
157 /* Return from the PROM call. */
158 cpu->pc = cpu->cd.alpha.r[ALPHA_RA];
159 }
160
161
162 /*
163 * alpha_palcode():
164 *
165 * Execute an Alpha PALcode instruction. (Most of these correspond to
166 * OSF1 palcodes, used by for example NetBSD/alpha.)
167 */
168 void alpha_palcode(struct cpu *cpu, uint32_t palcode)
169 {
170 uint64_t a0 = cpu->cd.alpha.r[ALPHA_A0], a1 = cpu->cd.alpha.r[ALPHA_A1];
171
172 switch (palcode) {
173 case 0x02: /* PAL_draina */
174 /* TODO? */
175 break;
176 case 0x10: /* PAL_OSF1_rdmces */
177 /* TODO. Return Machine Check status in v0. */
178 cpu->cd.alpha.r[ALPHA_V0] = 0;
179 break;
180 case 0x11: /* PAL_OSF1_wrmces */
181 /* TODO. Clear Machine Check and Error status. */
182 break;
183 case 0x2b: /* PAL_OSF1_wrfen */
184 /* Floating point enable: a0 = 1 or 0. */
185 /* TODO */
186 break;
187 case 0x2d: /* PAL_OSF1_wrvptptr */
188 /* Write Virtual Page Table Pointer. a0 = value */
189 cpu->cd.alpha.vptptr = a0;
190 break;
191 case 0x30: /* PAL_OSF1_swpctx */
192 /* Save old context: */
193 store_64bit_word(cpu, cpu->cd.alpha.ctx + 0,
194 cpu->cd.alpha.pcb.apcb_ksp);
195 store_64bit_word(cpu, cpu->cd.alpha.ctx + 8,
196 cpu->cd.alpha.pcb.apcb_usp);
197 store_64bit_word(cpu, cpu->cd.alpha.ctx + 16,
198 cpu->cd.alpha.pcb.apcb_ptbr);
199 store_32bit_word(cpu, cpu->cd.alpha.ctx + 24,
200 cpu->cd.alpha.pcb.apcb_cpc);
201 store_32bit_word(cpu, cpu->cd.alpha.ctx + 28,
202 cpu->cd.alpha.pcb.apcb_asn);
203 store_64bit_word(cpu, cpu->cd.alpha.ctx + 32,
204 cpu->cd.alpha.pcb.apcb_unique);
205 store_64bit_word(cpu, cpu->cd.alpha.ctx + 40,
206 cpu->cd.alpha.pcb.apcb_flags);
207 store_64bit_word(cpu, cpu->cd.alpha.ctx + 48,
208 cpu->cd.alpha.pcb.apcb_decrsv0);
209 store_64bit_word(cpu, cpu->cd.alpha.ctx + 56,
210 cpu->cd.alpha.pcb.apcb_decrsv1);
211 /* Load new context: */
212 cpu->cd.alpha.ctx = a0;
213 cpu->cd.alpha.pcb.apcb_ksp =
214 load_64bit_word(cpu, cpu->cd.alpha.ctx + 0);
215 cpu->cd.alpha.pcb.apcb_usp =
216 load_64bit_word(cpu, cpu->cd.alpha.ctx + 8);
217 cpu->cd.alpha.pcb.apcb_ptbr =
218 load_64bit_word(cpu, cpu->cd.alpha.ctx + 16);
219 cpu->cd.alpha.pcb.apcb_cpc =
220 load_64bit_word(cpu, cpu->cd.alpha.ctx + 24);
221 cpu->cd.alpha.pcb.apcb_asn =
222 load_64bit_word(cpu, cpu->cd.alpha.ctx + 28);
223 cpu->cd.alpha.pcb.apcb_unique =
224 load_64bit_word(cpu, cpu->cd.alpha.ctx + 32);
225 cpu->cd.alpha.pcb.apcb_flags =
226 load_64bit_word(cpu, cpu->cd.alpha.ctx + 40);
227 cpu->cd.alpha.pcb.apcb_decrsv0 =
228 load_64bit_word(cpu, cpu->cd.alpha.ctx + 48);
229 cpu->cd.alpha.pcb.apcb_decrsv1 =
230 load_64bit_word(cpu, cpu->cd.alpha.ctx + 56);
231 break;
232 case 0x31: /* PAL_OSF1_wrval */
233 /* a0 = value */
234 cpu->cd.alpha.sysvalue = a0;
235 break;
236 case 0x32: /* PAL_OSF1_rdval */
237 /* return: v0 = value */
238 cpu->cd.alpha.r[ALPHA_V0] = cpu->cd.alpha.sysvalue;
239 break;
240 case 0x33: /* PAL_OSF1_tbi */
241 /*
242 * a0 = op, a1 = vaddr
243 */
244 fatal("[ Alpha PALcode: PAL_OSF1_tbi: a0=%"PRIi64" a1=0x%"
245 PRIx64" ]\n", (int64_t)a0, (uint64_t)a1);
246 cpu->invalidate_translation_caches(cpu, a1, INVALIDATE_VADDR);
247 break;
248 case 0x34: /* PAL_OSF1_wrent (Write System Entry Address) */
249 /* a0 = new vector, a1 = vector selector */
250 if (a1 < N_ALPHA_KENTRY)
251 cpu->cd.alpha.kentry[a1] = a0;
252 else {
253 fatal("[ Alpha PALcode: PAL_OSF1_wrent: attempt to "
254 "write to non-implemented selector %i ]\n",
255 (int)a1);
256 cpu->running = 0;
257 }
258 break;
259 case 0x35: /* PAL_OSF1_swpipl */
260 /* a0 = new ipl, v0 = return old ipl */
261 cpu->cd.alpha.r[ALPHA_V0] = cpu->cd.alpha.ipl;
262 cpu->cd.alpha.ipl = a0;
263 break;
264 case 0x36: /* PAL_OSF1_rdps */
265 /* TODO */
266 cpu->cd.alpha.r[ALPHA_V0] = 0;
267 break;
268 case 0x37: /* PAL_OSF1_wrkgp */
269 /* "clobbers a0, t0, t8-t11" according to comments in
270 NetBSD sources */
271 cpu->cd.alpha.kgp = a0;
272 break;
273 case 0x38: /* PAL_OSF1_wrusp */
274 /* a0 = value */
275 cpu->cd.alpha.pcb.apcb_usp = a0;
276 break;
277 case 0x3a: /* PAL_OSF1_rdusp */
278 /* return: v0 = value */
279 cpu->cd.alpha.r[ALPHA_V0] = cpu->cd.alpha.pcb.apcb_usp;
280 break;
281 case 0x3c: /* PAL_OSF1_whami */
282 /* Returns CPU id in v0: */
283 cpu->cd.alpha.r[ALPHA_V0] = cpu->cpu_id;
284 break;
285 case 0x81: /* PAL_bugchk */
286 cpu->running = 0;
287 break;
288 case 0x83: /* PAL_OSF1_syscall */
289 if (cpu->machine->userland_emul != NULL)
290 useremul_syscall(cpu, 0);
291 else {
292 fatal("[ Alpha PALcode: syscall, but no"
293 " syscall handler? ]\n");
294 cpu->running = 0;
295 }
296 break;
297 case 0x86: /* PAL_OSF1_imb */
298 /* TODO */
299 break;
300 case 0x3fffffc:
301 fatal("[ Alpha: KENTRY not set! Halting. ]");
302 cpu->running = 0;
303 break;
304 case 0x3fffffd:
305 fatal("[ Alpha PALcode: Fixup: TODO ]\n");
306 /* Return from the fixup call. */
307 cpu->cd.alpha.r[ALPHA_V0] = 0; /* Success? */
308 cpu->pc = cpu->cd.alpha.r[ALPHA_RA];
309 break;
310 case 0x3fffffe:
311 alpha_prom_call(cpu);
312 break;
313 default:fatal("[ Alpha PALcode 0x%x unimplemented! ]\n", palcode);
314 cpu->running = 0;
315 }
316 }
317
318
319 #endif /* ENABLE_ALPHA */

  ViewVC Help
Powered by ViewVC 1.1.26