--- trunk/doc/technical.html 2007/10/08 16:18:27 10 +++ trunk/doc/technical.html 2007/10/08 16:19:56 24 @@ -1,18 +1,18 @@ -
|
@@ -52,7 +53,6 @@
Performance depends on several factors, including (but not limited to) -host architecture, host clock speed, which compiler and compiler flags -were used to build the emulator, what the workload is, and so on. For -example, if an emulated operating system tries to read a block from disk, -from its point of view the read was instantaneous (no waiting). So 1 MIPS -in an emulated OS might have taken more than one million instructions on a -real machine. +host architecture, target architecture, host clock speed, which compiler +and compiler flags were used to build the emulator, what the workload is, +what additional runtime flags are given to the emulator, and so on. + +
Devices are generally not timing-accurate: for example, if an emulated +operating system tries to read a block from disk, from its point of view +the read was instantaneous (no waiting). So 1 MIPS in an emulated OS might +have taken more than one million instructions on a real machine.
Also, if the emulator says it has executed 1 million instructions, and the CPU family in question was capable of scalar execution (i.e. one cycle @@ -85,48 +87,16 @@
Because of these issues, it is in my opinion best to measure performance as the actual (real-world) time it takes to perform a task -with the emulator. Typical examples would be "How long does it take to -install NetBSD?", or "How long does it take to compile XYZ inside NetBSD -in the emulator?". - -
The emulation technique used varies depending on which processor type -is being emulated. (One of my main goals with GXemul is to experiment with -different kinds of emulation, so these might change in the future.) +with the emulator, e.g.:
-
-
-
-
So, how fast is it? :-) Answer: it varies. + @@ -330,9 +300,6 @@ files in both directions, but then you should be aware of the fragmentation issue mentioned above. -
TODO: Write a section on how to connect multiple emulator instances. -(Using the local_port and add_remote configuration file -commands.) @@ -343,14 +310,11 @@
NOTE: The device registry subsystem is currently -in a state of flux, as it is being redesigned. +Each file called dev_*.c in the src/device/ directory is +responsible for one hardware device. These are used from +src/machines/machine_*.c, when initializing which hardware a particular +machine model will be using, or when adding devices to a machine using the +device() command in configuration files.
(I'll be using the name "foo" as the name of the device in all these examples. This is pseudo code, it might need some modification to @@ -363,10 +327,7 @@
- /* - * devinit_foo(): - */ - int devinit_foo(struct devinit *devinit) + DEVINIT(foo) { struct foo_data *d = malloc(sizeof(struct foo_data)); @@ -374,7 +335,7 @@ fprintf(stderr, "out of memory\n"); exit(1); } - memset(d, 0, sizeof(struct foon_data)); + memset(d, 0, sizeof(struct foo_data)); /* * Set up stuff here, for example fill d with useful @@ -386,7 +347,7 @@ memory_device_register(devinit->machine->memory, devinit->name, devinit->addr, DEV_FOO_LENGTH, - dev_foo_access, (void *)d, MEM_DEFAULT, NULL); + dev_foo_access, (void *)d, DM_DEFAULT, NULL); /* This should only be here if the device has a tick function: */ @@ -398,6 +359,11 @@ }
DEVINIT(foo) is defined as int devinit_foo(struct devinit *devinit), + and the devinit argument contains everything that the device driver's + initialization function needs. + +
@@ -406,12 +372,17 @@ /* ... */ }
- #define FOO_TICKSHIFT 10 + #define FOO_TICKSHIFT 14 void dev_foo_tick(struct cpu *cpu, void *extra) { @@ -424,13 +395,27 @@ }
- int dev_foo_access(struct cpu *cpu, struct memory *mem, + to an address which is in the device' memory mapped region. To + simplify things a little, a macro DEVICE_ACCESS(x) + is expanded into+ int dev_x_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr, unsigned char *data, size_t len, int writeflag, void *extra) +The access function can look like this: ++ DEVICE_ACCESS(foo) { struct foo_data *d = extra; uint64_t idata = 0, odata = 0; @@ -474,76 +459,6 @@ -Regression tests
- -In order to make sure that the emulator actually works like it is supposed -to, it must be tested. For this purpose, there is a simple regression -testing framework in the tests/ directory. - --NOTE: The regression testing framework is basically just a skeleton so far. -Regression tests are very good to have. However, the fact that complete -operating systems can run in the emulator indicate that the emulation is -probably not too incorrect. This makes it less of a priority to write -regression tests. - -
-To run all the regression tests, type make regtest. Each assembly -language file matching the pattern test_*.S will be compiled and -linked into a 64-bit MIPS ELF (using a gcc cross compiler), and run in the -emulator. If everything goes well, you should see something like this: - -
- $ make regtest - cd tests; make run_tests; cd .. - gcc33 -Wall -fomit-frame-pointer -fmove-all-movables -fpeephole -O2 - -mcpu=ev5 -I/usr/X11R6/include -lm -L/usr/X11R6/lib -lX11 do_tests.c - -o do_tests - do_tests.c: In function `main': - do_tests.c:173: warning: unused variable `s' - /var/tmp//ccFOupvD.o: In function `do_tests': - /var/tmp//ccFOupvD.o(.text+0x3a8): warning: tmpnam() possibly used - unsafely; consider using mkstemp() - mips64-unknown-elf-gcc -g -O3 -fno-builtin -fschedule-insns -mips64 - -mabi=64 test_common.c -c -o test_common.o - ./do_tests "mips64-unknown-elf-gcc -g -O3 -fno-builtin -fschedule-insns - -mips64 -mabi=64" "mips64-unknown-elf-as -mabi=64 -mips64" - "mips64-unknown-elf-ld -Ttext 0xa800000000030000 -e main - --oformat=elf64-bigmips" "../gxemul" - - Starting tests: - test_addu.S (-a) - test_addu.S (-a -b) - test_clo_clz.S (-a) - test_clo_clz.S (-a -b) - .. - test_unaligned.S (-a) - test_unaligned.S (-a -b) - - Done. (12 tests done) - PASS: 12 - FAIL: 0 - - ---------------- - - All tests OK - - ---------------- -- --Each test writes output to stdout, and there is a test_*.good for -each .S file which contains the wanted output. If the actual -output matches the .good file, then the test passes, otherwise it -fails. - -
-Read tests/README for more information. - - -