/[gxemul]/trunk/doc/technical.html
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 /trunk/doc/technical.html

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6 - (show annotations)
Mon Oct 8 16:18:11 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/html
File size: 21775 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.772 2005/06/04 12:02:16 debug Exp $
20050428	Disabling the "-fmove-all-movables" option in the configure
		script, because it causes the compile to fail on OpenBSD/sgi.
20050502	Minor updates.
20050503	Removing the WRT54G mode (it was bogus anyway), and adding a
		comment about Windows NT for MIPS in doc/experiments.html.
		Minor updates to the x86 instruction decoding.
20050504	Adding some more x86 instructions.
		Adding support for reading files from ISO9660 CDROMs (including
		gzipped files). It's an ugly hack, but it seems to work.
		Various other minor updates (dev_vga.c, pc_bios.c etc).
20050505	Some more x86-related updates.
		Beginning (what I hope will be) a major code cleanup phase.
		"bootris" (an x86 bootsector) runs :-)
20050506	Adding some more x86 instructions.
20050507	tmpnam => mkstemp.
		Working on a hack to allow VGA charcells to be shown even when
		not running with X11.
		Adding more x86 instructions.
20050508	x86 32-bit SIB addressing fix, and more instructions.
20050509	Adding more x86 instructions.
20050510	Minor documentation updates, and other updates (x86 stuff etc.)
20050511	More x86-related updates.
20050513	Various updates, mostly x86-related. (Trying to fix flag 
		calculation, factoring out the ugly shift/rotate code, and
		some other things.)
20050514	Adding support for loading some old i386 a.out executables.
		Finally beginning the cleanup of machine/PROM/bios dependant
		info.
		Some minor documentation updates.
		Trying to clean up ARCBIOS stuff a little.
20050515	Trying to make it possible to actually use more than one disk
		type per machine (floppy, ide, scsi).
		Trying to clean up the kbd vs PROM console stuff. (For PC and
		ARC emulation modes, mostly.)
		Beginning to add an 8259 interrupt controller, and connecting
		it to the x86 emulation.
20050516	The first x86 interrupts seem to work (keyboard stuff).
		Adding a 8253/8254 programmable interval timer skeleton.
		FreeDOS now reaches a command prompt and can be interacted
		with.
20050517	After some bugfixes, MS-DOS also (sometimes) reaches a
		command prompt now.
		Trying to fix the pckbc to work with MS-DOS' keyb.com, but no
		success yet.
20050518	Adding a simple 32-bit x86 MMU skeleton.
20050519	Some more work on the x86 stuff. (Beginning the work on paging,
		and various other fixes).
20050520	More updates. Working on dev_vga (4-bit graphics modes), adding
		40 columns support to the PC bios emulation.
		Trying to add support for resizing windows when switching
		between graphics modes.
20050521	Many more x86-related updates.
20050522	Correcting the initial stack pointer's sign-extension for
		ARCBIOS emulation (thanks to Alec Voropay for noticing the
		error).
		Continuing on the cleanup (ARCBIOS etc).
		dev_vga updates.
20050523	More x86 updates: trying to add some support for protected mode
		interrupts (via gate descriptors) and many other fixes.
		More ARCBIOS cleanup.
		Adding a device flag which indicates that reads cause no
		side-effects. (Useful for the "dump" command in the debugger,
		and other things.)
		Adding support for directly starting up x86 ELFs, skipping the
		bootloader stage. (Most ELFs, however, are not suitable for
		this.)
20050524	Adding simple 32-bit x86 TSS task switching, but no privilege
		level support yet.
		More work on dev_vga. A small "Copper bars" demo works. :-)
		Adding support for Trap Flag (single-step exceptions), at least
		in real mode, and various other x86-related fixes.
20050525	Adding a new disk image prefix (gH;S;) which can be used to
		override the default nr of heads and sectors per track.
20050527	Various bug fixes, more work on the x86 mode (stack change on
		interrupts between different priv.levels), and some minor
		documentation updates.
20050528	Various fixes (x86 stuff).
20050529	More x86 fixes. An OpenBSD/i386 bootfloppy reaches userland
		and can be interacted with (although there are problems with
		key repetition). NetBSD/i386 triggers a serious CISC-related
		problem: instruction fetches across page boundaries, where
		the later part isn't actually part of the instruction.
20050530	Various minor updates. (Documentation updates, etc.)
20050531	Adding some experimental code (experiments/new_test_*) which
		could be useful for dynamic (but not binary) translation in
		the future.
20050602	Adding a dummy ARM skeleton.
		Fixing the pckbc key repetition problem (by adding release
		scancodes for all keypresses).
20050603	Minor updates for the next release.
20050604	Release testing. Minor updates.

==============  RELEASE 0.3.3  ==============

20050604	There'll probably be a 0.3.3.1 release soon, with some very
		very tiny updates.


1 <html>
2 <head><title>GXemul documentation: Technical details</title>
3 </head>
4 <body bgcolor="#f8f8f8" text="#000000" link="#4040f0" vlink="#404040" alink="#ff0000">
5 <table border=0 width=100% bgcolor="#d0d0d0"><tr>
6 <td width=100% align=center valign=center><table border=0 width=100%><tr>
7 <td align="left" valign=center bgcolor="#d0efff"><font color="#6060e0" size="6">
8 <b>GXemul documentation:</b></font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
9 <font color="#000000" size="6"><b>Technical details</b>
10 </font></td></tr></table></td></tr></table><p>
11 <!-- The first 10 lines are cut away by the homepage updating script. -->
12
13
14 <!--
15
16 $Id: technical.html,v 1.50 2005/05/14 18:31:16 debug Exp $
17
18 Copyright (C) 2004-2005 Anders Gavare. All rights reserved.
19
20 Redistribution and use in source and binary forms, with or without
21 modification, are permitted provided that the following conditions are met:
22
23 1. Redistributions of source code must retain the above copyright
24 notice, this list of conditions and the following disclaimer.
25 2. Redistributions in binary form must reproduce the above copyright
26 notice, this list of conditions and the following disclaimer in the
27 documentation and/or other materials provided with the distribution.
28 3. The name of the author may not be used to endorse or promote products
29 derived from this software without specific prior written permission.
30
31 THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
32 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
35 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
40 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 SUCH DAMAGE.
42
43 -->
44
45
46 <a href="./">Back to the index</a>
47
48 <p><br>
49 <h2>Technical details</h2>
50
51 <p>
52 This page describes some of the internals of GXemul.
53
54 <p>
55 <font color="#e00000"><b>NOTE: This page is probably not
56 very up-to-date by now.</b></font>
57
58 <p>
59 <ul>
60 <li><a href="#overview">Overview</a>
61 <li><a href="#speed">Speed</a>
62 <li><a href="#net">Networking</a>
63 <li><a href="#devices">Emulation of hardware devices</a>
64 <li><a href="#regtest">Regression tests</a>
65 </ul>
66
67
68
69
70 <p><br>
71 <a name="overview"></a>
72 <h3>Overview</h3>
73
74 In simple terms, GXemul is just a simple fetch-and-execute
75 loop; an instruction is fetched from memory, and executed.
76
77 <p>
78 In reality, a lot of things need to be handled. Before each instruction is
79 executed, the emulator checks to see if any interrupts are asserted which
80 are not masked away. If so, then an INT exception is generated. Exceptions
81 cause the program counter to be set to a specific value, and some of the
82 system coprocessor's registers to be set to values signifying what kind of
83 exception it was (an interrupt exception in this case).
84
85 <p>
86 Reading instructions from memory is done through a TLB, a translation
87 lookaside buffer. The TLB on MIPS is software controlled, which means that
88 the program running inside the emulator (for example an operating system
89 kernel) has to take care of manually updating the TLB. Some memory
90 addresses are translated into physical addresses directly, some are
91 translated into valid physical addresses via the TLB, and some memory
92 references are not valid. Invalid memory references cause exceptions.
93
94 <p>
95 After an instruction has been read from memory, the emulator checks which
96 opcode it contains and executes the instruction. Executing an instruction
97 usually involves reading some register and writing some register, or perhaps a
98 load from memory (or a store to memory). The program counter is increased
99 for every instruction.
100
101 <p>
102 Some memory references point to physical addresses which are not in the
103 normal RAM address space. They may point to hardware devices. If that is
104 the case, then loads and stores are converted into calls to a device
105 access function. The device access function is then responsible for
106 handling these reads and writes. For example, a graphical framebuffer
107 device may put a pixel on the screen when a value is written to it, or a
108 serial controller device may output a character to stdout when written to.
109
110
111
112
113 <p><br>
114 <a name="speed"></a>
115 <h3>Speed</h3>
116
117 There are two modes in which the emulator can run, <b>a</b>) a straight forward
118 loop which fetches one instruction from emulated RAM and executes it
119 (described in the previous section), and <b>b</b>)
120 using dynamic binary translation.
121
122 <p>
123 Mode <b>a</b> is very slow. On a 2.8 GHz Intel Xeon host the resulting
124 emulated machine is rougly equal to a 7 MHz R3000 (or a 3.5 MHz R4000).
125 The actual performance varies a lot, maybe between 5 and 10 million
126 instructions per second, depending on workload.
127
128 <p>
129 Mode <b>b</b> ("bintrans") is still to be considered experimental, but
130 gives higher performance than mode <b>a</b>. It translates MIPS machine
131 code into machine code that can be executed on the host machine
132 on-the-fly. The translation itself obviously takes some time, but this is
133 usually made up for by the fact that the translated code chunks are
134 executed multiple times.
135 To run the emulator with binary translation enabled, just add
136 <tt><b>-b</b></tt> to the command line.
137
138 <p>
139 Only small pieces of MIPS machine code are translated, usually the size of
140 a function, or less. There is no "intermediate representation" code, so
141 all translations are done directly from MIPS to host machine code.
142
143 <p>
144 The default bintrans cache size is 16 MB, but you can change this by adding
145 <tt>-DDEFAULT_BINTRANS_SIZE_IN_MB=<i>xx</i></tt> to your CFLAGS environment
146 variable before running the configure script, or by using the
147 <tt>bintrans_size()</tt> configuration file option when running the emulator.
148
149 <p>
150 By default, an emulated OS running under DECstation emulation which listens to
151 interrupts from the mc146818 clock will get interrupts that are close to the
152 host's clock. That is, if the emulated OS says it wants 100 interrupts per
153 second, it will get approximately 100 interrupts per real second.
154
155 <p>
156 There is however a <tt><b>-I</b></tt> option, which sets the number of
157 emulated cycles per seconds to a fixed value. Let's say you wish to make the
158 emulated OS think it is running on a 40 MHz DECstation, and not a 7 MHz one,
159 then you can add <tt><b>-I 40000000</b></tt> to the command line. This will not
160 make the emulation faster, of course. It might even make it seem slower; for
161 example, if NetBSD/pmax waits 2 seconds for SCSI devices to settle during
162 bootup, those 2 seconds will take 2*40000000 cycles (which will take more
163 time than 2*7000000).
164
165 <p>
166 The <b><tt>-I</tt></b> option is also necessary if you want to run
167 deterministic experiments, if a mc146818 (or similar) device is present.
168
169 <p>
170 Some emulators make claims such as "x times slowdown," but in the case of
171 GXemul, the host is often not a MIPS-based machine, and hence comparing
172 one MIPS instruction to a host instruction doesn't work. Performance depends on
173 a lot of factors, including (but not limited to) host architecture, host speed,
174 which compiler and compiler flags were used to build GXemul, what the
175 workload is, and so on. For example, if an emulated operating system tries
176 to read a block from disk, from its point of view the read was instantaneous
177 (no waiting). So 1 MIPS in an emulated OS might have taken more than one
178 million instructions on a real machine. Because of this, imho it is best
179 to measure performance as the actual (real-world) time it takes to perform
180 a task with the emulator.
181
182
183
184
185 <p><br>
186 <a name="net"></a>
187 <h3>Networking</h3>
188
189 Running an entire operating system under emulation is very interesting in
190 itself, but for several reasons, running a modern OS without access to
191 TCP/IP networking is a bit akward. Hence, I feel the need to implement TCP/IP
192 (networking) support in the emulator.
193
194 <p>
195 As far as I have understood it, there seems to be two different ways to go:
196
197 <ol>
198 <li>Forward ethernet packets from the emulated ethernet controller to
199 the host machine's ethernet controller, and capture incoming
200 packets on the host's controller, giving them back to the
201 emulated OS. Characteristics are:
202 <ul>
203 <li>Requires <i>direct</i> access to the host's NIC, which
204 means on most platforms that the emulator cannot be
205 run as a normal user!
206 <li>Reduced portability, as not every host operating system
207 uses the same programming interface for dealing with
208 hardware ethernet controllers directly.
209 <li>When run on a switched network, it might be problematic to
210 connect from the emulated OS to the OS running on the
211 host, as packets sent out on the host's NIC are not
212 received by itself. (?)
213 <li>All specific networking protocols will be handled by the
214 physical network.
215 </ul>
216 <p>
217 or
218 <p>
219 <li>Whenever the emulated ethernet controller wishes to send a packet,
220 the emulator looks at the packet and creates a response. Packets
221 that can have an immediate response never go outside the emulator,
222 other packet types have to be converted into suitable other
223 connection types (UDP, TCP, etc). Characteristics:
224 <ul>
225 <li>Each packet type sent out on the emulated NIC must be handled.
226 This means that I have to do a lot of coding.
227 (I like this, because it gives me an opportunity to
228 learn about networking protocols.)
229 <li>By not relying on access to the host's NIC directly,
230 portability is maintained. (It would be sad if the networking
231 portion of a portable emulator isn't as portable as the
232 rest of the emulator.)
233 <li>The emulator can be run as a normal user process, does
234 not require root privilegies.
235 <li>Connecting from the emulated OS to the host's OS should
236 not be problematic.
237 <li>The emulated OS will experience the network just as a single
238 machine behind a NAT gateway/firewall would. The emulated
239 OS is thus automatically protected from the outside world.
240 </ul>
241 </ol>
242
243 <p>
244 Some emulators/simulators use the first approach, while others use the
245 second. I think that SIMH and QEMU are examples of emulators using the
246 first and second approach, respectively.
247
248 <p>
249 Since I have choosen the second kind of implementation, I have to write
250 support explicitly for any kind of network protocol that should be
251 supported. As of 2004-07-09, the following has been implemented and seems
252 to work under at least NetBSD/pmax and OpenBSD/pmax under DECstation 5000/200
253 emulation (-E dec -e 3max):
254
255 <p>
256 <ul>
257 <li>ARP requests sent out from the emulated NIC are interpreted,
258 and converted to ARP responses. (This is used by the emulated OS
259 to find out the MAC address of the gateway.)
260 <li>ICMP echo requests (that is the kind of packet produced by the
261 <b><tt>ping</tt></b> program) are interpreted and converted to ICMP echo
262 replies, <i>regardless of the IP address</i>. This means that
263 running ping from within the emulated OS will <i>always</i>
264 receive a response. The ping packets never leave the emulated
265 environment.
266 <li>UDP packets are interpreted and passed along to the outside world.
267 If the emulator receives an UDP packet from the outside world, it
268 is converted into an UDP packet for the emulated OS. (This is not
269 implemented very well yet, but seems to be enough for nameserver
270 lookups, tftp file transfers, and NFS mounts using UDP.)
271 <li>TCP packets are interpreted one at a time, similar to how UDP
272 packets are handled (but more state is kept for each connection).
273 <font color="#ff0000">NOTE: Much of the TCP handling code is very
274 ugly and hardcoded.</font>
275 <!--
276 <li>RARP is not implemented yet. (I haven't needed it so far.)
277 -->
278 </ul>
279
280 <p>
281 The gateway machine, which is the only "other" machine that the emulated
282 OS sees on its emulated network, works as a NAT-style firewall/gateway. It
283 usually has a fixed IPv4 address of <tt>10.0.0.254</tt>. An OS running in
284 the emulator would usually have an address of the form <tt>10.x.x.x</tt>;
285 a typical choice would be <tt>10.0.0.1</tt>.
286
287 <p>
288 Inside emulated NetBSD/pmax or OpenBSD/pmax, running the following
289 commands should configure the emulated NIC:
290 <pre>
291 # <b>ifconfig le0 10.0.0.1</b>
292 # <b>route add default 10.0.0.254</b>
293 add net default: gateway 10.0.0.254
294 </pre>
295
296 <p>
297 If you want nameserver lookups to work, you need a valid /etc/resolv.conf
298 as well:
299 <pre>
300 # <b>echo nameserver 129.16.1.3 > /etc/resolv.conf</b>
301 </pre>
302 (But replace <tt>129.16.1.3</tt> with the actual real-world IP address of
303 your nearest nameserver.)
304
305 <p>
306 Now, host lookups should work:
307 <pre>
308 # <b>host -a www.netbsd.org</b>
309 Trying null domain
310 rcode = 0 (Success), ancount=2
311 The following answer is not authoritative:
312 The following answer is not verified as authentic by the server:
313 www.netbsd.org 86400 IN AAAA 2001:4f8:4:7:290:27ff:feab:19a7
314 www.netbsd.org 86400 IN A 204.152.184.116
315 For authoritative answers, see:
316 netbsd.org 83627 IN NS uucp-gw-2.pa.dec.com
317 netbsd.org 83627 IN NS ns.netbsd.org
318 netbsd.org 83627 IN NS adns1.berkeley.edu
319 netbsd.org 83627 IN NS adns2.berkeley.edu
320 netbsd.org 83627 IN NS uucp-gw-1.pa.dec.com
321 Additional information:
322 ns.netbsd.org 83627 IN A 204.152.184.164
323 uucp-gw-1.pa.dec.com 172799 IN A 204.123.2.18
324 uucp-gw-2.pa.dec.com 172799 IN A 204.123.2.19
325 </pre>
326
327 <p>
328 At this point, UDP and TCP should (mostly) work.
329
330 <p>
331 Here is an example of how to configure a server machine and an emulated
332 client machine for sharing files via NFS:
333
334 <p>
335 (This is very useful if you want to share entire directory trees
336 between the emulated environment and another machine. These instruction
337 will work for FreeBSD, if you are running something else, use your
338 imagination to modify them.)
339
340 <p>
341 <ul>
342 <li>On the server, add a line to your /etc/exports file, exporting
343 the files you wish to use in the emulator:<pre>
344 <b>/tftpboot -mapall=nobody -ro 123.11.22.33</b>
345 </pre>
346 where 123.11.22.33 is the IP address of the machine running the
347 emulator process, as seen from the outside world.
348 <p>
349 <li>Then start up the programs needed to serve NFS via UDP. Note the
350 -n argument to mountd. This is needed to tell mountd to accept
351 connections from unprivileged ports (because the emulator does
352 not need to run as root).<pre>
353 # <b>portmap</b>
354 # <b>nfsd -u</b> &lt;--- u for UDP
355 # <b>mountd -n</b>
356 </pre>
357 <li>In the guest OS in the emulator, once you have ethernet and IPv4
358 configured so that you can use UDP, mounting the filesystem
359 should now be possible: (this example is for NetBSD/pmax
360 or OpenBSD/pmax)<pre>
361 # <b>mount -o ro,-r=1024,-w=1024,-U,-3 my.server.com:/tftpboot /mnt</b>
362 or
363 # <b>mount my.server.com:/tftpboot /mnt</b>
364 </pre>
365 If you don't supply the read and write sizes, there is a risk
366 that the default values are too large. The emulator currently
367 does not handle fragmentation/defragmentation of <i>outgoing</i>
368 packets, so going above the ethernet frame size (1518) is a very
369 bad idea. Incoming packets (reading from nfs) should work, though,
370 for example during an NFS install.
371 </ul>
372
373 The example above uses read-only mounts. That is enough for things like
374 letting NetBSD/pmax or OpenBSD/pmax install via NFS, without the need for
375 a CDROM ISO image. You can use a read-write mount if you wish to share
376 files in both directions, but then you should be aware of the
377 fragmentation issue mentioned above.
378
379
380
381
382
383 <p><br>
384 <a name="devices"></a>
385 <h3>Emulation of hardware devices</h3>
386
387 Each file in the device/ directory is responsible for one hardware device.
388 These are used from src/machine.c, when initializing which hardware a
389 particular machine model will be using, or when adding devices to a
390 machine using the <b>device()</b> command in configuration files.
391
392 <p>
393 <font color="#ff0000">NOTE: 2005-02-26: I'm currently rewriting the
394 device registry subsystem.</font>
395
396 <p>
397 (I'll be using the name 'foo' as the name of the device in all these
398 examples. This is pseudo code, it might need some modification to
399 actually compile and run.)
400
401 <p>
402 Each device should have the following:
403
404 <p>
405 <ul>
406 <li>A devinit function in dev_foo.c. It would typically look
407 something like this:
408 <pre>
409 /*
410 * devinit_foo():
411 */
412 int devinit_foo(struct devinit *devinit)
413 {
414 struct foo_data *d = malloc(sizeof(struct foo_data));
415
416 if (d == NULL) {
417 fprintf(stderr, "out of memory\n");
418 exit(1);
419 }
420 memset(d, 0, sizeof(struct foon_data));
421
422 /*
423 * Set up stuff here, for example fill d with useful
424 * data. devinit contains settings like address, irq_nr,
425 * and other things.
426 *
427 * ...
428 */
429
430 memory_device_register(devinit->machine->memory, devinit->name,
431 devinit->addr, DEV_FOO_LENGTH,
432 dev_foo_access, (void *)d, MEM_DEFAULT, NULL);
433
434 /* This should only be here if the device
435 has a tick function: */
436 machine_add_tickfunction(machine, dev_foo_tick, d,
437 FOO_TICKSHIFT);
438
439 /* Return 1 if the device was successfully added. */
440 return 1;
441 }
442 </pre><br>
443
444 <li>At the top of dev_foo.c, the foo_data struct should be defined.
445 <pre>
446 struct foo_data {
447 int irq_nr;
448 /* ... */
449 }
450 </pre><br>
451
452 <li>If foo has a tick function (that is, something that needs to be
453 run at regular intervals) then FOO_TICKSHIFT and a tick function
454 need to be defined as well:
455 <pre>
456 #define FOO_TICKSHIFT 10
457
458 void dev_foo_tick(struct cpu *cpu, void *extra)
459 {
460 struct foo_data *d = (struct foo_data *) extra;
461
462 if (.....)
463 cpu_interrupt(cpu, d->irq_nr);
464 else
465 cpu_interrupt_ack(cpu, d->irq_nr);
466 }
467 </pre><br>
468
469 <li>And last but not least, the device should have an access function.
470 The access function is called whenever there is a load or store
471 to an address which is in the device' memory mapped region.
472 <pre>
473 int dev_foo_access(struct cpu *cpu, struct memory *mem,
474 uint64_t relative_addr, unsigned char *data, size_t len,
475 int writeflag, void *extra)
476 {
477 struct foo_data *d = extra;
478 uint64_t idata = 0, odata = 0;
479
480 idata = memory_readmax64(cpu, data, len);
481 switch (relative_addr) {
482 /* .... */
483 }
484
485 if (writeflag == MEM_READ)
486 memory_writemax64(cpu, data, len, odata);
487
488 /* Perhaps interrupts need to be asserted or
489 deasserted: */
490 dev_foo_tick(cpu, extra);
491
492 /* Return successfully. */
493 return 1;
494 }
495 </pre><br>
496 </ul>
497
498 <p>
499 The return value of the access function has until 2004-07-02 been a
500 true/false value; 1 for success, or 0 for device access failure. A device
501 access failure (on MIPS) will result in a DBE exception.
502
503 <p>
504 Some devices are converted to support arbitrary memory latency
505 values. The return value is the number of cycles that the read or
506 write access took. A value of 1 means one cycle, a value of 10 means 10
507 cycles. Negative values are used for device access failures, and the
508 absolute value of the value is then the number of cycles; a value of -5
509 means that the access failed, and took 5 cycles.
510
511 <p>
512 To be compatible with pre-20040702 devices, a return value of 0 is treated
513 by the caller (in <tt>src/memory_rw.c</tt>) as a value of -1.
514
515
516
517
518
519 <p><br>
520 <a name="regtest"></a>
521 <h3>Regression tests</h3>
522
523 In order to make sure that the emulator actually works like it is supposed
524 to, it must be tested. For this purpose, there is a simple regression
525 testing framework in the <tt>tests/</tt> directory.
526
527 <p>
528 <i>NOTE: The regression testing framework is basically just a skeleton so far.
529 Regression tests are very good to have. However, the fact that complete
530 operating systems can run in the emulator indicate that the emulation is
531 probably not too incorrect. This makes it less of a priority to write
532 regression tests.</i>
533
534 <p>
535 To run all the regression tests, type <tt>make regtest</tt>. Each assembly
536 language file matching the pattern <tt>test_*.S</tt> will be compiled and
537 linked into a 64-bit MIPS ELF (using a gcc cross compiler), and run in the
538 emulator. If everything goes well, you should see something like this:
539
540 <pre>
541 $ make regtest
542 cd tests; make run_tests; cd ..
543 gcc33 -Wall -fomit-frame-pointer -fmove-all-movables -fpeephole -O2
544 -mcpu=ev5 -I/usr/X11R6/include -lm -L/usr/X11R6/lib -lX11 do_tests.c
545 -o do_tests
546 do_tests.c: In function `main':
547 do_tests.c:173: warning: unused variable `s'
548 /var/tmp//ccFOupvD.o: In function `do_tests':
549 /var/tmp//ccFOupvD.o(.text+0x3a8): warning: tmpnam() possibly used
550 unsafely; consider using mkstemp()
551 mips64-unknown-elf-gcc -g -O3 -fno-builtin -fschedule-insns -mips64
552 -mabi=64 test_common.c -c -o test_common.o
553 ./do_tests "mips64-unknown-elf-gcc -g -O3 -fno-builtin -fschedule-insns
554 -mips64 -mabi=64" "mips64-unknown-elf-as -mabi=64 -mips64"
555 "mips64-unknown-elf-ld -Ttext 0xa800000000030000 -e main
556 --oformat=elf64-bigmips" "../gxemul"
557
558 Starting tests:
559 test_addu.S (-a)
560 test_addu.S (-a -b)
561 test_clo_clz.S (-a)
562 test_clo_clz.S (-a -b)
563 ..
564 test_unaligned.S (-a)
565 test_unaligned.S (-a -b)
566
567 Done. (12 tests done)
568 PASS: 12
569 FAIL: 0
570
571 ----------------
572
573 All tests OK
574
575 ----------------
576 </pre>
577
578 <p>
579 Each test writes output to stdout, and there is a <tt>test_*.good</tt> for
580 each <tt>.S</tt> file which contains the wanted output. If the actual
581 output matches the <tt>.good</tt> file, then the test passes, otherwise it
582 fails.
583
584 <p>
585 Read <tt>tests/README</tt> for more information.
586
587
588
589
590 </body>
591 </html>

  ViewVC Help
Powered by ViewVC 1.1.26