/[gxemul]/trunk/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

Diff of /trunk/src/cpus/cpu_alpha_palcode.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 31 by dpavlin, Mon Oct 8 16:19:56 2007 UTC revision 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_alpha_palcode.c,v 1.8 2006/06/02 18:11:38 debug Exp $   *  $Id: cpu_alpha_palcode.c,v 1.15 2006/10/08 02:28:58 debug Exp $
29   *   *
30   *  Alpha PALcode-related functionality.   *  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    
# Line 53  void alpha_palcode(struct cpu *cpu, uint Line 56  void alpha_palcode(struct cpu *cpu, uint
56  #else   /*  ENABLE_ALPHA  */  #else   /*  ENABLE_ALPHA  */
57    
58    
59    #include "alpha_prom.h"
60  #include "console.h"  #include "console.h"
61  #include "cpu.h"  #include "cpu.h"
62  #include "machine.h"  #include "machine.h"
# Line 91  void alpha_palcode_name(uint32_t palcode Line 95  void alpha_palcode_name(uint32_t palcode
95          case 0x86: snprintf(buf, buflen, "PAL_OSF1_imb"); break;          case 0x86: snprintf(buf, buflen, "PAL_OSF1_imb"); break;
96          case 0x92: snprintf(buf, buflen, "PAL_OSF1_urti"); break;          case 0x92: snprintf(buf, buflen, "PAL_OSF1_urti"); break;
97          case 0x3fffffe: snprintf(buf, buflen, "GXemul_PROM"); break;          case 0x3fffffe: snprintf(buf, buflen, "GXemul_PROM"); break;
98          default:snprintf(buf, buflen, "UNKNOWN 0x%x", palcode);          default:snprintf(buf, buflen, "UNKNOWN 0x%"PRIx32, palcode);
99          }          }
100  }  }
101    
# Line 101  void alpha_palcode_name(uint32_t palcode Line 105  void alpha_palcode_name(uint32_t palcode
105   */   */
106  void alpha_prom_call(struct cpu *cpu)  void alpha_prom_call(struct cpu *cpu)
107  {  {
108          uint64_t addr;          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]) {          switch (cpu->cd.alpha.r[ALPHA_A0]) {
114          case 0x02:  
115                  /*  puts: a1 = channel, a2 = ptr to buf, a3 = len  */          case PROM_R_PUTS:
116                  for (addr = cpu->cd.alpha.r[ALPHA_A2];                  /*  a1 = channel, a2 = ptr to buf, a3 = len  */
117                       addr < cpu->cd.alpha.r[ALPHA_A2] +                  for (addr = a2; addr < a2 + a3; addr ++) {
                      cpu->cd.alpha.r[ALPHA_A3]; addr ++) {  
118                          unsigned char ch;                          unsigned char ch;
119                          cpu->memory_rw(cpu, cpu->mem, addr, &ch, sizeof(ch),                          cpu->memory_rw(cpu, cpu->mem, addr, &ch, sizeof(ch),
120                              MEM_READ, CACHE_DATA | NO_EXCEPTIONS);                              MEM_READ, CACHE_DATA | NO_EXCEPTIONS);
121                          console_putchar(cpu->machine->main_console_handle, ch);                          console_putchar(cpu->machine->main_console_handle, ch);
122                  }                  }
123                  cpu->cd.alpha.r[ALPHA_V0] = cpu->cd.alpha.r[ALPHA_A3];                  cpu->cd.alpha.r[ALPHA_V0] = a3;
124                  break;                  break;
125          case 0x22:  
126                  /*  getenv  */          case PROM_R_GETENV:
127                  fatal("[ Alpha PALcode: GXemul PROM call 0x22: TODO ]\n");                  /*  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;                  break;
151    
152          default:fatal("[ Alpha PALcode: GXemul PROM call, a0=0x%"PRIx64" ]\n",          default:fatal("[ Alpha PALcode: GXemul PROM call, a0=0x%"PRIx64" ]\n",
153                      (uint64_t) cpu->cd.alpha.r[ALPHA_A0]);                      (uint64_t) cpu->cd.alpha.r[ALPHA_A0]);
154                  cpu->running = 0;                  cpu->running = 0;
# Line 138  void alpha_prom_call(struct cpu *cpu) Line 167  void alpha_prom_call(struct cpu *cpu)
167   */   */
168  void alpha_palcode(struct cpu *cpu, uint32_t palcode)  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) {          switch (palcode) {
173            case 0x02:      /*  PAL_draina  */
174                    /*  TODO?  */
175                    break;
176          case 0x10:      /*  PAL_OSF1_rdmces  */          case 0x10:      /*  PAL_OSF1_rdmces  */
177                  /*  TODO? Return something in v0.  */                  /*  TODO. Return Machine Check status in v0.  */
178                    cpu->cd.alpha.r[ALPHA_V0] = 0;
179                  break;                  break;
180          case 0x11:      /*  PAL_OSF1_wrmces  */          case 0x11:      /*  PAL_OSF1_wrmces  */
181                  /*  TODO? Set something to a0.  */                  /*  TODO. Clear Machine Check and Error status.  */
182                  break;                  break;
183          case 0x2b:      /*  PAL_OSF1_wrfen  */          case 0x2b:      /*  PAL_OSF1_wrfen  */
184                  /*  Floating point enable: a0 = 1 or 0.  */                  /*  Floating point enable: a0 = 1 or 0.  */
185                  /*  TODO  */                  /*  TODO  */
186                  break;                  break;
187          case 0x2d:      /*  PAL_OSF1_wrvptptr  */          case 0x2d:      /*  PAL_OSF1_wrvptptr  */
188                  /*  a0 = value  */                  /*  Write Virtual Page Table Pointer. a0 = value  */
189                  cpu->cd.alpha.wrvptptr = cpu->cd.alpha.r[ALPHA_A0];                  cpu->cd.alpha.vptptr = a0;
190                  break;                  break;
191          case 0x30:      /*  PAL_OSF1_swpctx  */          case 0x30:      /*  PAL_OSF1_swpctx  */
192                  /*  TODO  */                  /*  Save old context:  */
193                  /*  Swap context  */                  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;                  break;
232          case 0x31:      /*  PAL_OSF1_wrval  */          case 0x31:      /*  PAL_OSF1_wrval  */
233                  /*  a0 = value  */                  /*  a0 = value  */
234                  cpu->cd.alpha.sysvalue = cpu->cd.alpha.r[ALPHA_A0];                  cpu->cd.alpha.sysvalue = a0;
235                  break;                  break;
236          case 0x32:      /*  PAL_OSF1_rdval  */          case 0x32:      /*  PAL_OSF1_rdval  */
237                  /*  return: v0 = value  */                  /*  return: v0 = value  */
238                  cpu->cd.alpha.r[ALPHA_V0] = cpu->cd.alpha.sysvalue;                  cpu->cd.alpha.r[ALPHA_V0] = cpu->cd.alpha.sysvalue;
239                  break;                  break;
240          case 0x33:      /*  PAL_OSF1_tbi  */          case 0x33:      /*  PAL_OSF1_tbi  */
241                  /*  a0 = op, a1 = vaddr  */                  /*
242                  debug("[ Alpha PALcode: PAL_OSF1_tbi: a0=%"PRIi64" a1=0x%"                   *  a0 = op, a1 = vaddr
243                      PRIx64" ]\n", (int64_t)cpu->cd.alpha.r[ALPHA_A0],                   */
244                      (uint64_t)cpu->cd.alpha.r[ALPHA_A1]);                  fatal("[ Alpha PALcode: PAL_OSF1_tbi: a0=%"PRIi64" a1=0x%"
245                  /*  TODO  */                      PRIx64" ]\n", (int64_t)a0, (uint64_t)a1);
246                    cpu->invalidate_translation_caches(cpu, a1, INVALIDATE_VADDR);
247                  break;                  break;
248          case 0x34:      /*  PAL_OSF1_wrent (Write System Entry Address)  */          case 0x34:      /*  PAL_OSF1_wrent (Write System Entry Address)  */
249                  /*  a0 = new vector, a1 = vector selector  */                  /*  a0 = new vector, a1 = vector selector  */
250                  debug("[ Alpha PALcode: PAL_OSF1_tbi: a0=%"PRIi64" a1=0x%"                  if (a1 < N_ALPHA_KENTRY)
251                      PRIx64" ]\n", (int64_t) cpu->cd.alpha.r[ALPHA_A0],                          cpu->cd.alpha.kentry[a1] = a0;
252                      (uint64_t) cpu->cd.alpha.r[ALPHA_A1]);                  else {
253                  /*  TODO  */                          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;                  break;
259          case 0x35:      /*  PAL_OSF1_swpipl  */          case 0x35:      /*  PAL_OSF1_swpipl  */
260                  /*  a0 = new ipl, v0 = return old ipl  */                  /*  a0 = new ipl, v0 = return old ipl  */
261                  cpu->cd.alpha.r[ALPHA_V0] = cpu->cd.alpha.ipl;                  cpu->cd.alpha.r[ALPHA_V0] = cpu->cd.alpha.ipl;
262                  cpu->cd.alpha.ipl = cpu->cd.alpha.r[ALPHA_A0];                  cpu->cd.alpha.ipl = a0;
263                  break;                  break;
264          case 0x36:      /*  PAL_OSF1_rdps  */          case 0x36:      /*  PAL_OSF1_rdps  */
265                  /*  TODO  */                  /*  TODO  */
# Line 191  void alpha_palcode(struct cpu *cpu, uint Line 268  void alpha_palcode(struct cpu *cpu, uint
268          case 0x37:      /*  PAL_OSF1_wrkgp  */          case 0x37:      /*  PAL_OSF1_wrkgp  */
269                  /*  "clobbers a0, t0, t8-t11" according to comments in                  /*  "clobbers a0, t0, t8-t11" according to comments in
270                      NetBSD sources  */                      NetBSD sources  */
271                    cpu->cd.alpha.kgp = a0;
272                  /*  KGP shoudl be set to a0.  (TODO)  */                  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;                  break;
281          case 0x3c:      /*  PAL_OSF1_whami  */          case 0x3c:      /*  PAL_OSF1_whami  */
282                  /*  Returns CPU id in v0:  */                  /*  Returns CPU id in v0:  */
# Line 213  void alpha_palcode(struct cpu *cpu, uint Line 297  void alpha_palcode(struct cpu *cpu, uint
297          case 0x86:      /*  PAL_OSF1_imb  */          case 0x86:      /*  PAL_OSF1_imb  */
298                  /*  TODO  */                  /*  TODO  */
299                  break;                  break;
300            case 0x3fffffc:
301                    fatal("[ Alpha: KENTRY not set! Halting. ]");
302                    cpu->running = 0;
303                    break;
304          case 0x3fffffd:          case 0x3fffffd:
305                  fatal("[ Alpha PALcode: Fixup: TODO ]\n");                  fatal("[ Alpha PALcode: Fixup: TODO ]\n");
306                  /*  Return from the fixup call.  */                  /*  Return from the fixup call.  */

Legend:
Removed from v.31  
changed lines
  Added in v.32

  ViewVC Help
Powered by ViewVC 1.1.26