/[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 12 - (show annotations)
Mon Oct 8 16:18:38 2007 UTC (12 years, 2 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 <html><head><title>Gavare's eXperimental Emulator:&nbsp;&nbsp;&nbsp;Technical details</title>
2 <meta name="robots" content="noarchive,nofollow,noindex"></head>
3 <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 <b>Gavare's eXperimental Emulator:&nbsp;&nbsp;&nbsp;</b></font>
8 <font color="#000000" size="6"><b>Technical details</b>
9 </font></td></tr></table></td></tr></table><p>
10
11 <!--
12
13 $Id: technical.html,v 1.62 2005/08/16 05:15:24 debug Exp $
14
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
44 <a href="./">Back to the index</a>
45
46 <p><br>
47 <h2>Technical details</h2>
48
49 <p>This page describes some of the internals of GXemul.
50
51 <p>
52 <ul>
53 <li><a href="#speed">Speed and emulation modes</a>
54 <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 <h3>Speed and emulation modes</h3>
66
67 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
72 <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
80 <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
86 <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
92 <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
96 <ul>
97 <li><b>MIPS:</b><br>
98 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 <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 </ul>
116
117
118
119
120
121
122 <p><br>
123 <a name="net"></a>
124 <h3>Networking</h3>
125
126 <font color="#ff0000">NOTE/TODO: This section is very old and a bit
127 out of date.</font>
128
129 <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 <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 <li>All specific networking protocols will be handled by the
154 physical network.
155 </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 <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
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 <b><tt>ping</tt></b> program) are interpreted and converted to ICMP echo
202 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 <!--
216 <li>RARP is not implemented yet. (I haven't needed it so far.)
217 -->
218 </ul>
219
220 <p>
221 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 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
227 <p>
228 Inside emulated NetBSD/pmax or OpenBSD/pmax, running the following
229 commands should configure the emulated NIC:
230 <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 <p>
237 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 (But replace <tt>129.16.1.3</tt> with the actual real-world IP address of
243 your nearest nameserver.)
244
245 <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 <p>
268 At this point, UDP and TCP should (mostly) work.
269
270 <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
274 <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
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 <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
323
324
325
326
327
328 <p><br>
329 <a name="devices"></a>
330 <h3>Emulation of hardware devices</h3>
331
332 Each file in the <tt>src/device/</tt> directory is responsible for one
333 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
338 <p><font color="#ff0000">NOTE: The device registry subsystem is currently
339 in a state of flux, as it is being redesigned.</font>
340
341 <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 actually compile and run.)
344
345 <p>Each device should have the following:
346
347 <p>
348 <ul>
349 <li>A <tt>devinit</tt> function in <tt>src/devices/dev_foo.c</tt>. It
350 would typically look something like this:
351 <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 <li>At the top of <tt>dev_foo.c</tt>, the <tt>foo_data</tt> struct
388 should be defined.
389 <pre>
390 struct foo_data {
391 int irq_nr;
392 /* ... */
393 }
394 </pre><br>
395
396 <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 <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 The return value of the access function has until 2004-07-02 been a
444 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 by the caller (in <tt>src/memory_rw.c</tt>) as a value of -1.
458
459
460
461
462
463
464 </body>
465 </html>

  ViewVC Help
Powered by ViewVC 1.1.26