/[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 12 - (hide annotations)
Mon Oct 8 16:18:38 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/html
File size: 17011 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.905 2005/08/16 09:16:24 debug Exp $
20050628	Continuing the work on the ARM translation engine. end_of_page
		works. Experimenting with load/store translation caches
		(virtual -> physical -> host).
20050629	More ARM stuff (memory access translation cache, mostly). This
		might break a lot of stuff elsewhere, probably some MIPS-
		related translation things.
20050630	Many load/stores are now automatically generated and included
		into cpu_arm_instr.c; 1024 functions in total (!).
		Fixes based on feedback from Alec Voropay: only print 8 hex
		digits instead of 16 in some cases when emulating 32-bit
		machines; similar 8 vs 16 digit fix for breakpoint addresses;
		4Kc has 16 TLB entries, not 48; the MIPS config select1
		register is now printed with "reg ,0".
		Also changing many other occurances of 16 vs 8 digit output.
		Adding cache associativity fields to mips_cpu_types.h; updating
		some other cache fields; making the output of
		mips_cpu_dumpinfo() look nicer.
		Generalizing the bintrans stuff for device accesses to also
		work with the new translation system. (This might also break
		some MIPS things.)
		Adding multi-load/store instructions to the ARM disassembler
		and the translator, and some optimizations of various kinds.
20050701	Adding a simple dev_disk (it can read/write sectors from
		disk images).
20050712	Adding dev_ether (a simple ethernet send/receive device).
		Debugger command "ninstrs" for toggling show_nr_of_instructions
		during runtime.
		Removing the framebuffer logo.
20050713	Continuing on dev_ether.
		Adding a dummy cpu_alpha (again).
20050714	More work on cpu_alpha.
20050715	More work on cpu_alpha. Many instructions work, enough to run
		a simple framebuffer fill test (similar to the ARM test).
20050716	More Alpha stuff.
20050717	Minor updates (Alpha stuff).
20050718	Minor updates (Alpha stuff).
20050719	Generalizing some Alpha instructions.
20050720	More Alpha-related updates.
20050721	Continuing on cpu_alpha. Importing rpb.h from NetBSD/alpha.
20050722	Alpha-related updates: userland stuff (Hello World using
		write() compiled statically for FreeBSD/Alpha runs fine), and
		more instructions are now implemented.
20050723	Fixing ldq_u and stq_u.
		Adding more instructions (conditional moves, masks, extracts,
		shifts).
20050724	More FreeBSD/Alpha userland stuff, and adding some more
		instructions (inserts).
20050725	Continuing on the Alpha stuff. (Adding dummy ldt/stt.)
		Adding a -A command line option to turn off alignment checks
		in some cases (for translated code).
		Trying to remove the old bintrans code which updated the pc
		and nr_of_executed_instructions for every instruction.
20050726	Making another attempt att removing the pc/nr of instructions
		code. This time it worked, huge performance increase for
		artificial test code, but performance loss for real-world
		code :-( so I'm scrapping that code for now.
		Tiny performance increase on Alpha (by using ret instead of
		jmp, to play nice with the Alpha's branch prediction) for the
		old MIPS bintrans backend.
20050727	Various minor fixes and cleanups.
20050728	Switching from a 2-level virtual to host/physical translation
		system for ARM emulation, to a 1-level translation.
		Trying to switch from 2-level to 1-level for the MIPS bintrans
		system as well (Alpha only, so far), but there is at least one
		problem: caches and/or how they work with device mappings.
20050730	Doing the 2-level to 1-level conversion for the i386 backend.
		The cache/device bug is still there for R2K/3K :(
		Various other minor updates (Malta etc).
		The mc146818 clock now updates the UIP bit in a way which works
		better with Linux for at least sgimips and Malta emulation.
		Beginning the work on refactoring the dyntrans system.
20050731	Continuing the dyntrans refactoring.
		Fixing a small but serious host alignment bug in memory_rw.
		Adding support for big-endian load/stores to the i386 bintrans
		backend.
		Another minor i386 bintrans backend update: stores from the
		zero register are now one (or two) loads shorter.
		The slt and sltu instructions were incorrectly implemented for
		the i386 backend; only using them for 32-bit mode for now.
20050801	Continuing the dyntrans refactoring.
		Cleanup of the ns16550 serial controller (removing unnecessary
		code).
		Bugfix (memory corruption bug) in dev_gt, and a patch/hack from
		Alec Voropay for Linux/Malta.
20050802	More cleanup/refactoring of the dyntrans subsystem: adding
		phys_page pointers to the lookup tables, for quick jumps
		between translated pages.
		Better fix for the ns16550 device (but still no real FIFO
		functionality).
		Converting cpu_ppc to the new dyntrans system. This means that
		I will have to start from scratch with implementing each
		instruction, and figure out how to implement dual 64/32-bit
		modes etc.
		Removing the URISC CPU family, because it was useless.
20050803	When selecting a machine type, the main type can now be omitted
		if the subtype name is unique. (I.e. -E can be omitted.)
		Fixing a dyntrans/device update bug. (Writes to offset 0 of
		a device could sometimes go unnoticed.)
		Adding an experimental "instruction combination" hack for
		ARM for memset-like byte fill loops.
20050804	Minor progress on cpu_alpha and related things.
		Finally fixing the MIPS dmult/dmultu bugs.
		Fixing some minor TODOs.
20050805	Generalizing the 8259 PIC. It now also works with Cobalt
		and evbmips emulation, in addition to the x86 hack.
		Finally converting the ns16550 device to use devinit.
		Continuing the work on the dyntrans system. Thinking about
		how to add breakpoints.
20050806	More dyntrans updates. Breakpoints seem to work now.
20050807	Minor updates: cpu_alpha and related things; removing
		dev_malta (as it isn't used any more).
		Dyntrans: working on general "show trace tree" support.
		The trace tree stuff now works with both the old MIPS code and
		with newer dyntrans modes. :)
		Continuing on Alpha-related stuff (trying to get *BSD to boot
		a bit further, adding more instructions, etc).
20050808	Adding a dummy IA64 cpu family, and continuing the refactoring
		of the dyntrans system.
		Removing the regression test stuff, because it was more or
		less useless.
		Adding loadlinked/storeconditional type instructions to the
		Alpha emulation. (Needed for Linux/alpha. Not very well tested
		yet.)
20050809	The function call trace tree now prints a per-function nr of
		arguments. (Semi-meaningless, since that data isn't read yet
		from the ELFs; some hardcoded symbols such as memcpy() and
		strlen() work fine, though.)
		More dyntrans refactoring; taking out more of the things that
		are common to all cpu families.
20050810	Working on adding support for "dual mode" for PPC dyntrans
		(i.e. both 64-bit and 32-bit modes).
		(Re)adding some simple PPC instructions.
20050811	Adding a dummy M68K cpu family. The dyntrans system isn't ready
		for variable-length ISAs yet, so it's completely bogus so far.
		Re-adding more PPC instructions.
		Adding a hack to src/file.c which allows OpenBSD/mac68k a.out
		kernels to be loaded.
		Beginning to add PPC loads/stores. So far they only work in
		32-bit mode.
20050812	The configure file option "add_remote" now accepts symbolic
		host names, in addition to numeric IPv4 addresses.
		Re-adding more PPC instructions.
20050814	Continuing to port back more PPC instructions.
		Found and fixed the cache/device write-update bug for 32-bit
		MIPS bintrans. :-)
		Triggered a really weird and annoying bug in Compaq's C
		compiler; ccc sometimes outputs code which loads from an
		address _before_ checking whether the pointer was NULL or not.
		(I'm not sure how to handle this problem.)
20050815	Removing all of the old x86 instruction execution code; adding
		a new (dummy) dyntrans module for x86.
		Taking the first steps to extend the dyntrans system to support
		variable-length instructions.
		Slowly preparing for the next release.
20050816	Adding a dummy SPARC cpu module.
		Minor updates (documentation etc) for the release.

==============  RELEASE 0.3.5  ==============


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 12 <b>Gavare's eXperimental Emulator:&nbsp;&nbsp;&nbsp;</b></font>
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 12 $Id: technical.html,v 1.62 2005/08/16 05:15:24 debug Exp $
14 dpavlin 2
15     Copyright (C) 2004-2005 Anders Gavare. All rights reserved.
16    
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 10 So, how fast is GXemul? There is no good answer to this. There is
68     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 10 <p>The emulation technique used varies depending on which processor type
93     is being emulated. (One of my main goals with GXemul is to experiment with
94     different kinds of emulation, so these might change in the future.)
95 dpavlin 2
96 dpavlin 10 <ul>
97 dpavlin 12 <li><b>MIPS:</b><br>
98 dpavlin 10 There are two emulation modes. The most important one is an
99     implementation of a <i>dynamic binary translator</i>.
100     (Compared to real binary translators, though, GXemul's bintrans
101     subsystem is very simple and does not perform very well.)
102     This mode can be used on Alpha and i386 host. The other emulation
103     mode is simple interpretation, where an instruction is read from
104     emulated memory, and interpreted one-at-a-time. (Slow, but it
105     works. It can be forcefully used by using the <tt>-B</tt> command
106     line option.)
107     <p>
108 dpavlin 12 <li><b>All other modes:</b><br>
109     These are under development, using a new dynamic translation
110     system. This system does not use host-specific backends.
111     Speed is slower than real binary translation, but faster than
112     traditional interpretation, and with some tricks it will hopefully
113     still give reasonable speed. These modes don't really work yet,
114     and are not enabled by default in the stable release.
115 dpavlin 10 </ul>
116 dpavlin 2
117    
118    
119    
120    
121    
122     <p><br>
123     <a name="net"></a>
124     <h3>Networking</h3>
125    
126 dpavlin 10 <font color="#ff0000">NOTE/TODO: This section is very old and a bit
127     out of date.</font>
128 dpavlin 2
129 dpavlin 10 <p>Running an entire operating system under emulation is very interesting
130     in itself, but for several reasons, running a modern OS without access to
131     TCP/IP networking is a bit akward. Hence, I feel the need to implement
132     TCP/IP (networking) support in the emulator.
133    
134 dpavlin 2 <p>
135     As far as I have understood it, there seems to be two different ways to go:
136    
137     <ol>
138     <li>Forward ethernet packets from the emulated ethernet controller to
139     the host machine's ethernet controller, and capture incoming
140     packets on the host's controller, giving them back to the
141     emulated OS. Characteristics are:
142     <ul>
143     <li>Requires <i>direct</i> access to the host's NIC, which
144     means on most platforms that the emulator cannot be
145     run as a normal user!
146     <li>Reduced portability, as not every host operating system
147     uses the same programming interface for dealing with
148     hardware ethernet controllers directly.
149     <li>When run on a switched network, it might be problematic to
150     connect from the emulated OS to the OS running on the
151     host, as packets sent out on the host's NIC are not
152     received by itself. (?)
153 dpavlin 6 <li>All specific networking protocols will be handled by the
154     physical network.
155 dpavlin 2 </ul>
156     <p>
157     or
158     <p>
159     <li>Whenever the emulated ethernet controller wishes to send a packet,
160     the emulator looks at the packet and creates a response. Packets
161     that can have an immediate response never go outside the emulator,
162     other packet types have to be converted into suitable other
163     connection types (UDP, TCP, etc). Characteristics:
164     <ul>
165     <li>Each packet type sent out on the emulated NIC must be handled.
166     This means that I have to do a lot of coding.
167     (I like this, because it gives me an opportunity to
168     learn about networking protocols.)
169     <li>By not relying on access to the host's NIC directly,
170     portability is maintained. (It would be sad if the networking
171     portion of a portable emulator isn't as portable as the
172     rest of the emulator.)
173     <li>The emulator can be run as a normal user process, does
174     not require root privilegies.
175     <li>Connecting from the emulated OS to the host's OS should
176     not be problematic.
177     <li>The emulated OS will experience the network just as a single
178     machine behind a NAT gateway/firewall would. The emulated
179     OS is thus automatically protected from the outside world.
180     </ul>
181     </ol>
182    
183 dpavlin 6 <p>
184     Some emulators/simulators use the first approach, while others use the
185     second. I think that SIMH and QEMU are examples of emulators using the
186     first and second approach, respectively.
187 dpavlin 2
188     <p>
189     Since I have choosen the second kind of implementation, I have to write
190     support explicitly for any kind of network protocol that should be
191     supported. As of 2004-07-09, the following has been implemented and seems
192     to work under at least NetBSD/pmax and OpenBSD/pmax under DECstation 5000/200
193     emulation (-E dec -e 3max):
194    
195     <p>
196     <ul>
197     <li>ARP requests sent out from the emulated NIC are interpreted,
198     and converted to ARP responses. (This is used by the emulated OS
199     to find out the MAC address of the gateway.)
200     <li>ICMP echo requests (that is the kind of packet produced by the
201 dpavlin 6 <b><tt>ping</tt></b> program) are interpreted and converted to ICMP echo
202 dpavlin 2 replies, <i>regardless of the IP address</i>. This means that
203     running ping from within the emulated OS will <i>always</i>
204     receive a response. The ping packets never leave the emulated
205     environment.
206     <li>UDP packets are interpreted and passed along to the outside world.
207     If the emulator receives an UDP packet from the outside world, it
208     is converted into an UDP packet for the emulated OS. (This is not
209     implemented very well yet, but seems to be enough for nameserver
210     lookups, tftp file transfers, and NFS mounts using UDP.)
211     <li>TCP packets are interpreted one at a time, similar to how UDP
212     packets are handled (but more state is kept for each connection).
213     <font color="#ff0000">NOTE: Much of the TCP handling code is very
214     ugly and hardcoded.</font>
215 dpavlin 6 <!--
216 dpavlin 2 <li>RARP is not implemented yet. (I haven't needed it so far.)
217 dpavlin 6 -->
218 dpavlin 2 </ul>
219    
220 dpavlin 6 <p>
221 dpavlin 2 The gateway machine, which is the only "other" machine that the emulated
222     OS sees on its emulated network, works as a NAT-style firewall/gateway. It
223 dpavlin 6 usually has a fixed IPv4 address of <tt>10.0.0.254</tt>. An OS running in
224     the emulator would usually have an address of the form <tt>10.x.x.x</tt>;
225     a typical choice would be <tt>10.0.0.1</tt>.
226 dpavlin 2
227     <p>
228 dpavlin 6 Inside emulated NetBSD/pmax or OpenBSD/pmax, running the following
229     commands should configure the emulated NIC:
230 dpavlin 2 <pre>
231     # <b>ifconfig le0 10.0.0.1</b>
232     # <b>route add default 10.0.0.254</b>
233     add net default: gateway 10.0.0.254
234     </pre>
235    
236 dpavlin 6 <p>
237 dpavlin 2 If you want nameserver lookups to work, you need a valid /etc/resolv.conf
238     as well:
239     <pre>
240     # <b>echo nameserver 129.16.1.3 > /etc/resolv.conf</b>
241     </pre>
242 dpavlin 6 (But replace <tt>129.16.1.3</tt> with the actual real-world IP address of
243     your nearest nameserver.)
244    
245 dpavlin 2 <p>
246     Now, host lookups should work:
247     <pre>
248     # <b>host -a www.netbsd.org</b>
249     Trying null domain
250     rcode = 0 (Success), ancount=2
251     The following answer is not authoritative:
252     The following answer is not verified as authentic by the server:
253     www.netbsd.org 86400 IN AAAA 2001:4f8:4:7:290:27ff:feab:19a7
254     www.netbsd.org 86400 IN A 204.152.184.116
255     For authoritative answers, see:
256     netbsd.org 83627 IN NS uucp-gw-2.pa.dec.com
257     netbsd.org 83627 IN NS ns.netbsd.org
258     netbsd.org 83627 IN NS adns1.berkeley.edu
259     netbsd.org 83627 IN NS adns2.berkeley.edu
260     netbsd.org 83627 IN NS uucp-gw-1.pa.dec.com
261     Additional information:
262     ns.netbsd.org 83627 IN A 204.152.184.164
263     uucp-gw-1.pa.dec.com 172799 IN A 204.123.2.18
264     uucp-gw-2.pa.dec.com 172799 IN A 204.123.2.19
265     </pre>
266    
267 dpavlin 6 <p>
268     At this point, UDP and TCP should (mostly) work.
269 dpavlin 2
270 dpavlin 6 <p>
271     Here is an example of how to configure a server machine and an emulated
272     client machine for sharing files via NFS:
273 dpavlin 2
274 dpavlin 6 <p>
275     (This is very useful if you want to share entire directory trees
276     between the emulated environment and another machine. These instruction
277     will work for FreeBSD, if you are running something else, use your
278     imagination to modify them.)
279 dpavlin 2
280     <p>
281     <ul>
282     <li>On the server, add a line to your /etc/exports file, exporting
283     the files you wish to use in the emulator:<pre>
284     <b>/tftpboot -mapall=nobody -ro 123.11.22.33</b>
285     </pre>
286     where 123.11.22.33 is the IP address of the machine running the
287     emulator process, as seen from the outside world.
288     <p>
289     <li>Then start up the programs needed to serve NFS via UDP. Note the
290     -n argument to mountd. This is needed to tell mountd to accept
291     connections from unprivileged ports (because the emulator does
292     not need to run as root).<pre>
293     # <b>portmap</b>
294     # <b>nfsd -u</b> &lt;--- u for UDP
295     # <b>mountd -n</b>
296     </pre>
297     <li>In the guest OS in the emulator, once you have ethernet and IPv4
298     configured so that you can use UDP, mounting the filesystem
299     should now be possible: (this example is for NetBSD/pmax
300     or OpenBSD/pmax)<pre>
301     # <b>mount -o ro,-r=1024,-w=1024,-U,-3 my.server.com:/tftpboot /mnt</b>
302     or
303     # <b>mount my.server.com:/tftpboot /mnt</b>
304     </pre>
305     If you don't supply the read and write sizes, there is a risk
306     that the default values are too large. The emulator currently
307     does not handle fragmentation/defragmentation of <i>outgoing</i>
308     packets, so going above the ethernet frame size (1518) is a very
309     bad idea. Incoming packets (reading from nfs) should work, though,
310     for example during an NFS install.
311     </ul>
312    
313     The example above uses read-only mounts. That is enough for things like
314     letting NetBSD/pmax or OpenBSD/pmax install via NFS, without the need for
315     a CDROM ISO image. You can use a read-write mount if you wish to share
316     files in both directions, but then you should be aware of the
317     fragmentation issue mentioned above.
318    
319 dpavlin 10 <p>TODO: Write a section on how to connect multiple emulator instances.
320     (Using the <tt>local_port</tt> and <tt>add_remote</tt> configuration file
321     commands.)
322 dpavlin 2
323    
324    
325    
326 dpavlin 10
327    
328 dpavlin 2 <p><br>
329     <a name="devices"></a>
330     <h3>Emulation of hardware devices</h3>
331    
332 dpavlin 12 Each file in the <tt>src/device/</tt> directory is responsible for one
333 dpavlin 10 hardware device. These are used from <tt>src/machine.c</tt>, when
334     initializing which hardware a particular machine model will be using, or
335     when adding devices to a machine using the <tt>device()</tt> command in
336     configuration files.
337 dpavlin 2
338 dpavlin 10 <p><font color="#ff0000">NOTE: The device registry subsystem is currently
339     in a state of flux, as it is being redesigned.</font>
340 dpavlin 2
341 dpavlin 10 <p>(I'll be using the name "<tt>foo</tt>" as the name of the device in all
342     these examples. This is pseudo code, it might need some modification to
343 dpavlin 2 actually compile and run.)
344    
345 dpavlin 10 <p>Each device should have the following:
346 dpavlin 2
347     <p>
348     <ul>
349 dpavlin 10 <li>A <tt>devinit</tt> function in <tt>src/devices/dev_foo.c</tt>. It
350     would typically look something like this:
351 dpavlin 2 <pre>
352     /*
353     * devinit_foo():
354     */
355     int devinit_foo(struct devinit *devinit)
356     {
357     struct foo_data *d = malloc(sizeof(struct foo_data));
358    
359     if (d == NULL) {
360     fprintf(stderr, "out of memory\n");
361     exit(1);
362     }
363     memset(d, 0, sizeof(struct foon_data));
364    
365     /*
366     * Set up stuff here, for example fill d with useful
367     * data. devinit contains settings like address, irq_nr,
368     * and other things.
369     *
370     * ...
371     */
372    
373     memory_device_register(devinit->machine->memory, devinit->name,
374     devinit->addr, DEV_FOO_LENGTH,
375     dev_foo_access, (void *)d, MEM_DEFAULT, NULL);
376    
377     /* This should only be here if the device
378     has a tick function: */
379     machine_add_tickfunction(machine, dev_foo_tick, d,
380     FOO_TICKSHIFT);
381    
382     /* Return 1 if the device was successfully added. */
383     return 1;
384     }
385     </pre><br>
386    
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    
396 dpavlin 10 <li>If <tt>foo</tt> has a tick function (that is, something that needs to be
397     run at regular intervals) then <tt>FOO_TICKSHIFT</tt> and a tick
398     function need to be defined as well:
399 dpavlin 2 <pre>
400     #define FOO_TICKSHIFT 10
401    
402     void dev_foo_tick(struct cpu *cpu, void *extra)
403     {
404     struct foo_data *d = (struct foo_data *) extra;
405    
406     if (.....)
407     cpu_interrupt(cpu, d->irq_nr);
408     else
409     cpu_interrupt_ack(cpu, d->irq_nr);
410     }
411     </pre><br>
412    
413     <li>And last but not least, the device should have an access function.
414     The access function is called whenever there is a load or store
415     to an address which is in the device' memory mapped region.
416     <pre>
417     int dev_foo_access(struct cpu *cpu, struct memory *mem,
418     uint64_t relative_addr, unsigned char *data, size_t len,
419     int writeflag, void *extra)
420     {
421     struct foo_data *d = extra;
422     uint64_t idata = 0, odata = 0;
423    
424     idata = memory_readmax64(cpu, data, len);
425     switch (relative_addr) {
426     /* .... */
427     }
428    
429     if (writeflag == MEM_READ)
430     memory_writemax64(cpu, data, len, odata);
431    
432     /* Perhaps interrupts need to be asserted or
433     deasserted: */
434     dev_foo_tick(cpu, extra);
435    
436     /* Return successfully. */
437     return 1;
438     }
439     </pre><br>
440     </ul>
441    
442     <p>
443 dpavlin 6 The return value of the access function has until 2004-07-02 been a
444 dpavlin 2 true/false value; 1 for success, or 0 for device access failure. A device
445     access failure (on MIPS) will result in a DBE exception.
446    
447     <p>
448     Some devices are converted to support arbitrary memory latency
449     values. The return value is the number of cycles that the read or
450     write access took. A value of 1 means one cycle, a value of 10 means 10
451     cycles. Negative values are used for device access failures, and the
452     absolute value of the value is then the number of cycles; a value of -5
453     means that the access failed, and took 5 cycles.
454    
455     <p>
456     To be compatible with pre-20040702 devices, a return value of 0 is treated
457 dpavlin 6 by the caller (in <tt>src/memory_rw.c</tt>) as a value of -1.
458 dpavlin 2
459    
460    
461    
462    
463    
464     </body>
465     </html>

  ViewVC Help
Powered by ViewVC 1.1.26