Commit 285dc330bd28aa0e097106875bb184e2707bbed5
1 parent
baf8ebf0
update
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@417 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
9 changed files
with
47 additions
and
320 deletions
Changelog
| 1 | -version 0.4.4: | |
| 1 | +version 0.5.0: | |
| 2 | 2 | |
| 3 | 3 | - full hardware level VGA emulation |
| 4 | 4 | - graphical display with SDL |
| ... | ... | @@ -16,8 +16,9 @@ version 0.4.4: |
| 16 | 16 | - preliminary SPARC target support (Thomas M. Ogrisegg) |
| 17 | 17 | - tun-fd option (Rusty Russell) |
| 18 | 18 | - automatic IDE geometry detection |
| 19 | - - renamed 'vl' to qemu and user qemu to qemu-{cpu}. | |
| 19 | + - renamed 'vl' to qemu[-fast] and user qemu to qemu-{cpu}. | |
| 20 | 20 | - added man page |
| 21 | + - added full soft mmy mode to launch unpatched OSes. | |
| 21 | 22 | |
| 22 | 23 | version 0.4.3: |
| 23 | 24 | ... | ... |
README
| ... | ... | @@ -6,35 +6,17 @@ INSTALLATION |
| 6 | 6 | |
| 7 | 7 | Type |
| 8 | 8 | |
| 9 | - ./configure --interp-prefix=/usr/local/qemu-i386 | |
| 9 | + ./configure | |
| 10 | 10 | make |
| 11 | 11 | |
| 12 | -to build qemu and libqemu.a. | |
| 12 | +to build qemu, qemu-CPU and libqemu.a (CPU is the name of the various | |
| 13 | +supported target CPUs). | |
| 13 | 14 | |
| 14 | 15 | Type |
| 15 | 16 | |
| 16 | 17 | make install |
| 17 | 18 | |
| 18 | -to install QEMU in /usr/local/bin | |
| 19 | - | |
| 20 | -* On x86 you should be able to launch any program by using the | |
| 21 | -libraries installed on your PC. For example: | |
| 22 | - | |
| 23 | - ./qemu -L / /bin/ls | |
| 24 | - | |
| 25 | -* On non x86 CPUs, you need first to download at least an x86 glibc | |
| 26 | -(qemu-XXX-i386-glibc21.tar.gz on the qemu web page). Ensure that | |
| 27 | -LD_LIBRARY_PATH is not set: | |
| 28 | - | |
| 29 | - unset LD_LIBRARY_PATH | |
| 30 | - | |
| 31 | -Then you can launch the precompiled 'ls' x86 executable: | |
| 32 | - | |
| 33 | - ./qemu /usr/local/qemu-i386/bin/ls-i386 | |
| 34 | - | |
| 35 | -You can look at /usr/local/qemu-i386/bin/qemu-conf.sh so that QEMU is | |
| 36 | -automatically launched by the Linux kernel when you try to launch x86 | |
| 37 | -executables. | |
| 19 | +to install QEMU in /usr/local | |
| 38 | 20 | |
| 39 | 21 | Tested tool versions |
| 40 | 22 | -------------------- | ... | ... |
README.distrib
| ... | ... | @@ -6,11 +6,11 @@ x86 binary distribution: |
| 6 | 6 | |
| 7 | 7 | * wine-20020411 tarball |
| 8 | 8 | |
| 9 | - ./configure --prefix=/usr/local/qemu-i386/wine | |
| 9 | + ./configure --prefix=/usr/local/wine-i386 | |
| 10 | 10 | |
| 11 | 11 | All exe and libs were stripped. Some compile time tools and the |
| 12 | 12 | includes were deleted. |
| 13 | 13 | |
| 14 | 14 | * ldconfig was launched to build the library links: |
| 15 | 15 | |
| 16 | - ./qemu /usr/local/qemu-i386/bin/ldconfig-i386 -C /usr/local/qemu-i386/etc/ld.so.cache | |
| 16 | + qemu-i386 /usr/gnemul/qemu-i386/bin/ldconfig-i386 -C /usr/gnemul/qemu-i386/etc/ld.so.cache | ... | ... |
TODO
| 1 | +- tests for each target CPU | |
| 2 | +- ppc qemu test | |
| 1 | 3 | - optimize FPU operations (evaluate x87 stack pointer statically) and |
| 2 | 4 | fix cr0.TS emulation |
| 5 | +- fix some 16 bit sp push/pop overflow | |
| 6 | +- sysenter/sysexit emulation | |
| 7 | +- finish segment ops (call far, ret far, load_seg suppressed) | |
| 3 | 8 | - fix CCOP optimisation |
| 4 | 9 | - fix all remaining thread lock issues (must put TBs in a specific invalid |
| 5 | 10 | state, find a solution for tb_flush()). |
| 6 | 11 | - cpu loop optimisation (optimise ret case as the cpu state does not change) |
| 7 | 12 | - fix arm fpu rounding (at least for float->integer conversions) |
| 8 | -- add IPC syscalls | |
| 9 | 13 | |
| 10 | 14 | lower priority: |
| 11 | 15 | -------------- |
| 12 | -- sysenter/sysexit emulation | |
| 16 | +- add IPC syscalls | |
| 13 | 17 | - SMP support |
| 14 | -- finish segment ops (call far, ret far, load_seg suppressed) | |
| 15 | 18 | - use -msoft-float on ARM |
| 16 | 19 | - use kernel traps for unaligned accesses on ARM ? |
| 17 | 20 | - handle rare page fault cases (in particular if page fault in heplers or | ... | ... |
VERSION
qemu-doc.texi
| ... | ... | @@ -72,7 +72,7 @@ QEMU user mode emulation features: |
| 72 | 72 | |
| 73 | 73 | QEMU full system emulation features: |
| 74 | 74 | @itemize |
| 75 | -@item Using mmap() system calls to simulate the MMU | |
| 75 | +@item QEMU can either use a full software MMU for maximum portability or use the host system call mmap() to simulate the target MMU. | |
| 76 | 76 | @end itemize |
| 77 | 77 | |
| 78 | 78 | @section x86 emulation |
| ... | ... | @@ -110,14 +110,7 @@ memory access. |
| 110 | 110 | 10 byte @code{long double}s of x86 for floating point emulation to get |
| 111 | 111 | maximum performances. |
| 112 | 112 | |
| 113 | -@item Full system emulation only works if no data are mapped above the virtual address | |
| 114 | -0xc0000000 (yet). | |
| 115 | - | |
| 116 | -@item Some priviledged instructions or behaviors are missing. Only the ones | |
| 117 | -needed for proper Linux kernel operation are emulated. | |
| 118 | - | |
| 119 | -@item No memory separation between the kernel and the user processes is done. | |
| 120 | -It will be implemented very soon. | |
| 113 | +@item Some priviledged instructions or behaviors are missing, especially for segment protection testing (yet). | |
| 121 | 114 | |
| 122 | 115 | @end itemize |
| 123 | 116 | |
| ... | ... | @@ -177,9 +170,9 @@ unset LD_LIBRARY_PATH |
| 177 | 170 | Then you can launch the precompiled @file{ls} x86 executable: |
| 178 | 171 | |
| 179 | 172 | @example |
| 180 | -qemu-i386 /usr/local/qemu-i386/bin/ls-i386 | |
| 173 | +qemu-i386 tests/i386/ls | |
| 181 | 174 | @end example |
| 182 | -You can look at @file{/usr/local/qemu-i386/bin/qemu-conf.sh} so that | |
| 175 | +You can look at @file{qemu-binfmt-conf.sh} so that | |
| 183 | 176 | QEMU is automatically launched by the Linux kernel when you try to |
| 184 | 177 | launch x86 executables. It requires the @code{binfmt_misc} module in the |
| 185 | 178 | Linux kernel. |
| ... | ... | @@ -258,16 +251,15 @@ available: |
| 258 | 251 | @enumerate |
| 259 | 252 | |
| 260 | 253 | @item |
| 261 | -@code{qemu} uses the host Memory Management Unit (MMU) to simulate | |
| 254 | +@code{qemu-fast} uses the host Memory Management Unit (MMU) to simulate | |
| 262 | 255 | the x86 MMU. It is @emph{fast} but has limitations because the whole 4 GB |
| 263 | 256 | address space cannot be used and some memory mapped peripherials |
| 264 | 257 | cannot be emulated accurately yet. Therefore, a specific Linux kernel |
| 265 | 258 | must be used (@xref{linux_compile}). |
| 266 | 259 | |
| 267 | 260 | @item |
| 268 | -@code{qemu-softmmu} uses a software MMU. It is about @emph{two times | |
| 269 | -slower} but gives a more accurate emulation. (XXX: Linux cannot be ran | |
| 270 | -unpatched yet). | |
| 261 | +@code{qemu} uses a software MMU. It is about @emph{two times | |
| 262 | +slower} but gives a more accurate emulation. | |
| 271 | 263 | |
| 272 | 264 | @end enumerate |
| 273 | 265 | |
| ... | ... | @@ -296,10 +288,10 @@ CMOS memory |
| 296 | 288 | |
| 297 | 289 | @section Quick Start |
| 298 | 290 | |
| 299 | -Download the linux image (@file{linux.img}) and type: | |
| 291 | +Download and uncompress the linux image (@file{linux.img}) and type: | |
| 300 | 292 | |
| 301 | 293 | @example |
| 302 | -qemu-softmmu linux.img | |
| 294 | +qemu linux.img | |
| 303 | 295 | @end example |
| 304 | 296 | |
| 305 | 297 | Linux should boot and give you a prompt. |
| ... | ... | @@ -627,8 +619,10 @@ the real one. To know it, use the @code{ls -ls} command. |
| 627 | 619 | @node linux_compile |
| 628 | 620 | @section Linux Kernel Compilation |
| 629 | 621 | |
| 630 | -You should be able to use any kernel with QEMU provided you make the | |
| 631 | -following changes (only 2.4.x and 2.5.x were tested): | |
| 622 | +You can use any linux kernel with QEMU. However, if you want to use | |
| 623 | +@code{qemu-fast} to get maximum performances, you should make the | |
| 624 | +following changes to the Linux kernel (only 2.4.x and 2.5.x were | |
| 625 | +tested): | |
| 632 | 626 | |
| 633 | 627 | @enumerate |
| 634 | 628 | @item |
| ... | ... | @@ -723,8 +717,6 @@ Then you can use gdb normally. For example, type 'c' to launch the kernel: |
| 723 | 717 | (gdb) c |
| 724 | 718 | @end example |
| 725 | 719 | |
| 726 | -WARNING: breakpoints and single stepping are not yet supported. | |
| 727 | - | |
| 728 | 720 | Here are some useful tips in order to use gdb on system code: |
| 729 | 721 | |
| 730 | 722 | @enumerate |
| ... | ... | @@ -1019,16 +1011,6 @@ The new Plex86 project. |
| 1019 | 1011 | In the directory @file{tests/}, various interesting testing programs |
| 1020 | 1012 | are available. There are used for regression testing. |
| 1021 | 1013 | |
| 1022 | -@section @file{hello-i386} | |
| 1023 | - | |
| 1024 | -Very simple statically linked x86 program, just to test QEMU during a | |
| 1025 | -port to a new host CPU. | |
| 1026 | - | |
| 1027 | -@section @file{hello-arm} | |
| 1028 | - | |
| 1029 | -Very simple statically linked ARM program, just to test QEMU during a | |
| 1030 | -port to a new host CPU. | |
| 1031 | - | |
| 1032 | 1014 | @section @file{test-i386} |
| 1033 | 1015 | |
| 1034 | 1016 | This program executes most of the 16 bit and 32 bit x86 instructions and |
| ... | ... | @@ -1044,6 +1026,22 @@ The Linux system call @code{vm86()} is used to test vm86 emulation. |
| 1044 | 1026 | Various exceptions are raised to test most of the x86 user space |
| 1045 | 1027 | exception reporting. |
| 1046 | 1028 | |
| 1029 | +@section @file{linux-test} | |
| 1030 | + | |
| 1031 | +This program tests various Linux system calls. It is used to verify | |
| 1032 | +that the system call parameters are correctly converted between target | |
| 1033 | +and host CPUs. | |
| 1034 | + | |
| 1035 | +@section @file{hello-i386} | |
| 1036 | + | |
| 1037 | +Very simple statically linked x86 program, just to test QEMU during a | |
| 1038 | +port to a new host CPU. | |
| 1039 | + | |
| 1040 | +@section @file{hello-arm} | |
| 1041 | + | |
| 1042 | +Very simple statically linked ARM program, just to test QEMU during a | |
| 1043 | +port to a new host CPU. | |
| 1044 | + | |
| 1047 | 1045 | @section @file{sha1} |
| 1048 | 1046 | |
| 1049 | 1047 | It is a simple benchmark. Care must be taken to interpret the results | ... | ... |
tests/linux-test.c
| ... | ... | @@ -71,7 +71,7 @@ int __chk_error(const char *filename, int line, int ret) |
| 71 | 71 | |
| 72 | 72 | #define FILE_BUF_SIZE 300 |
| 73 | 73 | |
| 74 | -void file_test(void) | |
| 74 | +void test_file(void) | |
| 75 | 75 | { |
| 76 | 76 | int fd, i, len, ret; |
| 77 | 77 | uint8_t buf[FILE_BUF_SIZE]; |
| ... | ... | @@ -499,7 +499,7 @@ void test_signal(void) |
| 499 | 499 | |
| 500 | 500 | int main(int argc, char **argv) |
| 501 | 501 | { |
| 502 | - file_test(); | |
| 502 | + test_file(); | |
| 503 | 503 | test_fork(); |
| 504 | 504 | test_time(); |
| 505 | 505 | test_socket(); |
| ... | ... | @@ -507,4 +507,3 @@ int main(int argc, char **argv) |
| 507 | 507 | test_signal(); |
| 508 | 508 | return 0; |
| 509 | 509 | } |
| 510 | - | ... | ... |
tests/testclone.c deleted
100644 โ 0
| 1 | -#include <stdlib.h> | |
| 2 | -#include <stdio.h> | |
| 3 | -#include <string.h> | |
| 4 | -#include <signal.h> | |
| 5 | -#include <unistd.h> | |
| 6 | -#include <inttypes.h> | |
| 7 | -#include <pthread.h> | |
| 8 | -#include <sys/wait.h> | |
| 9 | -#include <sched.h> | |
| 10 | - | |
| 11 | -int thread1_func(void *arg) | |
| 12 | -{ | |
| 13 | - int i; | |
| 14 | - char buf[512]; | |
| 15 | - | |
| 16 | - for(i=0;i<10;i++) { | |
| 17 | - snprintf(buf, sizeof(buf), "thread1: %d %s\n", i, (char *)arg); | |
| 18 | - write(1, buf, strlen(buf)); | |
| 19 | - usleep(100 * 1000); | |
| 20 | - } | |
| 21 | - return 0; | |
| 22 | -} | |
| 23 | - | |
| 24 | -int thread2_func(void *arg) | |
| 25 | -{ | |
| 26 | - int i; | |
| 27 | - char buf[512]; | |
| 28 | - for(i=0;i<20;i++) { | |
| 29 | - snprintf(buf, sizeof(buf), "thread2: %d %s\n", i, (char *)arg); | |
| 30 | - write(1, buf, strlen(buf)); | |
| 31 | - usleep(120 * 1000); | |
| 32 | - } | |
| 33 | - return 0; | |
| 34 | -} | |
| 35 | - | |
| 36 | -#define STACK_SIZE 16384 | |
| 37 | - | |
| 38 | -void test_clone(void) | |
| 39 | -{ | |
| 40 | - uint8_t *stack1, *stack2; | |
| 41 | - int pid1, pid2, status1, status2; | |
| 42 | - | |
| 43 | - stack1 = malloc(STACK_SIZE); | |
| 44 | - pid1 = clone(thread1_func, stack1 + STACK_SIZE, | |
| 45 | - CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello1"); | |
| 46 | - | |
| 47 | - stack2 = malloc(STACK_SIZE); | |
| 48 | - pid2 = clone(thread2_func, stack2 + STACK_SIZE, | |
| 49 | - CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello2"); | |
| 50 | - | |
| 51 | - while (waitpid(pid1, &status1, 0) != pid1); | |
| 52 | - while (waitpid(pid2, &status2, 0) != pid2); | |
| 53 | - printf("status1=0x%x\n", status1); | |
| 54 | - printf("status2=0x%x\n", status2); | |
| 55 | - printf("End of clone test.\n"); | |
| 56 | -} | |
| 57 | - | |
| 58 | -int main(int argc, char **argv) | |
| 59 | -{ | |
| 60 | - test_clone(); | |
| 61 | - return 0; | |
| 62 | -} |
tests/testsig.c deleted
100644 โ 0
| 1 | -#define _GNU_SOURCE | |
| 2 | -#include <stdlib.h> | |
| 3 | -#include <stdio.h> | |
| 4 | -#include <string.h> | |
| 5 | -#include <signal.h> | |
| 6 | -#include <unistd.h> | |
| 7 | -#include <setjmp.h> | |
| 8 | -#include <sys/ucontext.h> | |
| 9 | - | |
| 10 | -jmp_buf jmp_env; | |
| 11 | - | |
| 12 | -void alarm_handler(int sig) | |
| 13 | -{ | |
| 14 | - printf("alarm signal=%d\n", sig); | |
| 15 | - alarm(1); | |
| 16 | -} | |
| 17 | - | |
| 18 | -#ifndef REG_EAX | |
| 19 | -#define REG_EAX EAX | |
| 20 | -#define REG_EBX EBX | |
| 21 | -#define REG_ECX ECX | |
| 22 | -#define REG_EDX EDX | |
| 23 | -#define REG_ESI ESI | |
| 24 | -#define REG_EDI EDI | |
| 25 | -#define REG_EBP EBP | |
| 26 | -#define REG_ESP ESP | |
| 27 | -#define REG_EIP EIP | |
| 28 | -#define REG_EFL EFL | |
| 29 | -#define REG_TRAPNO TRAPNO | |
| 30 | -#define REG_ERR ERR | |
| 31 | -#endif | |
| 32 | - | |
| 33 | -void dump_regs(struct ucontext *uc) | |
| 34 | -{ | |
| 35 | - printf("EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n" | |
| 36 | - "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n" | |
| 37 | - "EFL=%08x EIP=%08x trapno=%02x err=%08x\n", | |
| 38 | - uc->uc_mcontext.gregs[REG_EAX], | |
| 39 | - uc->uc_mcontext.gregs[REG_EBX], | |
| 40 | - uc->uc_mcontext.gregs[REG_ECX], | |
| 41 | - uc->uc_mcontext.gregs[REG_EDX], | |
| 42 | - uc->uc_mcontext.gregs[REG_ESI], | |
| 43 | - uc->uc_mcontext.gregs[REG_EDI], | |
| 44 | - uc->uc_mcontext.gregs[REG_EBP], | |
| 45 | - uc->uc_mcontext.gregs[REG_ESP], | |
| 46 | - uc->uc_mcontext.gregs[REG_EFL], | |
| 47 | - uc->uc_mcontext.gregs[REG_EIP], | |
| 48 | - uc->uc_mcontext.gregs[REG_TRAPNO], | |
| 49 | - uc->uc_mcontext.gregs[REG_ERR]); | |
| 50 | -} | |
| 51 | - | |
| 52 | -void sig_handler(int sig, siginfo_t *info, void *puc) | |
| 53 | -{ | |
| 54 | - struct ucontext *uc = puc; | |
| 55 | - | |
| 56 | - printf("%s: si_signo=%d si_errno=%d si_code=%d si_addr=0x%08lx\n", | |
| 57 | - strsignal(info->si_signo), | |
| 58 | - info->si_signo, info->si_errno, info->si_code, | |
| 59 | - (unsigned long)info->si_addr); | |
| 60 | - dump_regs(uc); | |
| 61 | - longjmp(jmp_env, 1); | |
| 62 | -} | |
| 63 | - | |
| 64 | -int v1; | |
| 65 | -int tab[2]; | |
| 66 | - | |
| 67 | -int main(int argc, char **argv) | |
| 68 | -{ | |
| 69 | - struct sigaction act; | |
| 70 | - volatile int val; | |
| 71 | - | |
| 72 | - act.sa_sigaction = sig_handler; | |
| 73 | - sigemptyset(&act.sa_mask); | |
| 74 | - act.sa_flags = SA_SIGINFO; | |
| 75 | - sigaction(SIGFPE, &act, NULL); | |
| 76 | - sigaction(SIGILL, &act, NULL); | |
| 77 | - sigaction(SIGSEGV, &act, NULL); | |
| 78 | - sigaction(SIGTRAP, &act, NULL); | |
| 79 | - | |
| 80 | - /* test division by zero reporting */ | |
| 81 | - if (setjmp(jmp_env) == 0) { | |
| 82 | - /* now divide by zero */ | |
| 83 | - v1 = 0; | |
| 84 | - v1 = 2 / v1; | |
| 85 | - } | |
| 86 | - | |
| 87 | - /* test illegal instruction reporting */ | |
| 88 | - if (setjmp(jmp_env) == 0) { | |
| 89 | - /* now execute an invalid instruction */ | |
| 90 | - asm volatile("ud2"); | |
| 91 | - } | |
| 92 | - | |
| 93 | - /* test SEGV reporting */ | |
| 94 | - if (setjmp(jmp_env) == 0) { | |
| 95 | - /* now store in an invalid address */ | |
| 96 | - *(char *)0x1234 = 1; | |
| 97 | - } | |
| 98 | - | |
| 99 | - /* test SEGV reporting */ | |
| 100 | - if (setjmp(jmp_env) == 0) { | |
| 101 | - /* read from an invalid address */ | |
| 102 | - v1 = *(char *)0x1234; | |
| 103 | - } | |
| 104 | - | |
| 105 | - printf("segment GPF exception:\n"); | |
| 106 | - if (setjmp(jmp_env) == 0) { | |
| 107 | - /* load an invalid segment */ | |
| 108 | - asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 0)); | |
| 109 | - } | |
| 110 | - | |
| 111 | - printf("INT exception:\n"); | |
| 112 | - if (setjmp(jmp_env) == 0) { | |
| 113 | - asm volatile ("int $0xfd"); | |
| 114 | - } | |
| 115 | - | |
| 116 | - printf("INT3 exception:\n"); | |
| 117 | - if (setjmp(jmp_env) == 0) { | |
| 118 | - asm volatile ("int3"); | |
| 119 | - } | |
| 120 | - | |
| 121 | - printf("CLI exception:\n"); | |
| 122 | - if (setjmp(jmp_env) == 0) { | |
| 123 | - asm volatile ("cli"); | |
| 124 | - } | |
| 125 | - | |
| 126 | - printf("STI exception:\n"); | |
| 127 | - if (setjmp(jmp_env) == 0) { | |
| 128 | - asm volatile ("cli"); | |
| 129 | - } | |
| 130 | - | |
| 131 | - printf("INTO exception:\n"); | |
| 132 | - if (setjmp(jmp_env) == 0) { | |
| 133 | - /* overflow exception */ | |
| 134 | - asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff)); | |
| 135 | - } | |
| 136 | - | |
| 137 | - printf("BOUND exception:\n"); | |
| 138 | - if (setjmp(jmp_env) == 0) { | |
| 139 | - /* bound exception */ | |
| 140 | - tab[0] = 1; | |
| 141 | - tab[1] = 10; | |
| 142 | - asm volatile ("bound %0, %1" : : "r" (11), "m" (tab)); | |
| 143 | - } | |
| 144 | - | |
| 145 | - printf("OUTB exception:\n"); | |
| 146 | - if (setjmp(jmp_env) == 0) { | |
| 147 | - asm volatile ("outb %%al, %%dx" : : "d" (0x4321), "a" (0)); | |
| 148 | - } | |
| 149 | - | |
| 150 | - printf("INB exception:\n"); | |
| 151 | - if (setjmp(jmp_env) == 0) { | |
| 152 | - asm volatile ("inb %%dx, %%al" : "=a" (val) : "d" (0x4321)); | |
| 153 | - } | |
| 154 | - | |
| 155 | - printf("REP OUTSB exception:\n"); | |
| 156 | - if (setjmp(jmp_env) == 0) { | |
| 157 | - asm volatile ("rep outsb" : : "d" (0x4321), "S" (tab), "c" (1)); | |
| 158 | - } | |
| 159 | - | |
| 160 | - printf("REP INSB exception:\n"); | |
| 161 | - if (setjmp(jmp_env) == 0) { | |
| 162 | - asm volatile ("rep insb" : : "d" (0x4321), "D" (tab), "c" (1)); | |
| 163 | - } | |
| 164 | - | |
| 165 | - printf("HLT exception:\n"); | |
| 166 | - if (setjmp(jmp_env) == 0) { | |
| 167 | - asm volatile ("hlt"); | |
| 168 | - } | |
| 169 | - | |
| 170 | - printf("single step exception:\n"); | |
| 171 | - val = 0; | |
| 172 | - if (setjmp(jmp_env) == 0) { | |
| 173 | - asm volatile ("pushf\n" | |
| 174 | - "orl $0x00100, (%%esp)\n" | |
| 175 | - "popf\n" | |
| 176 | - "movl $0xabcd, %0\n" : "=m" (val) : : "cc", "memory"); | |
| 177 | - } | |
| 178 | - printf("val=0x%x\n", val); | |
| 179 | - | |
| 180 | -#if 1 | |
| 181 | - { | |
| 182 | - int i; | |
| 183 | - act.sa_handler = alarm_handler; | |
| 184 | - sigemptyset(&act.sa_mask); | |
| 185 | - act.sa_flags = 0; | |
| 186 | - sigaction(SIGALRM, &act, NULL); | |
| 187 | - alarm(1); | |
| 188 | - for(i = 0;i < 2; i++) { | |
| 189 | - sleep(1); | |
| 190 | - } | |
| 191 | - } | |
| 192 | -#endif | |
| 193 | - return 0; | |
| 194 | -} |