/[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

Annotation of /trunk/doc/technical.html

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (hide annotations)
Mon Oct 8 16:19:37 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/html
File size: 17906 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1121 2006/02/18 21:03:08 debug Exp $
20051126	Cobalt and PReP now work with the 21143 NIC.
		Continuing on Alpha dyntrans things.
		Fixing some more left-shift-by-24 to unsigned.
20051127	Working on OpenFirmware emulation; major cleanup/redesign.
		Progress on MacPPC emulation: NetBSD detects two CPUs (when
		running with -n 2), framebuffer output (for text) works.
		Adding quick-hack Bandit PCI controller and "gc" interrupt
		controller for MacPPC.
20051128	Changing from a Bandit to a Uni-North controller for macppc.
		Continuing on OpenFirmware and MacPPC emulation in general
		(obio controller, and wdc attached to the obio seems to work).
20051129	More work on MacPPC emulation (adding a dummy ADB controller).
		Continuing the PCI bus cleanup (endianness and tag composition)
		and rewriting all PCI controllers' access functions.
20051130	Various minor PPC dyntrans optimizations.
		Manually inlining some parts of the framebuffer redraw routine.
		Slowly beginning the conversion of the old MIPS emulation into
		dyntrans (but this will take quite some time to get right).
		Generalizing quick_pc_to_pointers.
20051201	Documentation update (David Muse has made available a kernel
		which simplifies Debian/DECstation installation).
		Continuing on the ADB bus controller.
20051202	Beginning a rewrite of the Zilog serial controller (dev_zs).
20051203	Continuing on the zs rewrite (now called dev_z8530); conversion
		to devinit style.
		Reworking some of the input-only vs output-only vs input-output
		details of src/console.c, better warning messages, and adding
		a debug dump.
		Removing the concept of "device state"; it wasn't really used.
		Changing some debug output (-vv should now be used to show all
		details about devices and busses; not shown during normal
		startup anymore).
		Beginning on some SPARC instruction disassembly support.
20051204	Minor PPC updates (WALNUT skeleton stuff).
		Continuing on the MIPS dyntrans rewrite.
		More progress on the ADB controller (a keyboard is "detected"
		by NetBSD and OpenBSD).
		Downgrading OpenBSD/arc as a guest OS from "working" to
		"almost working" in the documentation.
		Progress on Algor emulation ("v3" PCI controller).
20051205	Minor updates.
20051207	Sorting devices according to address; this reduces complexity
		of device lookups from O(n) to O(log n) in memory_rw (but no
		real performance increase (yet) in experiments).
20051210	Beginning the work on native dyntrans backends (by making a
		simple skeleton; so far only for Alpha hosts).
20051211	Some very minor SPARC updates.
20051215	Fixing a bug in the MIPS mul (note: not mult) instruction,
		so it also works with non-64-bit emulation. (Thanks to Alec
		Voropay for noticing the problem.)
20051216	More work on the fake/empty/simple/skeleton/whatever backend;
		performance doesn't increase, so this isn't really worth it,
		but it was probably worth it to prepare for a real backend
		later.
20051219	More instr call statistics gathering and analysis stuff.
20051220	Another fix for MIPS 'mul'. Also converting mul and {d,}cl{o,z}
		to dyntrans.
		memory_ppc.c syntax error fix (noticed by Peter Valchev).
		Beginning to move out machines from src/machine.c into
		individual files in src/machines (in a way similar to the
		autodev system for devices).
20051222	Updating the documentation regarding NetBSD/pmax 3.0.
20051223	- " - NetBSD/cats 3.0.
20051225	- " - NetBSD/hpcmips 3.0.
20051226	Continuing on the machine registry redesign.
		Adding support for ARM rrx (33-bit rotate).
		Fixing some signed/unsigned issues (exposed by gcc -W).
20051227	Fixing the bug which prevented a NetBSD/prep 3.0 install kernel
		from starting (triggered when an mtmsr was the last instruction
		on a page). Unfortunately not enough to get the kernel to run
		as well as the 2.1 kernels did.
20051230	Some dyntrans refactoring.
20051231	Continuing on the machine registry redesign.
20060101-10	Continuing... moving more machines. Moving MD interrupt stuff
		from machine.c into a new src/machines/interrupts.c.
20060114	Adding various mvmeppc machine skeletons.
20060115	Continuing on mvme* stuff. NetBSD/mvmeppc prints boot messages
		(for MVME1600) and reaches the root device prompt, but no
		specific hardware devices are emulated yet.
20060116	Minor updates to the mvme1600 emulation mode; the Eagle PCI bus
		seems to work without much modification, and a 21143 can be
		detected, interrupts might work (but untested so far).
		Adding a fake MK48Txx (mkclock) device, for NetBSD/mvmeppc.
20060121	Adding an aux control register for ARM. (A BIG thank you to
		Olivier Houchard for tracking down this bug.)
20060122	Adding more ARM instructions (smulXY), and dev_iq80321_7seg.
20060124	Adding disassembly of more ARM instructions (mia*, mra/mar),
		and some semi-bogus XScale and i80321 registers.
20060201-02	Various minor updates. Moving the last machines out of
		machine.c.
20060204	Adding a -c command line option, for running debugger commands
		before the simulation starts, but after all files have been
		loaded.
		Minor iq80321-related updates.
20060209	Minor hacks (DEVINIT macro, etc).
		Preparing for the generalization of the 64-bit dyntrans address
		translation subsystem.
20060216	Adding ARM ldrd (double-register load).
20060217	Continuing on various ARM-related stuff.
20060218	More progress on the ATA/wdc emulation for NetBSD/iq80321.
		NetBSD/evbarm can now be installed :-)  Updating the docs, etc.
		Continuing on Algor emulation.

==============  RELEASE 0.3.8  ==============


1 dpavlin 12 <html><head><title>Gavare's eXperimental Emulator:&nbsp;&nbsp;&nbsp;Technical details</title>
2 dpavlin 8 <meta name="robots" content="noarchive,nofollow,noindex"></head>
3 dpavlin 4 <body bgcolor="#f8f8f8" text="#000000" link="#4040f0" vlink="#404040" alink="#ff0000">
4     <table border=0 width=100% bgcolor="#d0d0d0"><tr>
5     <td width=100% align=center valign=center><table border=0 width=100%><tr>
6     <td align="left" valign=center bgcolor="#d0efff"><font color="#6060e0" size="6">
7 dpavlin 22 <b>Gavare's eXperimental Emulator:</b></font><br>
8 dpavlin 4 <font color="#000000" size="6"><b>Technical details</b>
9     </font></td></tr></table></td></tr></table><p>
10 dpavlin 2
11     <!--
12    
13 dpavlin 22 $Id: technical.html,v 1.72 2006/02/18 15:18:15 debug Exp $
14 dpavlin 2
15 dpavlin 22 Copyright (C) 2004-2006 Anders Gavare. All rights reserved.
16 dpavlin 2
17     Redistribution and use in source and binary forms, with or without
18     modification, are permitted provided that the following conditions are met:
19    
20     1. Redistributions of source code must retain the above copyright
21     notice, this list of conditions and the following disclaimer.
22     2. Redistributions in binary form must reproduce the above copyright
23     notice, this list of conditions and the following disclaimer in the
24     documentation and/or other materials provided with the distribution.
25     3. The name of the author may not be used to endorse or promote products
26     derived from this software without specific prior written permission.
27    
28     THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
29     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31     ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
32     FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34     OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37     OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38     SUCH DAMAGE.
39    
40     -->
41    
42    
43 dpavlin 12
44 dpavlin 2 <a href="./">Back to the index</a>
45    
46     <p><br>
47     <h2>Technical details</h2>
48    
49 dpavlin 10 <p>This page describes some of the internals of GXemul.
50 dpavlin 2
51     <p>
52     <ul>
53 dpavlin 10 <li><a href="#speed">Speed and emulation modes</a>
54 dpavlin 2 <li><a href="#net">Networking</a>
55     <li><a href="#devices">Emulation of hardware devices</a>
56     </ul>
57    
58    
59    
60    
61    
62    
63     <p><br>
64     <a name="speed"></a>
65 dpavlin 10 <h3>Speed and emulation modes</h3>
66 dpavlin 2
67 dpavlin 14 So, how fast is GXemul? There is no short answer to this. There is
68 dpavlin 10 especially no answer to the question <b>What is the slowdown factor?</b>,
69     because the host architecture and emulated architecture can usually not be
70     compared just like that.
71 dpavlin 2
72 dpavlin 10 <p>Performance depends on several factors, including (but not limited to)
73     host architecture, host clock speed, which compiler and compiler flags
74     were used to build the emulator, what the workload is, and so on. For
75     example, if an emulated operating system tries to read a block from disk,
76     from its point of view the read was instantaneous (no waiting). So 1 MIPS
77     in an emulated OS might have taken more than one million instructions on a
78     real machine.
79 dpavlin 2
80 dpavlin 10 <p>Also, if the emulator says it has executed 1 million instructions, and
81     the CPU family in question was capable of scalar execution (i.e. one cycle
82     per instruction), it might still have taken more than 1 million cycles on
83     a real machine because of cache misses and similar micro-architectural
84     penalties that are not simulated by GXemul.
85 dpavlin 2
86 dpavlin 10 <p>Because of these issues, it is in my opinion best to measure
87     performance as the actual (real-world) time it takes to perform a task
88     with the emulator. Typical examples would be "How long does it take to
89     install NetBSD?", or "How long does it take to compile XYZ inside NetBSD
90     in the emulator?".
91 dpavlin 2
92 dpavlin 14 <p>So, how fast is it? :-)&nbsp;&nbsp;&nbsp;Answer: it varies.
93    
94 dpavlin 10 <p>The emulation technique used varies depending on which processor type
95     is being emulated. (One of my main goals with GXemul is to experiment with
96     different kinds of emulation, so these might change in the future.)
97 dpavlin 2
98 dpavlin 10 <ul>
99 dpavlin 12 <li><b>MIPS:</b><br>
100 dpavlin 10 There are two emulation modes. The most important one is an
101     implementation of a <i>dynamic binary translator</i>.
102     (Compared to real binary translators, though, GXemul's bintrans
103     subsystem is very simple and does not perform very well.)
104     This mode can be used on Alpha and i386 host. The other emulation
105     mode is simple interpretation, where an instruction is read from
106     emulated memory, and interpreted one-at-a-time. (Slow, but it
107     works. It can be forcefully used by using the <tt>-B</tt> command
108     line option.)
109     <p>
110 dpavlin 12 <li><b>All other modes:</b><br>
111 dpavlin 22 These use a kind of dynamic translation system. This system does
112     not recompile anything into native code, it only uses tables of
113     pointers to functions written in (sometimes machine-generated) C
114     code. Speed is lower than what can be achieved using real binary
115     translation into native code, but higher than when traditional
116     interpretation is used. With some tricks, it will hopefully still
117     give reasonable speed. The ARM and PowerPC
118     emulation modes use this kind of translation.
119 dpavlin 10 </ul>
120 dpavlin 2
121    
122    
123    
124    
125    
126     <p><br>
127     <a name="net"></a>
128     <h3>Networking</h3>
129    
130 dpavlin 10 <font color="#ff0000">NOTE/TODO: This section is very old and a bit
131     out of date.</font>
132 dpavlin 2
133 dpavlin 10 <p>Running an entire operating system under emulation is very interesting
134     in itself, but for several reasons, running a modern OS without access to
135     TCP/IP networking is a bit akward. Hence, I feel the need to implement
136     TCP/IP (networking) support in the emulator.
137    
138 dpavlin 2 <p>
139     As far as I have understood it, there seems to be two different ways to go:
140    
141     <ol>
142     <li>Forward ethernet packets from the emulated ethernet controller to
143     the host machine's ethernet controller, and capture incoming
144     packets on the host's controller, giving them back to the
145     emulated OS. Characteristics are:
146     <ul>
147     <li>Requires <i>direct</i> access to the host's NIC, which
148     means on most platforms that the emulator cannot be
149     run as a normal user!
150     <li>Reduced portability, as not every host operating system
151     uses the same programming interface for dealing with
152     hardware ethernet controllers directly.
153     <li>When run on a switched network, it might be problematic to
154     connect from the emulated OS to the OS running on the
155     host, as packets sent out on the host's NIC are not
156     received by itself. (?)
157 dpavlin 6 <li>All specific networking protocols will be handled by the
158     physical network.
159 dpavlin 2 </ul>
160     <p>
161     or
162     <p>
163     <li>Whenever the emulated ethernet controller wishes to send a packet,
164     the emulator looks at the packet and creates a response. Packets
165     that can have an immediate response never go outside the emulator,
166     other packet types have to be converted into suitable other
167     connection types (UDP, TCP, etc). Characteristics:
168     <ul>
169     <li>Each packet type sent out on the emulated NIC must be handled.
170     This means that I have to do a lot of coding.
171     (I like this, because it gives me an opportunity to
172     learn about networking protocols.)
173     <li>By not relying on access to the host's NIC directly,
174     portability is maintained. (It would be sad if the networking
175     portion of a portable emulator isn't as portable as the
176     rest of the emulator.)
177     <li>The emulator can be run as a normal user process, does
178     not require root privilegies.
179     <li>Connecting from the emulated OS to the host's OS should
180     not be problematic.
181     <li>The emulated OS will experience the network just as a single
182     machine behind a NAT gateway/firewall would. The emulated
183     OS is thus automatically protected from the outside world.
184     </ul>
185     </ol>
186    
187 dpavlin 6 <p>
188     Some emulators/simulators use the first approach, while others use the
189     second. I think that SIMH and QEMU are examples of emulators using the
190     first and second approach, respectively.
191 dpavlin 2
192     <p>
193     Since I have choosen the second kind of implementation, I have to write
194     support explicitly for any kind of network protocol that should be
195     supported. As of 2004-07-09, the following has been implemented and seems
196     to work under at least NetBSD/pmax and OpenBSD/pmax under DECstation 5000/200
197     emulation (-E dec -e 3max):
198    
199     <p>
200     <ul>
201     <li>ARP requests sent out from the emulated NIC are interpreted,
202     and converted to ARP responses. (This is used by the emulated OS
203     to find out the MAC address of the gateway.)
204     <li>ICMP echo requests (that is the kind of packet produced by the
205 dpavlin 6 <b><tt>ping</tt></b> program) are interpreted and converted to ICMP echo
206 dpavlin 2 replies, <i>regardless of the IP address</i>. This means that
207     running ping from within the emulated OS will <i>always</i>
208     receive a response. The ping packets never leave the emulated
209     environment.
210     <li>UDP packets are interpreted and passed along to the outside world.
211     If the emulator receives an UDP packet from the outside world, it
212     is converted into an UDP packet for the emulated OS. (This is not
213     implemented very well yet, but seems to be enough for nameserver
214     lookups, tftp file transfers, and NFS mounts using UDP.)
215     <li>TCP packets are interpreted one at a time, similar to how UDP
216     packets are handled (but more state is kept for each connection).
217     <font color="#ff0000">NOTE: Much of the TCP handling code is very
218     ugly and hardcoded.</font>
219 dpavlin 6 <!--
220 dpavlin 2 <li>RARP is not implemented yet. (I haven't needed it so far.)
221 dpavlin 6 -->
222 dpavlin 2 </ul>
223    
224 dpavlin 6 <p>
225 dpavlin 2 The gateway machine, which is the only "other" machine that the emulated
226     OS sees on its emulated network, works as a NAT-style firewall/gateway. It
227 dpavlin 6 usually has a fixed IPv4 address of <tt>10.0.0.254</tt>. An OS running in
228     the emulator would usually have an address of the form <tt>10.x.x.x</tt>;
229     a typical choice would be <tt>10.0.0.1</tt>.
230 dpavlin 2
231     <p>
232 dpavlin 6 Inside emulated NetBSD/pmax or OpenBSD/pmax, running the following
233     commands should configure the emulated NIC:
234 dpavlin 2 <pre>
235     # <b>ifconfig le0 10.0.0.1</b>
236     # <b>route add default 10.0.0.254</b>
237     add net default: gateway 10.0.0.254
238     </pre>
239    
240 dpavlin 6 <p>
241 dpavlin 2 If you want nameserver lookups to work, you need a valid /etc/resolv.conf
242     as well:
243     <pre>
244     # <b>echo nameserver 129.16.1.3 > /etc/resolv.conf</b>
245     </pre>
246 dpavlin 6 (But replace <tt>129.16.1.3</tt> with the actual real-world IP address of
247     your nearest nameserver.)
248    
249 dpavlin 2 <p>
250     Now, host lookups should work:
251     <pre>
252     # <b>host -a www.netbsd.org</b>
253     Trying null domain
254     rcode = 0 (Success), ancount=2
255     The following answer is not authoritative:
256     The following answer is not verified as authentic by the server:
257     www.netbsd.org 86400 IN AAAA 2001:4f8:4:7:290:27ff:feab:19a7
258     www.netbsd.org 86400 IN A 204.152.184.116
259     For authoritative answers, see:
260     netbsd.org 83627 IN NS uucp-gw-2.pa.dec.com
261     netbsd.org 83627 IN NS ns.netbsd.org
262     netbsd.org 83627 IN NS adns1.berkeley.edu
263     netbsd.org 83627 IN NS adns2.berkeley.edu
264     netbsd.org 83627 IN NS uucp-gw-1.pa.dec.com
265     Additional information:
266     ns.netbsd.org 83627 IN A 204.152.184.164
267     uucp-gw-1.pa.dec.com 172799 IN A 204.123.2.18
268     uucp-gw-2.pa.dec.com 172799 IN A 204.123.2.19
269     </pre>
270    
271 dpavlin 6 <p>
272     At this point, UDP and TCP should (mostly) work.
273 dpavlin 2
274 dpavlin 6 <p>
275     Here is an example of how to configure a server machine and an emulated
276     client machine for sharing files via NFS:
277 dpavlin 2
278 dpavlin 6 <p>
279     (This is very useful if you want to share entire directory trees
280     between the emulated environment and another machine. These instruction
281     will work for FreeBSD, if you are running something else, use your
282     imagination to modify them.)
283 dpavlin 2
284     <p>
285     <ul>
286     <li>On the server, add a line to your /etc/exports file, exporting
287     the files you wish to use in the emulator:<pre>
288     <b>/tftpboot -mapall=nobody -ro 123.11.22.33</b>
289     </pre>
290     where 123.11.22.33 is the IP address of the machine running the
291     emulator process, as seen from the outside world.
292     <p>
293     <li>Then start up the programs needed to serve NFS via UDP. Note the
294     -n argument to mountd. This is needed to tell mountd to accept
295     connections from unprivileged ports (because the emulator does
296     not need to run as root).<pre>
297     # <b>portmap</b>
298     # <b>nfsd -u</b> &lt;--- u for UDP
299     # <b>mountd -n</b>
300     </pre>
301     <li>In the guest OS in the emulator, once you have ethernet and IPv4
302     configured so that you can use UDP, mounting the filesystem
303     should now be possible: (this example is for NetBSD/pmax
304     or OpenBSD/pmax)<pre>
305     # <b>mount -o ro,-r=1024,-w=1024,-U,-3 my.server.com:/tftpboot /mnt</b>
306     or
307     # <b>mount my.server.com:/tftpboot /mnt</b>
308     </pre>
309     If you don't supply the read and write sizes, there is a risk
310     that the default values are too large. The emulator currently
311     does not handle fragmentation/defragmentation of <i>outgoing</i>
312     packets, so going above the ethernet frame size (1518) is a very
313     bad idea. Incoming packets (reading from nfs) should work, though,
314     for example during an NFS install.
315     </ul>
316    
317     The example above uses read-only mounts. That is enough for things like
318     letting NetBSD/pmax or OpenBSD/pmax install via NFS, without the need for
319     a CDROM ISO image. You can use a read-write mount if you wish to share
320     files in both directions, but then you should be aware of the
321     fragmentation issue mentioned above.
322    
323    
324    
325    
326    
327 dpavlin 10
328    
329 dpavlin 2 <p><br>
330     <a name="devices"></a>
331     <h3>Emulation of hardware devices</h3>
332    
333 dpavlin 20 Each file called <tt>dev_*.c</tt> in the <tt>src/device/</tt> directory is
334     responsible for one hardware device. These are used from
335 dpavlin 22 <tt>src/machines/machine_*.c</tt>, when initializing which hardware a particular
336 dpavlin 20 machine model will be using, or when adding devices to a machine using the
337     <tt>device()</tt> command in configuration files.
338 dpavlin 2
339 dpavlin 10 <p>(I'll be using the name "<tt>foo</tt>" as the name of the device in all
340     these examples. This is pseudo code, it might need some modification to
341 dpavlin 2 actually compile and run.)
342    
343 dpavlin 10 <p>Each device should have the following:
344 dpavlin 2
345     <p>
346     <ul>
347 dpavlin 10 <li>A <tt>devinit</tt> function in <tt>src/devices/dev_foo.c</tt>. It
348     would typically look something like this:
349 dpavlin 2 <pre>
350 dpavlin 22 DEVINIT(foo)
351 dpavlin 2 {
352     struct foo_data *d = malloc(sizeof(struct foo_data));
353    
354     if (d == NULL) {
355     fprintf(stderr, "out of memory\n");
356     exit(1);
357     }
358 dpavlin 22 memset(d, 0, sizeof(struct foo_data));
359 dpavlin 2
360     /*
361     * Set up stuff here, for example fill d with useful
362     * data. devinit contains settings like address, irq_nr,
363     * and other things.
364     *
365     * ...
366     */
367    
368     memory_device_register(devinit->machine->memory, devinit->name,
369     devinit->addr, DEV_FOO_LENGTH,
370 dpavlin 20 dev_foo_access, (void *)d, DM_DEFAULT, NULL);
371 dpavlin 2
372     /* This should only be here if the device
373     has a tick function: */
374     machine_add_tickfunction(machine, dev_foo_tick, d,
375     FOO_TICKSHIFT);
376    
377     /* Return 1 if the device was successfully added. */
378     return 1;
379     }
380     </pre><br>
381    
382 dpavlin 22 <p><tt>DEVINIT(foo)</tt> is defined as <tt>int devinit_foo(struct devinit *devinit)</tt>,
383     and the <tt>devinit</tt> argument contains everything that the device driver's
384     initialization function needs.
385    
386     <p>
387 dpavlin 10 <li>At the top of <tt>dev_foo.c</tt>, the <tt>foo_data</tt> struct
388     should be defined.
389 dpavlin 2 <pre>
390     struct foo_data {
391     int irq_nr;
392     /* ... */
393     }
394     </pre><br>
395 dpavlin 20 (There is an exception to this rule; ugly hacks which allow
396     code in <tt>src/machine.c</tt> to use some structures makes it
397     necessary to place the <tt>struct foo_data</tt> in
398     <tt>src/include/devices.h</tt> instead of in <tt>dev_foo.c</tt>
399     itself. This is useful for example for interrupt controllers.)
400     <p>
401 dpavlin 10 <li>If <tt>foo</tt> has a tick function (that is, something that needs to be
402     run at regular intervals) then <tt>FOO_TICKSHIFT</tt> and a tick
403     function need to be defined as well:
404 dpavlin 2 <pre>
405 dpavlin 20 #define FOO_TICKSHIFT 14
406 dpavlin 2
407     void dev_foo_tick(struct cpu *cpu, void *extra)
408     {
409     struct foo_data *d = (struct foo_data *) extra;
410    
411     if (.....)
412     cpu_interrupt(cpu, d->irq_nr);
413     else
414     cpu_interrupt_ack(cpu, d->irq_nr);
415     }
416     </pre><br>
417    
418 dpavlin 20 <li>Does this device belong to a standard bus?
419     <ul>
420     <li>If this device should be detectable as a PCI device, then
421     glue code should be added to
422     <tt>src/devices/bus_pci.c</tt>.
423     <li>If this is a legacy ISA device which should be usable by
424     any machine which has an ISA bus, then the device should
425     be added to <tt>src/devices/bus_isa.c</tt>.
426     </ul>
427     <p>
428 dpavlin 2 <li>And last but not least, the device should have an access function.
429     The access function is called whenever there is a load or store
430 dpavlin 22 to an address which is in the device' memory mapped region. To
431     simplify things a little, a macro <tt>DEVICE_ACCESS(x)</tt>
432     is expanded into<pre>
433     int dev_x_access(struct cpu *cpu, struct memory *mem,
434 dpavlin 2 uint64_t relative_addr, unsigned char *data, size_t len,
435     int writeflag, void *extra)
436 dpavlin 22 </pre> The access function can look like this:
437     <pre>
438     DEVICE_ACCESS(foo)
439 dpavlin 2 {
440     struct foo_data *d = extra;
441     uint64_t idata = 0, odata = 0;
442    
443     idata = memory_readmax64(cpu, data, len);
444     switch (relative_addr) {
445     /* .... */
446     }
447    
448     if (writeflag == MEM_READ)
449     memory_writemax64(cpu, data, len, odata);
450    
451     /* Perhaps interrupts need to be asserted or
452     deasserted: */
453     dev_foo_tick(cpu, extra);
454    
455     /* Return successfully. */
456     return 1;
457     }
458     </pre><br>
459     </ul>
460    
461     <p>
462 dpavlin 6 The return value of the access function has until 2004-07-02 been a
463 dpavlin 2 true/false value; 1 for success, or 0 for device access failure. A device
464     access failure (on MIPS) will result in a DBE exception.
465    
466     <p>
467     Some devices are converted to support arbitrary memory latency
468     values. The return value is the number of cycles that the read or
469     write access took. A value of 1 means one cycle, a value of 10 means 10
470     cycles. Negative values are used for device access failures, and the
471     absolute value of the value is then the number of cycles; a value of -5
472     means that the access failed, and took 5 cycles.
473    
474     <p>
475     To be compatible with pre-20040702 devices, a return value of 0 is treated
476 dpavlin 6 by the caller (in <tt>src/memory_rw.c</tt>) as a value of -1.
477 dpavlin 2
478    
479    
480    
481    
482    
483     </body>
484     </html>

  ViewVC Help
Powered by ViewVC 1.1.26