1 |
/* |
/* |
2 |
* Copyright (C) 2005 Anders Gavare. All rights reserved. |
* Copyright (C) 2005-2006 Anders Gavare. All rights reserved. |
3 |
* |
* |
4 |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
5 |
* modification, are permitted provided that the following conditions are met: |
* modification, are permitted provided that the following conditions are met: |
25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: cpu_alpha_palcode.c,v 1.1 2005/08/29 14:36:41 debug Exp $ |
* $Id: cpu_alpha_palcode.c,v 1.8 2006/06/02 18:11:38 debug Exp $ |
29 |
* |
* |
30 |
* Alpha PALcode-related functionality. |
* Alpha PALcode-related functionality. |
31 |
*/ |
*/ |
86 |
case 0x3c: snprintf(buf, buflen, "PAL_OSF1_whami"); break; |
case 0x3c: snprintf(buf, buflen, "PAL_OSF1_whami"); break; |
87 |
case 0x3d: snprintf(buf, buflen, "PAL_OSF1_retsys"); break; |
case 0x3d: snprintf(buf, buflen, "PAL_OSF1_retsys"); break; |
88 |
case 0x3f: snprintf(buf, buflen, "PAL_OSF1_rti"); break; |
case 0x3f: snprintf(buf, buflen, "PAL_OSF1_rti"); break; |
89 |
|
case 0x81: snprintf(buf, buflen, "PAL_bugchk"); break; |
90 |
case 0x83: snprintf(buf, buflen, "PAL_OSF1_callsys"); break; |
case 0x83: snprintf(buf, buflen, "PAL_OSF1_callsys"); break; |
91 |
case 0x86: snprintf(buf, buflen, "PAL_OSF1_imb"); break; |
case 0x86: snprintf(buf, buflen, "PAL_OSF1_imb"); break; |
92 |
case 0x92: snprintf(buf, buflen, "PAL_OSF1_urti"); break; |
case 0x92: snprintf(buf, buflen, "PAL_OSF1_urti"); break; |
105 |
|
|
106 |
switch (cpu->cd.alpha.r[ALPHA_A0]) { |
switch (cpu->cd.alpha.r[ALPHA_A0]) { |
107 |
case 0x02: |
case 0x02: |
108 |
/* put string. a1 = channel, a2 = ptr to buf, a3 = len */ |
/* puts: a1 = channel, a2 = ptr to buf, a3 = len */ |
109 |
for (addr = cpu->cd.alpha.r[ALPHA_A2]; |
for (addr = cpu->cd.alpha.r[ALPHA_A2]; |
110 |
addr < cpu->cd.alpha.r[ALPHA_A2] + |
addr < cpu->cd.alpha.r[ALPHA_A2] + |
111 |
cpu->cd.alpha.r[ALPHA_A3]; addr ++) { |
cpu->cd.alpha.r[ALPHA_A3]; addr ++) { |
117 |
cpu->cd.alpha.r[ALPHA_V0] = cpu->cd.alpha.r[ALPHA_A3]; |
cpu->cd.alpha.r[ALPHA_V0] = cpu->cd.alpha.r[ALPHA_A3]; |
118 |
break; |
break; |
119 |
case 0x22: |
case 0x22: |
120 |
|
/* getenv */ |
121 |
fatal("[ Alpha PALcode: GXemul PROM call 0x22: TODO ]\n"); |
fatal("[ Alpha PALcode: GXemul PROM call 0x22: TODO ]\n"); |
122 |
break; |
break; |
123 |
default:fatal("[ Alpha PALcode: GXemul PROM call, a0=0x%llx ]\n", |
default:fatal("[ Alpha PALcode: GXemul PROM call, a0=0x%"PRIx64" ]\n", |
124 |
(long long)cpu->cd.alpha.r[ALPHA_A0]); |
(uint64_t) cpu->cd.alpha.r[ALPHA_A0]); |
125 |
cpu->running = 0; |
cpu->running = 0; |
126 |
} |
} |
127 |
|
|
134 |
* alpha_palcode(): |
* alpha_palcode(): |
135 |
* |
* |
136 |
* Execute an Alpha PALcode instruction. (Most of these correspond to |
* Execute an Alpha PALcode instruction. (Most of these correspond to |
137 |
* NetBSD/alpha code). |
* OSF1 palcodes, used by for example NetBSD/alpha.) |
138 |
*/ |
*/ |
139 |
void alpha_palcode(struct cpu *cpu, uint32_t palcode) |
void alpha_palcode(struct cpu *cpu, uint32_t palcode) |
140 |
{ |
{ |
149 |
/* Floating point enable: a0 = 1 or 0. */ |
/* Floating point enable: a0 = 1 or 0. */ |
150 |
/* TODO */ |
/* TODO */ |
151 |
break; |
break; |
152 |
|
case 0x2d: /* PAL_OSF1_wrvptptr */ |
153 |
|
/* a0 = value */ |
154 |
|
cpu->cd.alpha.wrvptptr = cpu->cd.alpha.r[ALPHA_A0]; |
155 |
|
break; |
156 |
|
case 0x30: /* PAL_OSF1_swpctx */ |
157 |
|
/* TODO */ |
158 |
|
/* Swap context */ |
159 |
|
break; |
160 |
|
case 0x31: /* PAL_OSF1_wrval */ |
161 |
|
/* a0 = value */ |
162 |
|
cpu->cd.alpha.sysvalue = cpu->cd.alpha.r[ALPHA_A0]; |
163 |
|
break; |
164 |
|
case 0x32: /* PAL_OSF1_rdval */ |
165 |
|
/* return: v0 = value */ |
166 |
|
cpu->cd.alpha.r[ALPHA_V0] = cpu->cd.alpha.sysvalue; |
167 |
|
break; |
168 |
case 0x33: /* PAL_OSF1_tbi */ |
case 0x33: /* PAL_OSF1_tbi */ |
169 |
/* a0 = op, a1 = vaddr */ |
/* a0 = op, a1 = vaddr */ |
170 |
debug("[ Alpha PALcode: PAL_OSF1_tbi: a0=%lli a1=0x%llx ]\n", |
debug("[ Alpha PALcode: PAL_OSF1_tbi: a0=%"PRIi64" a1=0x%" |
171 |
(signed long long)cpu->cd.alpha.r[ALPHA_A0], |
PRIx64" ]\n", (int64_t)cpu->cd.alpha.r[ALPHA_A0], |
172 |
(long long)cpu->cd.alpha.r[ALPHA_A1]); |
(uint64_t)cpu->cd.alpha.r[ALPHA_A1]); |
173 |
/* TODO */ |
/* TODO */ |
174 |
break; |
break; |
175 |
case 0x34: /* PAL_OSF1_wrent (Write System Entry Address) */ |
case 0x34: /* PAL_OSF1_wrent (Write System Entry Address) */ |
176 |
/* a0 = new vector, a1 = vector selector */ |
/* a0 = new vector, a1 = vector selector */ |
177 |
debug("[ Alpha PALcode: PAL_OSF1_tbi: a0=%lli a1=0x%llx ]\n", |
debug("[ Alpha PALcode: PAL_OSF1_tbi: a0=%"PRIi64" a1=0x%" |
178 |
(signed long long)cpu->cd.alpha.r[ALPHA_A0], |
PRIx64" ]\n", (int64_t) cpu->cd.alpha.r[ALPHA_A0], |
179 |
(long long)cpu->cd.alpha.r[ALPHA_A1]); |
(uint64_t) cpu->cd.alpha.r[ALPHA_A1]); |
180 |
/* TODO */ |
/* TODO */ |
181 |
break; |
break; |
182 |
case 0x35: /* PAL_OSF1_swpipl */ |
case 0x35: /* PAL_OSF1_swpipl */ |
198 |
/* Returns CPU id in v0: */ |
/* Returns CPU id in v0: */ |
199 |
cpu->cd.alpha.r[ALPHA_V0] = cpu->cpu_id; |
cpu->cd.alpha.r[ALPHA_V0] = cpu->cpu_id; |
200 |
break; |
break; |
201 |
|
case 0x81: /* PAL_bugchk */ |
202 |
|
cpu->running = 0; |
203 |
|
break; |
204 |
case 0x83: /* PAL_OSF1_syscall */ |
case 0x83: /* PAL_OSF1_syscall */ |
205 |
if (cpu->machine->userland_emul != NULL) |
if (cpu->machine->userland_emul != NULL) |
206 |
useremul_syscall(cpu, 0); |
useremul_syscall(cpu, 0); |
213 |
case 0x86: /* PAL_OSF1_imb */ |
case 0x86: /* PAL_OSF1_imb */ |
214 |
/* TODO */ |
/* TODO */ |
215 |
break; |
break; |
216 |
|
case 0x3fffffd: |
217 |
|
fatal("[ Alpha PALcode: Fixup: TODO ]\n"); |
218 |
|
/* Return from the fixup call. */ |
219 |
|
cpu->cd.alpha.r[ALPHA_V0] = 0; /* Success? */ |
220 |
|
cpu->pc = cpu->cd.alpha.r[ALPHA_RA]; |
221 |
|
break; |
222 |
case 0x3fffffe: |
case 0x3fffffe: |
223 |
alpha_prom_call(cpu); |
alpha_prom_call(cpu); |
224 |
break; |
break; |