ps2_bios.cc Source File

Back to the index.

ps2_bios.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003-2009 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  * COMMENT: Playstation 2 SIFBIOS emulation
29  */
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/types.h>
35 #include <sys/time.h>
36 #include <sys/resource.h>
37 
38 #include "console.h"
39 #include "cpu.h"
40 #include "cpu_mips.h"
41 #include "machine.h"
42 #include "memory.h"
43 
44 
45 extern int quiet_mode;
46 
47 
48 /*
49  * playstation2_sifbios_emul():
50  */
52 {
53  int callnr;
54 
55  callnr = cpu->cd.mips.gpr[MIPS_GPR_A0];
56 
57  switch (callnr) {
58  case 0: /* getver() */
59  cpu->cd.mips.gpr[MIPS_GPR_V0] = 0x200; /* TODO */
60  break;
61  case 1: /* halt(int mode) */
62  debug("[ SIFBIOS halt(0x%" PRIx64") ]\n",
63  (uint64_t) cpu->cd.mips.gpr[MIPS_GPR_A1]);
64  cpu->running = 0;
65  break;
66  case 2: /* setdve(int mode) */
67  debug("[ SIFBIOS setdve(0x%" PRIx64") ]\n",
68  (uint64_t) cpu->cd.mips.gpr[MIPS_GPR_A1]);
69  break;
70  case 3: /* putchar(int ch) */
71  /* debug("[ SIFBIOS putchar(0x%x) ]\n",
72  (char)cpu->cd.mips.gpr[MIPS_GPR_A1]); */
74  cpu->cd.mips.gpr[MIPS_GPR_A1]);
75  break;
76  case 4: /* getchar() */
77  /* This is untested. TODO */
78  /* debug("[ SIFBIOS getchar() ]\n"; */
79  cpu->cd.mips.gpr[MIPS_GPR_V0] = 0;
83  break;
84  case 16: /* dma_init() */
85  debug("[ SIFBIOS dma_init() ]\n");
86  cpu->cd.mips.gpr[MIPS_GPR_V0] = 0; /* TODO */
87  break;
88  case 17: /* dma_exit() */
89  debug("[ SIFBIOS dma_exit() ]\n");
90  break;
91  case 32: /* cmd_init() */
92  debug("[ SIFBIOS cmd_init() ]\n");
93  cpu->cd.mips.gpr[MIPS_GPR_V0] = 0; /* TODO */
94  break;
95  case 33: /* cmd_exit() */
96  debug("[ SIFBIOS cmd_exit() ]\n");
97  break;
98  case 48:
99  debug("[ SIFBIOS rpc_init(): TODO ]\n");
100  cpu->cd.mips.gpr[MIPS_GPR_V0] = 0; /* TODO */
101  break;
102  case 49:
103  debug("[ SIFBIOS rpc_exit(): TODO ]\n");
104  cpu->cd.mips.gpr[MIPS_GPR_V0] = 0; /* TODO */
105  break;
106  case 51:
107  debug("[ SIFBIOS rpc_bind(): TODO ]\n");
108  cpu->cd.mips.gpr[MIPS_GPR_V0] = 1; /* TODO */
109  break;
110  case 64:
111  fatal("[ SIFBIOS SBR_IOPH_INIT(0x%" PRIx32",0x%" PRIx32",0x%"
112  PRIx32"): TODO ]\n",
113  (uint32_t) cpu->cd.mips.gpr[MIPS_GPR_A1],
114  (uint32_t) cpu->cd.mips.gpr[MIPS_GPR_A2],
115  (uint32_t) cpu->cd.mips.gpr[MIPS_GPR_A3]);
116 
117  /*
118  * This is really really ugly: TODO
119  *
120  * Linux and NetBSD seem to work, but it's an ugly hack.
121  * This should really be a callback thingy...
122  *
123  * NetBSD has a done-word which should be set to 1.
124  * Linux has one done-word which should be set to 1, and
125  * one which should be set to 0.
126  *
127  * The code as it is right now probably overwrites stuff in
128  * memory that shouldn't be touched. Not good.
129  *
130  * Linux: err = sbios_rpc(SBR_IOPH_INIT, NULL, &result);
131  * err should be 0 (just as NetBSD),
132  * and result should be set to 0 as well.
133  */
134  {
135  uint32_t tmpaddr;
136 
137  tmpaddr = load_32bit_word(cpu,
138  cpu->cd.mips.gpr[MIPS_GPR_A1] + 0);
139  fatal(" +0: %08x\n", tmpaddr);
140  tmpaddr = load_32bit_word(cpu,
141  cpu->cd.mips.gpr[MIPS_GPR_A1] + 4);
142  fatal(" +4: %08x\n", tmpaddr);
143  tmpaddr = load_32bit_word(cpu,
144  cpu->cd.mips.gpr[MIPS_GPR_A1] + 8);
145  fatal(" +8: %08x\n", tmpaddr);
146  tmpaddr = load_32bit_word(cpu,
147  cpu->cd.mips.gpr[MIPS_GPR_A1] + 12);
148  fatal(" +12: %08x\n", tmpaddr);
149 
150  /* TODO: This is probably netbsd specific */
151  tmpaddr = load_32bit_word(cpu,
152  cpu->cd.mips.gpr[MIPS_GPR_A1] + 12);
153  fatal("tmpaddr 1 = 0x%08x\n", tmpaddr);
154 
155  /* "done" word for NetBSD: */
156  store_32bit_word(cpu, tmpaddr, 1);
157  /* "done" word A for Linux: */
158  store_32bit_word(cpu, tmpaddr + 4, 1);
159  /* "done" word B for Linux: */
160  store_32bit_word(cpu,
161  cpu->cd.mips.gpr[MIPS_GPR_A1] + 0, 0);
162  }
163  cpu->cd.mips.gpr[MIPS_GPR_V0] = 0;
164  break;
165  case 65:
166  fatal("[ SIFBIOS alloc iop heap(0x" PRIx32") ]\n",
167  (uint32_t)cpu->cd.mips.gpr[MIPS_GPR_A1]);
168 
169  /*
170  * Linux uses this to allocate "heap" for the OHCI USB
171  * controller.
172  *
173  * TODO: This naïve implementation does not allow for a
174  * "free iop heap" function: :-/
175  */
176 
177  {
178  uint32_t tmpaddr;
179  static uint32_t return_addr = 0x1000;
180  /* 0xbc000000; */
181  uint32_t size;
182 
183  tmpaddr = load_32bit_word(cpu,
184  cpu->cd.mips.gpr[MIPS_GPR_A1] + 0);
185  fatal(" +0: %08x (result should be placed here)\n",
186  tmpaddr);
187  tmpaddr = load_32bit_word(cpu,
188  cpu->cd.mips.gpr[MIPS_GPR_A1] + 4);
189  fatal(" +4: %08x (*arg)\n", tmpaddr);
190  size = load_32bit_word(cpu, tmpaddr + 0);
191  fatal(" size = %08x\n", size);
192  tmpaddr = load_32bit_word(cpu,
193  cpu->cd.mips.gpr[MIPS_GPR_A1] + 8);
194  fatal(" +8: %08x (*func (void *, int))\n", tmpaddr);
195  tmpaddr = load_32bit_word(cpu,
196  cpu->cd.mips.gpr[MIPS_GPR_A1] + 12);
197  fatal(" +12: %08x (*para)\n", tmpaddr);
198 
199  /* TODO: This is probably netbsd specific */
200  tmpaddr = load_32bit_word(cpu,
201  cpu->cd.mips.gpr[MIPS_GPR_A1] + 12);
202  fatal("tmpaddr 1 = 0x%08x\n", tmpaddr);
203 
204  /* "done" word for NetBSD: */
205  store_32bit_word(cpu, tmpaddr, 1);
206  /* "done" word A for Linux: */
207  store_32bit_word(cpu, tmpaddr + 4, 1);
208 
209  /* Result: */
210  store_32bit_word(cpu,
211  cpu->cd.mips.gpr[MIPS_GPR_A1] + 0, return_addr);
212 
213  return_addr += size;
214  /* Round up to next page: */
215  return_addr += 4095;
216  return_addr &= ~4095;
217  }
218  cpu->cd.mips.gpr[MIPS_GPR_V0] = 0;
219  break;
220  case 66:
221  debug("[ SIFBIOS iopmem_free(): TODO ]\n");
222  cpu->cd.mips.gpr[MIPS_GPR_V0] = 0; /* TODO */
223  break;
224  default:
225  quiet_mode = 0;
226  cpu_register_dump(cpu->machine, cpu, 1, 0x1);
227  printf("\n");
228  fatal("Playstation 2 SIFBIOS emulation: "
229  "unimplemented call nr 0x%x\n", callnr);
230  cpu->running = 0;
231  }
232 
233  return 1;
234 }
235 
void fatal(const char *fmt,...)
Definition: main.cc:152
int main_console_handle
Definition: machine.h:128
int store_32bit_word(struct cpu *cpu, uint64_t addr, uint64_t data32)
Definition: memory.cc:783
#define MIPS_GPR_A0
union cpu::@1 cd
struct machine * machine
Definition: cpu.h:328
void console_putchar(int handle, int ch)
Definition: console.cc:405
int console_readchar(int handle)
Definition: console.cc:385
#define MIPS_GPR_A2
int playstation2_sifbios_emul(struct cpu *cpu)
Definition: ps2_bios.cc:51
int console_charavail(int handle)
Definition: console.cc:336
#define MIPS_GPR_A3
#define MIPS_GPR_A1
uint8_t running
Definition: cpu.h:353
int quiet_mode
Definition: main.cc:78
void cpu_register_dump(struct machine *m, struct cpu *cpu, int gprs, int coprocs)
Definition: cpu.cc:203
#define debug
Definition: dev_adb.cc:57
Definition: cpu.h:326
uint32_t load_32bit_word(struct cpu *cpu, uint64_t addr)
Definition: memory.cc:902
uint64_t gpr[N_MIPS_GPRS]
Definition: cpu_mips.h:209
struct mips_cpu mips
Definition: cpu.h:443
#define MIPS_GPR_V0

Generated on Sun Sep 30 2018 16:05:18 for GXemul by doxygen 1.8.13