├── Changelog ├── MIT-LICENSE.txt ├── Makefile ├── Makefile.js ├── VERSION ├── aes.c ├── aes.h ├── block_net.c ├── build_filelist.c ├── cutils.c ├── cutils.h ├── fbuf.h ├── fs.c ├── fs.h ├── fs_disk.c ├── fs_net.c ├── fs_utils.c ├── fs_utils.h ├── fs_wget.c ├── fs_wget.h ├── ide.c ├── ide.h ├── iomem.c ├── iomem.h ├── js └── lib.js ├── jsemu.c ├── jslinux-2019-12-21 ├── bbl64.bin ├── images │ ├── bg-scrollbar-thumb-y.png │ ├── bg-scrollbar-track-y.png │ ├── bg-scrollbar-trackend-y.png │ └── upload-icon.png ├── index.html ├── jslinux.js ├── kernel-riscv64.bin ├── kernel-x86.bin ├── readme.txt ├── riscvemu32-wasm.js ├── riscvemu32-wasm.wasm ├── riscvemu32.js ├── riscvemu64-wasm.js ├── riscvemu64-wasm.wasm ├── riscvemu64.js ├── root-riscv64.bin ├── root-riscv64.cfg ├── root-riscv64 │ ├── blk.txt │ ├── blk000000000.bin │ ├── blk000000001.bin │ ├── blk000000002.bin │ ├── blk000000003.bin │ ├── blk000000004.bin │ ├── blk000000005.bin │ ├── blk000000006.bin │ ├── blk000000007.bin │ ├── blk000000008.bin │ ├── blk000000009.bin │ ├── blk000000010.bin │ ├── blk000000011.bin │ ├── blk000000012.bin │ ├── blk000000013.bin │ ├── blk000000014.bin │ └── blk000000015.bin ├── root-x86.bin ├── root-x86.cfg ├── root-x86 │ ├── blk.txt │ ├── blk000000000.bin │ ├── blk000000001.bin │ ├── blk000000002.bin │ ├── blk000000003.bin │ ├── blk000000004.bin │ ├── blk000000005.bin │ ├── blk000000006.bin │ ├── blk000000007.bin │ ├── blk000000008.bin │ ├── blk000000009.bin │ ├── blk000000010.bin │ ├── blk000000011.bin │ ├── blk000000012.bin │ ├── blk000000013.bin │ ├── blk000000014.bin │ └── blk000000015.bin ├── style.css ├── term.js ├── x86emu-wasm.js ├── x86emu-wasm.wasm └── x86emu.js ├── json.c ├── json.h ├── list.h ├── machine.c ├── machine.h ├── netinit.sh ├── pci.c ├── pci.h ├── pckbd.c ├── ps2.c ├── ps2.h ├── readme.txt ├── riscv_cpu.c ├── riscv_cpu.h ├── riscv_cpu_fp_template.h ├── riscv_cpu_priv.h ├── riscv_cpu_template.h ├── riscv_machine.c ├── sdl.c ├── sha256.c ├── sha256.h ├── simplefb.c ├── slirp ├── bootp.c ├── bootp.h ├── cksum.c ├── debug.h ├── if.c ├── if.h ├── ip.h ├── ip_icmp.c ├── ip_icmp.h ├── ip_input.c ├── ip_output.c ├── libslirp.h ├── main.h ├── mbuf.c ├── mbuf.h ├── misc.c ├── misc.h ├── sbuf.c ├── sbuf.h ├── slirp.c ├── slirp.h ├── slirp_config.h ├── socket.c ├── socket.h ├── tcp.h ├── tcp_input.c ├── tcp_output.c ├── tcp_subr.c ├── tcp_timer.c ├── tcp_timer.h ├── tcp_var.h ├── tcpip.h ├── tftp.h ├── udp.c └── udp.h ├── softfp.c ├── softfp.h ├── softfp_template.h ├── softfp_template_icvt.h ├── splitimg.c ├── temu.c ├── vga.c ├── virtio.c ├── virtio.h ├── vmmouse.c ├── x86_cpu.c ├── x86_cpu.h └── x86_machine.c /Changelog: -------------------------------------------------------------------------------- 1 | 2019-12-21: 2 | 3 | - added complete JSLinux demo 4 | - RISC-V: added initrd support 5 | - RISC-V: fixed FMIN/FMAX instructions 6 | 7 | 2018-09-23: 8 | 9 | - added support for separate RISC-V BIOS and kernel 10 | 11 | 2018-09-15: 12 | 13 | - renamed to TinyEMU (temu) 14 | - single executable for all emulated machines 15 | 16 | 2018-08-29: 17 | 18 | - compilation fixes 19 | 20 | 2017-08-06: 21 | 22 | - added JSON configuration file 23 | - added graphical display with SDL 24 | - added VirtIO input support 25 | - added PCI bus and VirtIO PCI support 26 | - x86: added IDE, PS/2, vmmouse and VGA devices 27 | - added user mode network interface 28 | 29 | 2017-06-10: 30 | 31 | - RISCV: avoid unnecessary kernel patches 32 | - x86: accept standard kernel images 33 | 34 | 2017-05-25: 35 | 36 | - RISCV: faster emulation (1.4x) 37 | - Support of user level ISA version 2.2 and priviledged architecture 38 | version 1.10 39 | - added small x86 emulator (x86emu) based on KVM 40 | - modified the fs_net network protocol to match the vfsync protocol 41 | - handle console resize 42 | - JS emulator: 43 | - added scrollbar in terminal 44 | - added file import and export 45 | - added copy/paste support 46 | -------------------------------------------------------------------------------- /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016-2017 Fabrice Bellard 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # TinyEMU 3 | # 4 | # Copyright (c) 2016-2018 Fabrice Bellard 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | # THE SOFTWARE. 23 | # 24 | 25 | # if set, network filesystem is enabled. libcurl and libcrypto 26 | # (openssl) must be installed. 27 | CONFIG_FS_NET=y 28 | # SDL support (optional) 29 | CONFIG_SDL=y 30 | # if set, compile the 128 bit emulator. Note: the 128 bit target does 31 | # not compile if gcc does not support the int128 type (32 bit hosts). 32 | CONFIG_INT128=y 33 | # build x86 emulator 34 | CONFIG_X86EMU=y 35 | # win32 build (not usable yet) 36 | #CONFIG_WIN32=y 37 | # user space network redirector 38 | CONFIG_SLIRP=y 39 | 40 | ifdef CONFIG_WIN32 41 | CROSS_PREFIX=i686-w64-mingw32- 42 | EXE=.exe 43 | else 44 | CROSS_PREFIX= 45 | EXE= 46 | endif 47 | CC=$(CROSS_PREFIX)gcc 48 | STRIP=$(CROSS_PREFIX)strip 49 | CFLAGS=-O2 -Wall -g -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -MMD 50 | CFLAGS+=-D_GNU_SOURCE -DCONFIG_VERSION=\"$(shell cat VERSION)\" 51 | LDFLAGS= 52 | 53 | bindir=/usr/local/bin 54 | INSTALL=install 55 | 56 | PROGS+= temu$(EXE) 57 | ifndef CONFIG_WIN32 58 | ifdef CONFIG_FS_NET 59 | PROGS+=build_filelist splitimg 60 | endif 61 | endif 62 | 63 | all: $(PROGS) 64 | 65 | EMU_OBJS:=virtio.o pci.o fs.o cutils.o iomem.o simplefb.o \ 66 | json.o machine.o temu.o 67 | 68 | ifdef CONFIG_SLIRP 69 | CFLAGS+=-DCONFIG_SLIRP 70 | EMU_OBJS+=$(addprefix slirp/, bootp.o ip_icmp.o mbuf.o slirp.o tcp_output.o cksum.o ip_input.o misc.o socket.o tcp_subr.o udp.o if.o ip_output.o sbuf.o tcp_input.o tcp_timer.o) 71 | endif 72 | 73 | ifndef CONFIG_WIN32 74 | EMU_OBJS+=fs_disk.o 75 | EMU_LIBS=-lrt 76 | endif 77 | ifdef CONFIG_FS_NET 78 | CFLAGS+=-DCONFIG_FS_NET 79 | EMU_OBJS+=fs_net.o fs_wget.o fs_utils.o block_net.o 80 | EMU_LIBS+=-lcurl -lcrypto 81 | ifdef CONFIG_WIN32 82 | EMU_LIBS+=-lwsock32 83 | endif # CONFIG_WIN32 84 | endif # CONFIG_FS_NET 85 | ifdef CONFIG_SDL 86 | EMU_LIBS+=-lSDL 87 | EMU_OBJS+=sdl.o 88 | CFLAGS+=-DCONFIG_SDL 89 | ifdef CONFIG_WIN32 90 | LDFLAGS+=-mwindows 91 | endif 92 | endif 93 | 94 | EMU_OBJS+=riscv_machine.o softfp.o riscv_cpu32.o riscv_cpu64.o 95 | ifdef CONFIG_INT128 96 | CFLAGS+=-DCONFIG_RISCV_MAX_XLEN=128 97 | EMU_OBJS+=riscv_cpu128.o 98 | else 99 | CFLAGS+=-DCONFIG_RISCV_MAX_XLEN=64 100 | endif 101 | ifdef CONFIG_X86EMU 102 | CFLAGS+=-DCONFIG_X86EMU 103 | EMU_OBJS+=x86_cpu.o x86_machine.o ide.o ps2.o vmmouse.o pckbd.o vga.o 104 | endif 105 | 106 | temu$(EXE): $(EMU_OBJS) 107 | $(CC) $(LDFLAGS) -o $@ $^ $(EMU_LIBS) 108 | 109 | riscv_cpu32.o: riscv_cpu.c 110 | $(CC) $(CFLAGS) -DMAX_XLEN=32 -c -o $@ $< 111 | 112 | riscv_cpu64.o: riscv_cpu.c 113 | $(CC) $(CFLAGS) -DMAX_XLEN=64 -c -o $@ $< 114 | 115 | riscv_cpu128.o: riscv_cpu.c 116 | $(CC) $(CFLAGS) -DMAX_XLEN=128 -c -o $@ $< 117 | 118 | build_filelist: build_filelist.o fs_utils.o cutils.o 119 | $(CC) $(LDFLAGS) -o $@ $^ -lm 120 | 121 | splitimg: splitimg.o 122 | $(CC) $(LDFLAGS) -o $@ $^ 123 | 124 | install: $(PROGS) 125 | $(STRIP) $(PROGS) 126 | $(INSTALL) -m755 $(PROGS) "$(DESTDIR)$(bindir)" 127 | 128 | %.o: %.c 129 | $(CC) $(CFLAGS) -c -o $@ $< 130 | 131 | clean: 132 | rm -f *.o *.d *~ $(PROGS) slirp/*.o slirp/*.d slirp/*~ 133 | 134 | -include $(wildcard *.d) 135 | -include $(wildcard slirp/*.d) 136 | -------------------------------------------------------------------------------- /Makefile.js: -------------------------------------------------------------------------------- 1 | # 2 | # TinyEMU emulator 3 | # 4 | # Copyright (c) 2016-2018 Fabrice Bellard 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in 14 | # all copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | # THE SOFTWARE. 23 | # 24 | 25 | # Build the Javascript version of TinyEMU 26 | EMCC=emcc 27 | EMCFLAGS=-O2 --llvm-opts 2 -Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -MMD -fno-strict-aliasing -DCONFIG_FS_NET 28 | #EMCFLAGS+=-Werror 29 | EMLDFLAGS=-O3 --memory-init-file 0 --closure 0 -s NO_EXIT_RUNTIME=1 -s NO_FILESYSTEM=1 -s "EXPORTED_FUNCTIONS=['_console_queue_char','_vm_start','_fs_import_file','_display_key_event','_display_mouse_event','_display_wheel_event','_net_write_packet','_net_set_carrier']" -s 'EXTRA_EXPORTED_RUNTIME_METHODS=["ccall", "cwrap"]' -s BINARYEN_TRAP_MODE=clamp --js-library js/lib.js 30 | EMLDFLAGS_ASMJS:=$(EMLDFLAGS) -s WASM=0 31 | EMLDFLAGS_WASM:=$(EMLDFLAGS) -s WASM=1 -s TOTAL_MEMORY=67108864 -s ALLOW_MEMORY_GROWTH=1 32 | 33 | PROGS=js/riscvemu32.js js/riscvemu32-wasm.js js/riscvemu64.js js/riscvemu64-wasm.js 34 | 35 | all: $(PROGS) 36 | 37 | JS_OBJS=jsemu.js.o softfp.js.o virtio.js.o fs.js.o fs_net.js.o fs_wget.js.o fs_utils.js.o simplefb.js.o pci.js.o json.js.o block_net.js.o 38 | JS_OBJS+=iomem.js.o cutils.js.o aes.js.o sha256.js.o 39 | 40 | RISCVEMU64_OBJS=$(JS_OBJS) riscv_cpu64.js.o riscv_machine.js.o machine.js.o 41 | RISCVEMU32_OBJS=$(JS_OBJS) riscv_cpu32.js.o riscv_machine.js.o machine.js.o 42 | 43 | js/riscvemu64.js: $(RISCVEMU64_OBJS) js/lib.js 44 | $(EMCC) $(EMLDFLAGS_ASMJS) -o $@ $(RISCVEMU64_OBJS) 45 | 46 | js/riscvemu32.js: $(RISCVEMU32_OBJS) js/lib.js 47 | $(EMCC) $(EMLDFLAGS_ASMJS) -o $@ $(RISCVEMU32_OBJS) 48 | 49 | js/riscvemu64-wasm.js: $(RISCVEMU64_OBJS) js/lib.js 50 | $(EMCC) $(EMLDFLAGS_WASM) -o $@ $(RISCVEMU64_OBJS) 51 | 52 | js/riscvemu32-wasm.js: $(RISCVEMU32_OBJS) js/lib.js 53 | $(EMCC) $(EMLDFLAGS_WASM) -o $@ $(RISCVEMU32_OBJS) 54 | 55 | riscv_cpu32.js.o: riscv_cpu.c 56 | $(EMCC) $(EMCFLAGS) -DMAX_XLEN=32 -DCONFIG_RISCV_MAX_XLEN=32 -c -o $@ $< 57 | 58 | riscv_cpu64.js.o: riscv_cpu.c 59 | $(EMCC) $(EMCFLAGS) -DMAX_XLEN=64 -DCONFIG_RISCV_MAX_XLEN=64 -c -o $@ $< 60 | 61 | 62 | %.js.o: %.c 63 | $(EMCC) $(EMCFLAGS) -c -o $@ $< 64 | 65 | -include $(wildcard *.d) 66 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 2019-12-21 2 | -------------------------------------------------------------------------------- /aes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OpenSSL compatible AES header 3 | * 4 | * Copyright (c) 2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef AES_H 25 | #define AES_H 26 | 27 | #define AES_MAXNR 14 28 | #define AES_BLOCK_SIZE 16 29 | 30 | struct aes_key_st { 31 | uint32_t rd_key[4 *(AES_MAXNR + 1)]; 32 | int rounds; 33 | }; 34 | typedef struct aes_key_st AES_KEY; 35 | 36 | int AES_set_encrypt_key(const unsigned char *userKey, const int bits, 37 | AES_KEY *key); 38 | int AES_set_decrypt_key(const unsigned char *userKey, const int bits, 39 | AES_KEY *key); 40 | 41 | void AES_encrypt(const unsigned char *in, unsigned char *out, 42 | const AES_KEY *key); 43 | void AES_decrypt(const unsigned char *in, unsigned char *out, 44 | const AES_KEY *key); 45 | void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, 46 | const unsigned long length, const AES_KEY *key, 47 | unsigned char *ivec, const int enc); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /cutils.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Misc C utilities 3 | * 4 | * Copyright (c) 2016-2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "cutils.h" 34 | 35 | void *mallocz(size_t size) 36 | { 37 | void *ptr; 38 | ptr = malloc(size); 39 | if (!ptr) 40 | return NULL; 41 | memset(ptr, 0, size); 42 | return ptr; 43 | } 44 | 45 | void pstrcpy(char *buf, int buf_size, const char *str) 46 | { 47 | int c; 48 | char *q = buf; 49 | 50 | if (buf_size <= 0) 51 | return; 52 | 53 | for(;;) { 54 | c = *str++; 55 | if (c == 0 || q >= buf + buf_size - 1) 56 | break; 57 | *q++ = c; 58 | } 59 | *q = '\0'; 60 | } 61 | 62 | char *pstrcat(char *buf, int buf_size, const char *s) 63 | { 64 | int len; 65 | len = strlen(buf); 66 | if (len < buf_size) 67 | pstrcpy(buf + len, buf_size - len, s); 68 | return buf; 69 | } 70 | 71 | int strstart(const char *str, const char *val, const char **ptr) 72 | { 73 | const char *p, *q; 74 | p = str; 75 | q = val; 76 | while (*q != '\0') { 77 | if (*p != *q) 78 | return 0; 79 | p++; 80 | q++; 81 | } 82 | if (ptr) 83 | *ptr = p; 84 | return 1; 85 | } 86 | 87 | void dbuf_init(DynBuf *s) 88 | { 89 | memset(s, 0, sizeof(*s)); 90 | } 91 | 92 | void dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len) 93 | { 94 | size_t end, new_size; 95 | new_size = end = offset + len; 96 | if (new_size > s->allocated_size) { 97 | new_size = max_int(new_size, s->allocated_size * 3 / 2); 98 | s->buf = realloc(s->buf, new_size); 99 | s->allocated_size = new_size; 100 | } 101 | memcpy(s->buf + offset, data, len); 102 | if (end > s->size) 103 | s->size = end; 104 | } 105 | 106 | void dbuf_putc(DynBuf *s, uint8_t c) 107 | { 108 | dbuf_write(s, s->size, &c, 1); 109 | } 110 | 111 | void dbuf_putstr(DynBuf *s, const char *str) 112 | { 113 | dbuf_write(s, s->size, (const uint8_t *)str, strlen(str)); 114 | } 115 | 116 | void dbuf_free(DynBuf *s) 117 | { 118 | free(s->buf); 119 | memset(s, 0, sizeof(*s)); 120 | } 121 | -------------------------------------------------------------------------------- /cutils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * C utilities 3 | * 4 | * Copyright (c) 2016 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef CUTILS_H 25 | #define CUTILS_H 26 | 27 | #include 28 | 29 | #define likely(x) __builtin_expect(!!(x), 1) 30 | #define unlikely(x) __builtin_expect(!!(x), 0) 31 | #define force_inline inline __attribute__((always_inline)) 32 | #define no_inline __attribute__((noinline)) 33 | #define __maybe_unused __attribute__((unused)) 34 | 35 | #define xglue(x, y) x ## y 36 | #define glue(x, y) xglue(x, y) 37 | #define stringify(s) tostring(s) 38 | #define tostring(s) #s 39 | 40 | #ifndef offsetof 41 | #define offsetof(type, field) ((size_t) &((type *)0)->field) 42 | #endif 43 | #define countof(x) (sizeof(x) / sizeof(x[0])) 44 | 45 | #define DLL_PUBLIC __attribute__ ((visibility ("default"))) 46 | 47 | #ifndef _BOOL_defined 48 | #define _BOOL_defined 49 | #undef FALSE 50 | #undef TRUE 51 | 52 | typedef int BOOL; 53 | enum { 54 | FALSE = 0, 55 | TRUE = 1, 56 | }; 57 | #endif 58 | 59 | /* this test works at least with gcc */ 60 | #if defined(__SIZEOF_INT128__) 61 | #define HAVE_INT128 62 | #endif 63 | 64 | #ifdef HAVE_INT128 65 | typedef __int128 int128_t; 66 | typedef unsigned __int128 uint128_t; 67 | #endif 68 | 69 | static inline int max_int(int a, int b) 70 | { 71 | if (a > b) 72 | return a; 73 | else 74 | return b; 75 | } 76 | 77 | static inline int min_int(int a, int b) 78 | { 79 | if (a < b) 80 | return a; 81 | else 82 | return b; 83 | } 84 | 85 | void *mallocz(size_t size); 86 | 87 | #if defined(_WIN32) 88 | static inline uint32_t bswap_32(uint32_t v) 89 | { 90 | return ((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >> 8) | 91 | ((v & 0x0000ff00) << 8) | ((v & 0x000000ff) << 24); 92 | } 93 | #else 94 | #include 95 | #endif 96 | 97 | static inline uint16_t get_le16(const uint8_t *ptr) 98 | { 99 | return ptr[0] | (ptr[1] << 8); 100 | } 101 | 102 | static inline uint32_t get_le32(const uint8_t *ptr) 103 | { 104 | return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24); 105 | } 106 | 107 | static inline uint64_t get_le64(const uint8_t *ptr) 108 | { 109 | return get_le32(ptr) | ((uint64_t)get_le32(ptr + 4) << 32); 110 | } 111 | 112 | static inline void put_le16(uint8_t *ptr, uint16_t v) 113 | { 114 | ptr[0] = v; 115 | ptr[1] = v >> 8; 116 | } 117 | 118 | static inline void put_le32(uint8_t *ptr, uint32_t v) 119 | { 120 | ptr[0] = v; 121 | ptr[1] = v >> 8; 122 | ptr[2] = v >> 16; 123 | ptr[3] = v >> 24; 124 | } 125 | 126 | static inline void put_le64(uint8_t *ptr, uint64_t v) 127 | { 128 | put_le32(ptr, v); 129 | put_le32(ptr + 4, v >> 32); 130 | } 131 | 132 | static inline uint32_t get_be32(const uint8_t *d) 133 | { 134 | return (d[0] << 24) | (d[1] << 16) | (d[2] << 8) | d[3]; 135 | } 136 | 137 | static inline void put_be32(uint8_t *d, uint32_t v) 138 | { 139 | d[0] = v >> 24; 140 | d[1] = v >> 16; 141 | d[2] = v >> 8; 142 | d[3] = v >> 0; 143 | } 144 | 145 | static inline void put_be64(uint8_t *d, uint64_t v) 146 | { 147 | put_be32(d, v >> 32); 148 | put_be32(d + 4, v); 149 | } 150 | 151 | #ifdef WORDS_BIGENDIAN 152 | static inline uint32_t cpu_to_be32(uint32_t v) 153 | { 154 | return v; 155 | } 156 | #else 157 | static inline uint32_t cpu_to_be32(uint32_t v) 158 | { 159 | return bswap_32(v); 160 | } 161 | #endif 162 | 163 | /* XXX: optimize */ 164 | static inline int ctz32(uint32_t a) 165 | { 166 | int i; 167 | if (a == 0) 168 | return 32; 169 | for(i = 0; i < 32; i++) { 170 | if ((a >> i) & 1) 171 | return i; 172 | } 173 | return 32; 174 | } 175 | 176 | 177 | void *mallocz(size_t size); 178 | void pstrcpy(char *buf, int buf_size, const char *str); 179 | char *pstrcat(char *buf, int buf_size, const char *s); 180 | int strstart(const char *str, const char *val, const char **ptr); 181 | 182 | typedef struct { 183 | uint8_t *buf; 184 | size_t size; 185 | size_t allocated_size; 186 | } DynBuf; 187 | 188 | void dbuf_init(DynBuf *s); 189 | void dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len); 190 | void dbuf_putc(DynBuf *s, uint8_t c); 191 | void dbuf_putstr(DynBuf *s, const char *str); 192 | void dbuf_free(DynBuf *s); 193 | 194 | #endif /* CUTILS_H */ 195 | -------------------------------------------------------------------------------- /fbuf.h: -------------------------------------------------------------------------------- 1 | #ifndef FBUF_H 2 | #define FBUF_H 3 | 4 | typedef struct { 5 | #if defined(EMSCRIPTEN) 6 | int handle; 7 | #else 8 | uint8_t *data; 9 | #endif 10 | size_t allocated_size; 11 | } FileBuffer; 12 | 13 | void file_buffer_init(FileBuffer *bs); 14 | void file_buffer_reset(FileBuffer *bs); 15 | int file_buffer_resize(FileBuffer *bs, size_t new_size); 16 | void file_buffer_write(FileBuffer *bs, size_t offset, const uint8_t *buf, 17 | size_t size); 18 | void file_buffer_set(FileBuffer *bs, size_t offset, int val, size_t size); 19 | void file_buffer_read(FileBuffer *bs, size_t offset, uint8_t *buf, 20 | size_t size); 21 | 22 | #endif /* FBUF_H */ 23 | -------------------------------------------------------------------------------- /fs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesystem utilities 3 | * 4 | * Copyright (c) 2016 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "cutils.h" 32 | #include "fs.h" 33 | 34 | FSFile *fs_dup(FSDevice *fs, FSFile *f) 35 | { 36 | FSQID qid; 37 | fs->fs_walk(fs, &f, &qid, f, 0, NULL); 38 | return f; 39 | } 40 | 41 | FSFile *fs_walk_path1(FSDevice *fs, FSFile *f, const char *path, 42 | char **pname) 43 | { 44 | const char *p; 45 | char *name; 46 | FSFile *f1; 47 | FSQID qid; 48 | int len, ret; 49 | BOOL is_last, is_first; 50 | 51 | if (path[0] == '/') 52 | path++; 53 | 54 | is_first = TRUE; 55 | for(;;) { 56 | p = strchr(path, '/'); 57 | if (!p) { 58 | name = (char *)path; 59 | if (pname) { 60 | *pname = name; 61 | if (is_first) { 62 | ret = fs->fs_walk(fs, &f, &qid, f, 0, NULL); 63 | if (ret < 0) 64 | f = NULL; 65 | } 66 | return f; 67 | } 68 | is_last = TRUE; 69 | } else { 70 | len = p - path; 71 | name = malloc(len + 1); 72 | memcpy(name, path, len); 73 | name[len] = '\0'; 74 | is_last = FALSE; 75 | } 76 | ret = fs->fs_walk(fs, &f1, &qid, f, 1, &name); 77 | if (!is_last) 78 | free(name); 79 | if (!is_first) 80 | fs->fs_delete(fs, f); 81 | f = f1; 82 | is_first = FALSE; 83 | if (ret <= 0) { 84 | fs->fs_delete(fs, f); 85 | f = NULL; 86 | break; 87 | } else if (is_last) { 88 | break; 89 | } 90 | path = p + 1; 91 | } 92 | return f; 93 | } 94 | 95 | FSFile *fs_walk_path(FSDevice *fs, FSFile *f, const char *path) 96 | { 97 | return fs_walk_path1(fs, f, path, NULL); 98 | } 99 | 100 | void fs_end(FSDevice *fs) 101 | { 102 | fs->fs_end(fs); 103 | free(fs); 104 | } 105 | -------------------------------------------------------------------------------- /fs_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Misc FS utilities 3 | * 4 | * Copyright (c) 2016-2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #define HEAD_FILENAME "head" 25 | #define ROOT_FILENAME "files" 26 | 27 | #define FILEID_SIZE_MAX 32 28 | 29 | #define FS_KEY_LEN 16 30 | 31 | /* default block size to determine the total filesytem size */ 32 | #define FS_BLOCK_SIZE_LOG2 12 33 | #define FS_BLOCK_SIZE (1 << FS_BLOCK_SIZE_LOG2) 34 | 35 | typedef enum { 36 | FS_ERR_OK = 0, 37 | FS_ERR_GENERIC = -1, 38 | FS_ERR_SYNTAX = -2, 39 | FS_ERR_REVISION = -3, 40 | FS_ERR_FILE_ID = -4, 41 | FS_ERR_IO = -5, 42 | FS_ERR_NOENT = -6, 43 | FS_ERR_COUNTERS = -7, 44 | FS_ERR_QUOTA = -8, 45 | FS_ERR_PROTOCOL_VERSION = -9, 46 | FS_ERR_HEAD = -10, 47 | } FSCommitErrorCode; 48 | 49 | typedef uint64_t FSFileID; 50 | 51 | static inline BOOL isspace_nolf(int c) 52 | { 53 | return (c == ' ' || c == '\t'); 54 | } 55 | 56 | static inline int from_hex(int c) 57 | { 58 | if (c >= '0' && c <= '9') 59 | return c - '0'; 60 | else if (c >= 'A' && c <= 'F') 61 | return c - 'A' + 10; 62 | else if (c >= 'a' && c <= 'f') 63 | return c - 'a' + 10; 64 | else 65 | return -1; 66 | } 67 | 68 | static inline uint64_t block_align(uint64_t val, uint64_t align) 69 | { 70 | return (val + align - 1) & ~(align - 1); 71 | } 72 | 73 | void pstrcpy(char *buf, int buf_size, const char *str); 74 | char *pstrcat(char *buf, int buf_size, const char *s); 75 | char *compose_path(const char *path, const char *name); 76 | char *compose_url(const char *base_url, const char *name); 77 | void skip_line(const char **pp); 78 | char *quoted_str(const char *str); 79 | int parse_fname(char *buf, int buf_size, const char **pp); 80 | int parse_uint32_base(uint32_t *pval, const char **pp, int base); 81 | int parse_uint64_base(uint64_t *pval, const char **pp, int base); 82 | int parse_uint64(uint64_t *pval, const char **pp); 83 | int parse_uint32(uint32_t *pval, const char **pp); 84 | int parse_time(uint32_t *psec, uint32_t *pnsec, const char **pp); 85 | int parse_file_id(FSFileID *pval, const char **pp); 86 | char *file_id_to_filename(char *buf, FSFileID file_id); 87 | void encode_hex(char *str, const uint8_t *buf, int len); 88 | int decode_hex(uint8_t *buf, const char *str, int len); 89 | BOOL is_url(const char *path); 90 | 91 | const char *skip_header(const char *p); 92 | int parse_tag(char *buf, int buf_size, const char *str, const char *tag); 93 | int parse_tag_uint64(uint64_t *pval, const char *str, const char *tag); 94 | int parse_tag_file_id(FSFileID *pval, const char *str, const char *tag); 95 | int parse_tag_version(const char *str); 96 | -------------------------------------------------------------------------------- /fs_wget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HTTP file download 3 | * 4 | * Copyright (c) 2016-2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #if defined(EMSCRIPTEN) 25 | #define USE_BUILTIN_CRYPTO 26 | #endif 27 | 28 | #ifdef USE_BUILTIN_CRYPTO 29 | #include "aes.h" 30 | #include "sha256.h" 31 | #else 32 | #include 33 | #include 34 | #include 35 | #endif 36 | #ifdef _WIN32 37 | #include 38 | #endif 39 | 40 | #define LOG() printf("%s:%d\n", __func__, __LINE__) 41 | 42 | /* XHR */ 43 | 44 | /* err < 0: error (no data provided) 45 | err = 0: end of transfer (data can be provided too) 46 | err = 1: data chunk 47 | */ 48 | typedef void WGetWriteCallback(void *opaque, int err, void *data, size_t size); 49 | typedef size_t WGetReadCallback(void *opaque, void *data, size_t size); 50 | typedef struct XHRState XHRState; 51 | 52 | XHRState *fs_wget(const char *url, const char *user, const char *password, 53 | void *opaque, WGetWriteCallback *cb, BOOL single_write); 54 | void fs_wget_free(XHRState *s); 55 | 56 | void fs_wget_init(void); 57 | void fs_wget_end(void); 58 | 59 | #ifndef EMSCRIPTEN 60 | typedef BOOL FSNetEventLoopCompletionFunc(void *opaque); 61 | void fs_net_set_fdset(int *pfd_max, fd_set *rfds, fd_set *wfds, fd_set *efds, 62 | int *ptimeout); 63 | void fs_net_event_loop(FSNetEventLoopCompletionFunc *cb, void *opaque); 64 | #endif 65 | 66 | /* crypto */ 67 | 68 | extern const uint8_t encrypted_file_magic[4]; 69 | 70 | typedef int DecryptFileCB(void *opaque, const uint8_t *data, size_t len); 71 | typedef struct DecryptFileState DecryptFileState; 72 | 73 | DecryptFileState *decrypt_file_init(AES_KEY *aes_state, 74 | DecryptFileCB *write_cb, 75 | void *opaque); 76 | int decrypt_file(DecryptFileState *s, const uint8_t *data, 77 | size_t size); 78 | int decrypt_file_flush(DecryptFileState *s); 79 | void decrypt_file_end(DecryptFileState *s); 80 | 81 | void pbkdf2_hmac_sha256(const uint8_t *pwd, int pwd_len, 82 | const uint8_t *salt, int salt_len, 83 | int iter, int key_len, uint8_t *out); 84 | 85 | /* XHR file */ 86 | 87 | typedef void FSWGetFileCB(FSDevice *fs, FSFile *f, int64_t size, void *opaque); 88 | 89 | void fs_wget_file2(FSDevice *fs, FSFile *f, const char *url, 90 | const char *user, const char *password, 91 | FSFile *posted_file, uint64_t post_data_len, 92 | FSWGetFileCB *cb, void *opaque, 93 | AES_KEY *aes_state); 94 | -------------------------------------------------------------------------------- /ide.h: -------------------------------------------------------------------------------- 1 | /* 2 | * IDE emulation 3 | * 4 | * Copyright (c) 2003-2016 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include "virtio.h" 25 | #include "iomem.h" 26 | #include "pci.h" 27 | 28 | typedef struct IDEIFState IDEIFState; 29 | 30 | IDEIFState *ide_init(PhysMemoryMap *port_map, uint32_t addr, uint32_t addr2, 31 | IRQSignal *irq, BlockDevice **tab_bs); 32 | PCIDevice *piix3_ide_init(PCIBus *pci_bus, int devfn); 33 | -------------------------------------------------------------------------------- /iomem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * IO memory handling 3 | * 4 | * Copyright (c) 2016-2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef IOMEM_H 25 | #define IOMEM_H 26 | 27 | typedef void DeviceWriteFunc(void *opaque, uint32_t offset, 28 | uint32_t val, int size_log2); 29 | typedef uint32_t DeviceReadFunc(void *opaque, uint32_t offset, int size_log2); 30 | 31 | #define DEVIO_SIZE8 (1 << 0) 32 | #define DEVIO_SIZE16 (1 << 1) 33 | #define DEVIO_SIZE32 (1 << 2) 34 | /* not supported, could add specific 64 bit callbacks when needed */ 35 | //#define DEVIO_SIZE64 (1 << 3) 36 | #define DEVIO_DISABLED (1 << 4) 37 | 38 | #define DEVRAM_FLAG_ROM (1 << 0) /* not writable */ 39 | #define DEVRAM_FLAG_DIRTY_BITS (1 << 1) /* maintain dirty bits */ 40 | #define DEVRAM_FLAG_DISABLED (1 << 2) /* allocated but not mapped */ 41 | #define DEVRAM_PAGE_SIZE_LOG2 12 42 | #define DEVRAM_PAGE_SIZE (1 << DEVRAM_PAGE_SIZE_LOG2) 43 | 44 | typedef struct PhysMemoryMap PhysMemoryMap; 45 | 46 | typedef struct { 47 | PhysMemoryMap *map; 48 | uint64_t addr; 49 | uint64_t org_size; /* original size */ 50 | uint64_t size; /* =org_size or 0 if the mapping is disabled */ 51 | BOOL is_ram; 52 | /* the following is used for RAM access */ 53 | int devram_flags; 54 | uint8_t *phys_mem; 55 | int dirty_bits_size; /* in bytes */ 56 | uint32_t *dirty_bits; /* NULL if not used */ 57 | uint32_t *dirty_bits_tab[2]; 58 | int dirty_bits_index; /* 0-1 */ 59 | /* the following is used for I/O access */ 60 | void *opaque; 61 | DeviceReadFunc *read_func; 62 | DeviceWriteFunc *write_func; 63 | int devio_flags; 64 | } PhysMemoryRange; 65 | 66 | #define PHYS_MEM_RANGE_MAX 32 67 | 68 | struct PhysMemoryMap { 69 | int n_phys_mem_range; 70 | PhysMemoryRange phys_mem_range[PHYS_MEM_RANGE_MAX]; 71 | PhysMemoryRange *(*register_ram)(PhysMemoryMap *s, uint64_t addr, 72 | uint64_t size, int devram_flags); 73 | void (*free_ram)(PhysMemoryMap *s, PhysMemoryRange *pr); 74 | const uint32_t *(*get_dirty_bits)(PhysMemoryMap *s, PhysMemoryRange *pr); 75 | void (*set_ram_addr)(PhysMemoryMap *s, PhysMemoryRange *pr, uint64_t addr, 76 | BOOL enabled); 77 | void *opaque; 78 | void (*flush_tlb_write_range)(void *opaque, uint8_t *ram_addr, 79 | size_t ram_size); 80 | }; 81 | 82 | 83 | PhysMemoryMap *phys_mem_map_init(void); 84 | void phys_mem_map_end(PhysMemoryMap *s); 85 | PhysMemoryRange *register_ram_entry(PhysMemoryMap *s, uint64_t addr, 86 | uint64_t size, int devram_flags); 87 | static inline PhysMemoryRange *cpu_register_ram(PhysMemoryMap *s, uint64_t addr, 88 | uint64_t size, int devram_flags) 89 | { 90 | return s->register_ram(s, addr, size, devram_flags); 91 | } 92 | PhysMemoryRange *cpu_register_device(PhysMemoryMap *s, uint64_t addr, 93 | uint64_t size, void *opaque, 94 | DeviceReadFunc *read_func, DeviceWriteFunc *write_func, 95 | int devio_flags); 96 | PhysMemoryRange *get_phys_mem_range(PhysMemoryMap *s, uint64_t paddr); 97 | void phys_mem_set_addr(PhysMemoryRange *pr, uint64_t addr, BOOL enabled); 98 | 99 | static inline const uint32_t *phys_mem_get_dirty_bits(PhysMemoryRange *pr) 100 | { 101 | PhysMemoryMap *map = pr->map; 102 | return map->get_dirty_bits(map, pr); 103 | } 104 | 105 | static inline void phys_mem_set_dirty_bit(PhysMemoryRange *pr, size_t offset) 106 | { 107 | size_t page_index; 108 | uint32_t mask, *dirty_bits_ptr; 109 | if (pr->dirty_bits) { 110 | page_index = offset >> DEVRAM_PAGE_SIZE_LOG2; 111 | mask = 1 << (page_index & 0x1f); 112 | dirty_bits_ptr = pr->dirty_bits + (page_index >> 5); 113 | *dirty_bits_ptr |= mask; 114 | } 115 | } 116 | 117 | static inline BOOL phys_mem_is_dirty_bit(PhysMemoryRange *pr, size_t offset) 118 | { 119 | size_t page_index; 120 | uint32_t *dirty_bits_ptr; 121 | if (!pr->dirty_bits) 122 | return TRUE; 123 | page_index = offset >> DEVRAM_PAGE_SIZE_LOG2; 124 | dirty_bits_ptr = pr->dirty_bits + (page_index >> 5); 125 | return (*dirty_bits_ptr >> (page_index & 0x1f)) & 1; 126 | } 127 | 128 | void phys_mem_reset_dirty_bit(PhysMemoryRange *pr, size_t offset); 129 | uint8_t *phys_mem_get_ram_ptr(PhysMemoryMap *map, uint64_t paddr, BOOL is_rw); 130 | 131 | /* IRQ support */ 132 | 133 | typedef void SetIRQFunc(void *opaque, int irq_num, int level); 134 | 135 | typedef struct { 136 | SetIRQFunc *set_irq; 137 | void *opaque; 138 | int irq_num; 139 | } IRQSignal; 140 | 141 | void irq_init(IRQSignal *irq, SetIRQFunc *set_irq, void *opaque, int irq_num); 142 | 143 | static inline void set_irq(IRQSignal *irq, int level) 144 | { 145 | irq->set_irq(irq->opaque, irq->irq_num, level); 146 | } 147 | 148 | #endif /* IOMEM_H */ 149 | -------------------------------------------------------------------------------- /jslinux-2019-12-21/bbl64.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/bbl64.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/images/bg-scrollbar-thumb-y.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/images/bg-scrollbar-thumb-y.png -------------------------------------------------------------------------------- /jslinux-2019-12-21/images/bg-scrollbar-track-y.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/images/bg-scrollbar-track-y.png -------------------------------------------------------------------------------- /jslinux-2019-12-21/images/bg-scrollbar-trackend-y.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/images/bg-scrollbar-trackend-y.png -------------------------------------------------------------------------------- /jslinux-2019-12-21/images/upload-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/images/upload-icon.png -------------------------------------------------------------------------------- /jslinux-2019-12-21/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSLinux 6 | 7 | 9 | 10 | 11 |
12 |
13 |
14 |
15 | 16 | 19 | 20 | 21 |
22 |
23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /jslinux-2019-12-21/kernel-riscv64.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/kernel-riscv64.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/kernel-x86.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/kernel-x86.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/readme.txt: -------------------------------------------------------------------------------- 1 | JSLinux demo 2 | ============ 3 | 4 | You must copy all the files to a directory on a web server in order to 5 | run the demo (it is needed so that the XML HTTP Requests work 6 | correctly). Assuming it is installed in http://localhost/jslinux, 7 | explore in a browser: 8 | 9 | http://localhost/jslinux 10 | 11 | A minimal busybox distribution for RISCV-64 and x86 is provided. The 12 | RISCV-64 version is executed by default. To run the x86 version, 13 | explore: 14 | 15 | http://localhost/jslinux?cpu=x86 16 | 17 | The source jslinux.js can be modified to change the default 18 | configuration. 19 | 20 | More complete Linux distributions (such as buildroot) can be used 21 | provided you keep using the same precompiled Linux kernels. The 22 | TinyEMU 'splitimg' tool must be used to convert a diskimage to a list 23 | of files. For example: 24 | 25 | splitimg root-riscv64.bin root-riscv64 256 26 | 27 | The demo VM configurations are in root-riscv64.cfg and root-x86.cfg. 28 | -------------------------------------------------------------------------------- /jslinux-2019-12-21/riscvemu32-wasm.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/riscvemu32-wasm.wasm -------------------------------------------------------------------------------- /jslinux-2019-12-21/riscvemu64-wasm.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/riscvemu64-wasm.wasm -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-riscv64.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64.cfg: -------------------------------------------------------------------------------- 1 | /* VM configuration file */ 2 | { 3 | version: 1, 4 | machine: "riscv64", 5 | memory_size: 128, 6 | bios: "bbl64.bin", 7 | kernel: "kernel-riscv64.bin", 8 | cmdline: "console=hvc0 root=/dev/vda rw", 9 | drive0: { file: "root-riscv64/blk.txt" }, 10 | eth0: { driver: "user" }, 11 | } 12 | -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64/blk.txt: -------------------------------------------------------------------------------- 1 | { 2 | block_size: 256, 3 | n_block: 16, 4 | } 5 | -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64/blk000000000.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-riscv64/blk000000000.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64/blk000000001.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-riscv64/blk000000001.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64/blk000000002.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-riscv64/blk000000002.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64/blk000000003.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-riscv64/blk000000003.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64/blk000000004.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-riscv64/blk000000004.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64/blk000000005.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-riscv64/blk000000005.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64/blk000000006.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-riscv64/blk000000006.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64/blk000000007.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-riscv64/blk000000007.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64/blk000000008.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-riscv64/blk000000008.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64/blk000000009.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-riscv64/blk000000009.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64/blk000000010.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-riscv64/blk000000010.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64/blk000000011.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-riscv64/blk000000011.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64/blk000000012.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-riscv64/blk000000012.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64/blk000000013.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-riscv64/blk000000013.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64/blk000000014.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-riscv64/blk000000014.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-riscv64/blk000000015.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-riscv64/blk000000015.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-x86.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86.cfg: -------------------------------------------------------------------------------- 1 | /* VM configuration file */ 2 | { 3 | version: 1, 4 | machine: "pc", 5 | memory_size: 128, 6 | kernel: "kernel-x86.bin", 7 | cmdline: "loglevel=3 console=hvc0 root=/dev/vda rw", 8 | drive0: { file: "root-x86/blk.txt" }, 9 | eth0: { driver: "user" }, 10 | } 11 | -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86/blk.txt: -------------------------------------------------------------------------------- 1 | { 2 | block_size: 256, 3 | n_block: 16, 4 | } 5 | -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86/blk000000000.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-x86/blk000000000.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86/blk000000001.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-x86/blk000000001.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86/blk000000002.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-x86/blk000000002.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86/blk000000003.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-x86/blk000000003.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86/blk000000004.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-x86/blk000000004.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86/blk000000005.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-x86/blk000000005.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86/blk000000006.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-x86/blk000000006.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86/blk000000007.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-x86/blk000000007.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86/blk000000008.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-x86/blk000000008.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86/blk000000009.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-x86/blk000000009.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86/blk000000010.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-x86/blk000000010.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86/blk000000011.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-x86/blk000000011.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86/blk000000012.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-x86/blk000000012.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86/blk000000013.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-x86/blk000000013.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86/blk000000014.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-x86/blk000000014.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/root-x86/blk000000015.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/root-x86/blk000000015.bin -------------------------------------------------------------------------------- /jslinux-2019-12-21/style.css: -------------------------------------------------------------------------------- 1 | .term { 2 | font-family: courier,fixed,swiss,monospace,sans-serif; 3 | font-size: 15px; 4 | color: #f0f0f0; 5 | background: #000000; 6 | } 7 | 8 | .term_content a { 9 | color: #ffff00; 10 | } 11 | 12 | .term_cursor { 13 | color: #000000; 14 | background: #00ff00; 15 | } 16 | 17 | .term_scrollbar { background: transparent url(images/bg-scrollbar-track-y.png) no-repeat 0 0; position: relative; background-position: 0 0; float: right; width: 15px; height: 100%; } 18 | .term_track { background: transparent url(images/bg-scrollbar-trackend-y.png) no-repeat 0 100%; height: 100%; width:13px; position: relative; padding: 0 1px; } 19 | .term_thumb { background: transparent url(images/bg-scrollbar-thumb-y.png) no-repeat 50% 100%; height: 20px; width: 25px; cursor: pointer; overflow: hidden; position: absolute; top: 0; left: -5px; } 20 | .term_thumb .term_end { background: transparent url(images/bg-scrollbar-thumb-y.png) no-repeat 50% 0; overflow: hidden; height: 5px; width: 25px; } 21 | .noSelect { user-select: none; -o-user-select: none; -moz-user-select: none; -khtml-user-select: none; -webkit-user-select: none; } 22 | #term_paste { 23 | border: 1px solid; 24 | height: 19px; 25 | } 26 | 27 | /* file import */ 28 | #files { 29 | visibility: hidden; 30 | width:1px; 31 | height:1px; 32 | padding: 0px; 33 | margin: 0px; 34 | bordex: 0px; 35 | } 36 | 37 | label { 38 | cursor: pointer; 39 | margin-left: 5px; 40 | margin-right: 5px; 41 | } 42 | -------------------------------------------------------------------------------- /jslinux-2019-12-21/x86emu-wasm.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhhuh/tinyemu/1a534eb4c3bd70197b99062fcdec2ab97a075fc2/jslinux-2019-12-21/x86emu-wasm.wasm -------------------------------------------------------------------------------- /json.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Pseudo JSON parser 3 | * 4 | * Copyright (c) 2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef JSON_H 25 | #define JSON_H 26 | 27 | typedef enum { 28 | JSON_STR, 29 | JSON_INT, 30 | JSON_OBJ, 31 | JSON_ARRAY, 32 | JSON_BOOL, 33 | JSON_NULL, 34 | JSON_UNDEFINED, 35 | JSON_EXCEPTION, 36 | } JSONTypeEnum; 37 | 38 | typedef struct { 39 | int len; 40 | char data[0]; 41 | } JSONString; 42 | 43 | typedef struct JSONValue { 44 | JSONTypeEnum type; 45 | union { 46 | JSONString *str; 47 | int int32; 48 | BOOL b; 49 | struct JSONObject *obj; 50 | struct JSONArray *array; 51 | } u; 52 | } JSONValue; 53 | 54 | typedef struct JSONProperty { 55 | JSONValue name; 56 | JSONValue value; 57 | } JSONProperty; 58 | 59 | typedef struct JSONObject { 60 | int len; 61 | int size; 62 | JSONProperty *props; 63 | } JSONObject; 64 | 65 | typedef struct JSONArray { 66 | int len; 67 | int size; 68 | JSONValue *tab; 69 | } JSONArray; 70 | 71 | JSONValue json_string_new2(const char *str, int len); 72 | JSONValue json_string_new(const char *str); 73 | JSONValue __attribute__((format(printf, 1, 2))) json_error_new(const char *fmt, ...); 74 | void json_free(JSONValue val); 75 | 76 | JSONValue json_object_new(void); 77 | JSONValue json_object_get(JSONValue val, const char *name); 78 | int json_object_set(JSONValue val, const char *name, JSONValue prop_val); 79 | 80 | JSONValue json_array_new(void); 81 | JSONValue json_array_get(JSONValue val, unsigned int idx); 82 | int json_array_set(JSONValue val, unsigned int idx, JSONValue prop_val); 83 | 84 | static inline BOOL json_is_error(JSONValue val) 85 | { 86 | return val.type == JSON_EXCEPTION; 87 | } 88 | 89 | static inline BOOL json_is_undefined(JSONValue val) 90 | { 91 | return val.type == JSON_UNDEFINED; 92 | } 93 | 94 | static inline JSONValue json_undefined_new(void) 95 | { 96 | JSONValue val; 97 | val.type = JSON_UNDEFINED; 98 | val.u.int32 = 0; 99 | return val; 100 | } 101 | 102 | static inline JSONValue json_null_new(void) 103 | { 104 | JSONValue val; 105 | val.type = JSON_NULL; 106 | val.u.int32 = 0; 107 | return val; 108 | } 109 | 110 | static inline JSONValue json_int32_new(int v) 111 | { 112 | JSONValue val; 113 | val.type = JSON_INT; 114 | val.u.int32 = v; 115 | return val; 116 | } 117 | 118 | static inline JSONValue json_bool_new(BOOL v) 119 | { 120 | JSONValue val; 121 | val.type = JSON_BOOL; 122 | val.u.b = v; 123 | return val; 124 | } 125 | 126 | const char *json_get_str(JSONValue val); 127 | const char *json_get_error(JSONValue val); 128 | 129 | JSONValue json_parse_value(const char *p); 130 | JSONValue json_parse_value_len(const char *p, int len); 131 | 132 | #endif /* JSON_H */ 133 | -------------------------------------------------------------------------------- /list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Linux klist like system 3 | * 4 | * Copyright (c) 2016-2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIST_H 25 | #define LIST_H 26 | 27 | struct list_head { 28 | struct list_head *prev; 29 | struct list_head *next; 30 | }; 31 | 32 | /* return the pointer of type 'type *' containing 'el' as field 'member' */ 33 | #define list_entry(el, type, member) \ 34 | ((type *)((uint8_t *)(el) - offsetof(type, member))) 35 | 36 | static inline void init_list_head(struct list_head *head) 37 | { 38 | head->prev = head; 39 | head->next = head; 40 | } 41 | 42 | /* insert 'el' between 'prev' and 'next' */ 43 | static inline void __list_add(struct list_head *el, 44 | struct list_head *prev, struct list_head *next) 45 | { 46 | prev->next = el; 47 | el->prev = prev; 48 | el->next = next; 49 | next->prev = el; 50 | } 51 | 52 | /* add 'el' at the head of the list 'head' (= after element head) */ 53 | static inline void list_add(struct list_head *el, struct list_head *head) 54 | { 55 | __list_add(el, head, head->next); 56 | } 57 | 58 | /* add 'el' at the end of the list 'head' (= before element head) */ 59 | static inline void list_add_tail(struct list_head *el, struct list_head *head) 60 | { 61 | __list_add(el, head->prev, head); 62 | } 63 | 64 | static inline void list_del(struct list_head *el) 65 | { 66 | struct list_head *prev, *next; 67 | prev = el->prev; 68 | next = el->next; 69 | prev->next = next; 70 | next->prev = prev; 71 | el->prev = NULL; /* fail safe */ 72 | el->next = NULL; /* fail safe */ 73 | } 74 | 75 | static inline int list_empty(struct list_head *el) 76 | { 77 | return el->next == el; 78 | } 79 | 80 | #define list_for_each(el, head) \ 81 | for(el = (head)->next; el != (head); el = el->next) 82 | 83 | #define list_for_each_safe(el, el1, head) \ 84 | for(el = (head)->next, el1 = el->next; el != (head); \ 85 | el = el1, el1 = el->next) 86 | 87 | #define list_for_each_prev(el, head) \ 88 | for(el = (head)->prev; el != (head); el = el->prev) 89 | 90 | #define list_for_each_prev_safe(el, el1, head) \ 91 | for(el = (head)->prev, el1 = el->prev; el != (head); \ 92 | el = el1, el1 = el->prev) 93 | 94 | #endif /* LIST_H */ 95 | -------------------------------------------------------------------------------- /machine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * VM definitions 3 | * 4 | * Copyright (c) 2016-2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include "json.h" 25 | 26 | typedef struct FBDevice FBDevice; 27 | 28 | typedef void SimpleFBDrawFunc(FBDevice *fb_dev, void *opaque, 29 | int x, int y, int w, int h); 30 | 31 | struct FBDevice { 32 | /* the following is set by the device */ 33 | int width; 34 | int height; 35 | int stride; /* current stride in bytes */ 36 | uint8_t *fb_data; /* current pointer to the pixel data */ 37 | int fb_size; /* frame buffer memory size (info only) */ 38 | void *device_opaque; 39 | void (*refresh)(struct FBDevice *fb_dev, 40 | SimpleFBDrawFunc *redraw_func, void *opaque); 41 | }; 42 | 43 | #define MAX_DRIVE_DEVICE 4 44 | #define MAX_FS_DEVICE 4 45 | #define MAX_ETH_DEVICE 1 46 | 47 | #define VM_CONFIG_VERSION 1 48 | 49 | typedef enum { 50 | VM_FILE_BIOS, 51 | VM_FILE_VGA_BIOS, 52 | VM_FILE_KERNEL, 53 | VM_FILE_INITRD, 54 | 55 | VM_FILE_COUNT, 56 | } VMFileTypeEnum; 57 | 58 | typedef struct { 59 | char *filename; 60 | uint8_t *buf; 61 | int len; 62 | } VMFileEntry; 63 | 64 | typedef struct { 65 | char *device; 66 | char *filename; 67 | BlockDevice *block_dev; 68 | } VMDriveEntry; 69 | 70 | typedef struct { 71 | char *device; 72 | char *tag; /* 9p mount tag */ 73 | char *filename; 74 | FSDevice *fs_dev; 75 | } VMFSEntry; 76 | 77 | typedef struct { 78 | char *driver; 79 | char *ifname; 80 | EthernetDevice *net; 81 | } VMEthEntry; 82 | 83 | typedef struct VirtMachineClass VirtMachineClass; 84 | 85 | typedef struct { 86 | char *cfg_filename; 87 | const VirtMachineClass *vmc; 88 | char *machine_name; 89 | uint64_t ram_size; 90 | BOOL rtc_real_time; 91 | BOOL rtc_local_time; 92 | char *display_device; /* NULL means no display */ 93 | int width, height; /* graphic width & height */ 94 | CharacterDevice *console; 95 | VMDriveEntry tab_drive[MAX_DRIVE_DEVICE]; 96 | int drive_count; 97 | VMFSEntry tab_fs[MAX_FS_DEVICE]; 98 | int fs_count; 99 | VMEthEntry tab_eth[MAX_ETH_DEVICE]; 100 | int eth_count; 101 | 102 | char *cmdline; /* bios or kernel command line */ 103 | BOOL accel_enable; /* enable acceleration (KVM) */ 104 | char *input_device; /* NULL means no input */ 105 | 106 | /* kernel, bios and other auxiliary files */ 107 | VMFileEntry files[VM_FILE_COUNT]; 108 | } VirtMachineParams; 109 | 110 | typedef struct VirtMachine { 111 | const VirtMachineClass *vmc; 112 | /* network */ 113 | EthernetDevice *net; 114 | /* console */ 115 | VIRTIODevice *console_dev; 116 | CharacterDevice *console; 117 | /* graphics */ 118 | FBDevice *fb_dev; 119 | } VirtMachine; 120 | 121 | struct VirtMachineClass { 122 | const char *machine_names; 123 | void (*virt_machine_set_defaults)(VirtMachineParams *p); 124 | VirtMachine *(*virt_machine_init)(const VirtMachineParams *p); 125 | void (*virt_machine_end)(VirtMachine *s); 126 | int (*virt_machine_get_sleep_duration)(VirtMachine *s, int delay); 127 | void (*virt_machine_interp)(VirtMachine *s, int max_exec_cycle); 128 | BOOL (*vm_mouse_is_absolute)(VirtMachine *s); 129 | void (*vm_send_mouse_event)(VirtMachine *s1, int dx, int dy, int dz, 130 | unsigned int buttons); 131 | void (*vm_send_key_event)(VirtMachine *s1, BOOL is_down, uint16_t key_code); 132 | }; 133 | 134 | extern const VirtMachineClass riscv_machine_class; 135 | extern const VirtMachineClass pc_machine_class; 136 | 137 | void __attribute__((format(printf, 1, 2))) vm_error(const char *fmt, ...); 138 | int vm_get_int(JSONValue obj, const char *name, int *pval); 139 | int vm_get_int_opt(JSONValue obj, const char *name, int *pval, int def_val); 140 | 141 | void virt_machine_set_defaults(VirtMachineParams *p); 142 | void virt_machine_load_config_file(VirtMachineParams *p, 143 | const char *filename, 144 | void (*start_cb)(void *opaque), 145 | void *opaque); 146 | void vm_add_cmdline(VirtMachineParams *p, const char *cmdline); 147 | char *get_file_path(const char *base_filename, const char *filename); 148 | void virt_machine_free_config(VirtMachineParams *p); 149 | VirtMachine *virt_machine_init(const VirtMachineParams *p); 150 | void virt_machine_end(VirtMachine *s); 151 | static inline int virt_machine_get_sleep_duration(VirtMachine *s, int delay) 152 | { 153 | return s->vmc->virt_machine_get_sleep_duration(s, delay); 154 | } 155 | static inline void virt_machine_interp(VirtMachine *s, int max_exec_cycle) 156 | { 157 | s->vmc->virt_machine_interp(s, max_exec_cycle); 158 | } 159 | static inline BOOL vm_mouse_is_absolute(VirtMachine *s) 160 | { 161 | return s->vmc->vm_mouse_is_absolute(s); 162 | } 163 | static inline void vm_send_mouse_event(VirtMachine *s1, int dx, int dy, int dz, 164 | unsigned int buttons) 165 | { 166 | s1->vmc->vm_send_mouse_event(s1, dx, dy, dz, buttons); 167 | } 168 | static inline void vm_send_key_event(VirtMachine *s1, BOOL is_down, uint16_t key_code) 169 | { 170 | s1->vmc->vm_send_key_event(s1, is_down, key_code); 171 | } 172 | 173 | /* gui */ 174 | void sdl_refresh(VirtMachine *m); 175 | void sdl_init(int width, int height); 176 | 177 | /* simplefb.c */ 178 | typedef struct SimpleFBState SimpleFBState; 179 | SimpleFBState *simplefb_init(PhysMemoryMap *map, uint64_t phys_addr, 180 | FBDevice *fb_dev, int width, int height); 181 | void simplefb_refresh(FBDevice *fb_dev, 182 | SimpleFBDrawFunc *redraw_func, void *opaque, 183 | PhysMemoryRange *mem_range, 184 | int fb_page_count); 185 | 186 | /* vga.c */ 187 | typedef struct VGAState VGAState; 188 | VGAState *pci_vga_init(PCIBus *bus, FBDevice *fb_dev, 189 | int width, int height, 190 | const uint8_t *vga_rom_buf, int vga_rom_size); 191 | 192 | /* block_net.c */ 193 | BlockDevice *block_device_init_http(const char *url, 194 | int max_cache_size_kb, 195 | void (*start_cb)(void *opaque), 196 | void *start_opaque); 197 | -------------------------------------------------------------------------------- /netinit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # RISCVEMU Ethernet bridge and NAT configuration (run with sudo) 4 | # 5 | # Copyright (c) 2017 Fabrice Bellard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in 15 | # all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | # THE SOFTWARE. 24 | # 25 | 26 | # host network interface connected to Internet (change it) 27 | internet_ifname="enp0s20f0u1" 28 | 29 | # setup bridge interface 30 | ip link add br0 type bridge 31 | # create and add tap0 interface to bridge 32 | ip tuntap add dev tap0 mode tap user $USER 33 | ip link set tap0 master br0 34 | 35 | ip link set dev br0 up 36 | ip link set dev tap0 up 37 | ifconfig br0 192.168.3.1 38 | 39 | # setup NAT to access to Internet 40 | echo 1 > /proc/sys/net/ipv4/ip_forward 41 | # delete forwarding reject rule if present 42 | #iptables -D FORWARD 1 43 | iptables -t nat -A POSTROUTING -o $internet_ifname -j MASQUERADE 44 | -------------------------------------------------------------------------------- /pci.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple PCI bus driver 3 | * 4 | * Copyright (c) 2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef PCI_H 25 | #define PCI_H 26 | 27 | #include "iomem.h" 28 | 29 | typedef struct PCIBus PCIBus; 30 | typedef struct PCIDevice PCIDevice; 31 | 32 | /* bar type */ 33 | #define PCI_ADDRESS_SPACE_MEM 0x00 34 | #define PCI_ADDRESS_SPACE_IO 0x01 35 | #define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08 36 | 37 | #define PCI_ROM_SLOT 6 38 | #define PCI_NUM_REGIONS 7 39 | 40 | /* PCI config addresses */ 41 | #define PCI_VENDOR_ID 0x00 /* 16 bits */ 42 | #define PCI_DEVICE_ID 0x02 /* 16 bits */ 43 | #define PCI_COMMAND 0x04 /* 16 bits */ 44 | #define PCI_COMMAND_IO (1 << 0) 45 | #define PCI_COMMAND_MEMORY (1 << 1) 46 | #define PCI_STATUS 0x06 /* 16 bits */ 47 | #define PCI_STATUS_CAP_LIST (1 << 4) 48 | #define PCI_CLASS_PROG 0x09 49 | #define PCI_SUBSYSTEM_VENDOR_ID 0x2c /* 16 bits */ 50 | #define PCI_SUBSYSTEM_ID 0x2e /* 16 bits */ 51 | #define PCI_CAPABILITY_LIST 0x34 /* 8 bits */ 52 | #define PCI_INTERRUPT_LINE 0x3c /* 8 bits */ 53 | #define PCI_INTERRUPT_PIN 0x3d /* 8 bits */ 54 | 55 | typedef void PCIBarSetFunc(void *opaque, int bar_num, uint32_t addr, 56 | BOOL enabled); 57 | 58 | PCIDevice *pci_register_device(PCIBus *b, const char *name, int devfn, 59 | uint16_t vendor_id, uint16_t device_id, 60 | uint8_t revision, uint16_t class_id); 61 | PhysMemoryMap *pci_device_get_mem_map(PCIDevice *d); 62 | PhysMemoryMap *pci_device_get_port_map(PCIDevice *d); 63 | void pci_register_bar(PCIDevice *d, unsigned int bar_num, 64 | uint32_t size, int type, 65 | void *opaque, PCIBarSetFunc *bar_set); 66 | IRQSignal *pci_device_get_irq(PCIDevice *d, unsigned int irq_num); 67 | uint8_t *pci_device_get_dma_ptr(PCIDevice *d, uint64_t addr, BOOL is_rw); 68 | void pci_device_set_config8(PCIDevice *d, uint8_t addr, uint8_t val); 69 | void pci_device_set_config16(PCIDevice *d, uint8_t addr, uint16_t val); 70 | int pci_device_get_devfn(PCIDevice *d); 71 | int pci_add_capability(PCIDevice *d, const uint8_t *buf, int size); 72 | 73 | typedef struct I440FXState I440FXState; 74 | 75 | I440FXState *i440fx_init(PCIBus **pbus, int *ppiix3_devfn, 76 | PhysMemoryMap *mem_map, PhysMemoryMap *port_map, 77 | IRQSignal *pic_irqs); 78 | void i440fx_map_interrupts(I440FXState *s, uint8_t *elcr, 79 | const uint8_t *pci_irqs); 80 | 81 | #endif /* PCI_H */ 82 | -------------------------------------------------------------------------------- /ps2.h: -------------------------------------------------------------------------------- 1 | /* ps2.c */ 2 | typedef struct PS2MouseState PS2MouseState; 3 | typedef struct PS2KbdState PS2KbdState; 4 | 5 | PS2KbdState *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg); 6 | PS2MouseState *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg); 7 | void ps2_write_mouse(void *, int val); 8 | void ps2_write_keyboard(void *, int val); 9 | uint32_t ps2_read_data(void *); 10 | void ps2_queue(void *, int b); 11 | void ps2_keyboard_set_translation(void *opaque, int mode); 12 | 13 | void ps2_put_keycode(PS2KbdState *s, BOOL is_down, int keycode); 14 | void ps2_mouse_event(PS2MouseState *s, 15 | int dx, int dy, int dz, int buttons_state); 16 | 17 | /* vmmouse.c */ 18 | typedef struct VMMouseState VMMouseState; 19 | 20 | VMMouseState *vmmouse_init(PS2MouseState *ps2_mouse); 21 | BOOL vmmouse_is_absolute(VMMouseState *s); 22 | void vmmouse_send_mouse_event(VMMouseState *s, int x, int y, int dz, 23 | int buttons); 24 | void vmmouse_handler(VMMouseState *s, uint32_t *regs); 25 | 26 | /* pckbd.c */ 27 | 28 | typedef struct KBDState KBDState; 29 | 30 | KBDState *i8042_init(PS2KbdState **pkbd, 31 | PS2MouseState **pmouse, 32 | PhysMemoryMap *port_map, 33 | IRQSignal *kbd_irq, IRQSignal *mouse_irq, 34 | uint32_t io_base); 35 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | TinyEMU System Emulator by Fabrice Bellard 2 | ========================================== 3 | 4 | 1) Features 5 | ----------- 6 | 7 | - RISC-V system emulator supporting the RV128IMAFDQC base ISA (user 8 | level ISA version 2.2, priviledged architecture version 1.10) 9 | including: 10 | 11 | - 32/64/128 bit integer registers 12 | - 32/64/128 bit floating point instructions 13 | - Compressed instructions 14 | - dynamic XLEN change 15 | 16 | - x86 system emulator based on KVM 17 | 18 | - VirtIO console, network, block device, input and 9P filesystem 19 | 20 | - Graphical display with SDL 21 | 22 | - JSON configuration file 23 | 24 | - Remote HTTP block device and filesystem 25 | 26 | - small code, easy to modify, no external dependancies 27 | 28 | - Javascript demo version 29 | 30 | 2) Installation 31 | --------------- 32 | 33 | - The libraries libcurl, OpenSSL and SDL should be installed. On a Fedora 34 | system you can do it with: 35 | 36 | sudo dnf install openssl-devel libcurl-devel SDL-devel 37 | 38 | It is possible to compile the programs without these libraries by 39 | commenting CONFIG_FS_NET and/or CONFIG_SDL in the Makefile. 40 | 41 | - Edit the Makefile to disable the 128 bit target if you compile on a 42 | 32 bit host (for the 128 bit RISCV target the compiler must support 43 | the __int128 C extension). 44 | 45 | - Use 'make' to compile the binaries. 46 | 47 | - You can optionally install the program to '/usr/local/bin' with: 48 | 49 | make install 50 | 51 | 3) Usage 52 | -------- 53 | 54 | 3.1 Quick examples 55 | ------------------ 56 | 57 | - Use the VM images available from https://bellard.org/jslinux (no 58 | need to download them): 59 | 60 | Terminal: 61 | 62 | ./temu https://bellard.org/jslinux/buildroot-riscv64.cfg 63 | 64 | Graphical (with SDL): 65 | 66 | ./temu https://bellard.org/jslinux/buildroot-x86-xwin.cfg 67 | 68 | ./temu https://bellard.org/jslinux/win2k.cfg 69 | 70 | - Download the example RISC-V Linux image 71 | (diskimage-linux-riscv-yyyy-mm-dd.tar.gz) and use it: 72 | 73 | ./temu root-riscv64.cfg 74 | 75 | ./temu rv128test/rv128test.cfg 76 | 77 | - Access to your local hard disk (/tmp directory) in the guest: 78 | 79 | ./temu root_9p-riscv64.cfg 80 | 81 | then type: 82 | mount -t 9p /dev/root /mnt 83 | 84 | in the guest. The content of the host '/tmp' directory is visible in '/mnt'. 85 | 86 | 3.2 Invocation 87 | -------------- 88 | 89 | usage: temu [options] config_file 90 | options are: 91 | -m ram_size set the RAM size in MB 92 | -rw allow write access to the disk image (default=snapshot) 93 | -ctrlc the C-c key stops the emulator instead of being sent to the 94 | emulated software 95 | -append cmdline append cmdline to the kernel command line 96 | -no-accel disable VM acceleration (KVM, x86 machine only) 97 | 98 | Console keys: 99 | Press C-a x to exit the emulator, C-a h to get some help. 100 | 101 | 3.3 Network usage 102 | ----------------- 103 | 104 | The easiest way is to use the "user" mode network driver. No specific 105 | configuration is necessary. 106 | 107 | TinyEMU also supports a "tap" network driver to redirect the network 108 | traffic from a VirtIO network adapter. 109 | 110 | You can look at the netinit.sh script to create the tap network 111 | interface and to redirect the virtual traffic to Internet thru a 112 | NAT. The exact configuration may depend on the Linux distribution and 113 | local firewall configuration. 114 | 115 | The VM configuration file must include: 116 | 117 | eth0: { driver: "tap", ifname: "tap0" } 118 | 119 | and configure the network in the guest system with: 120 | 121 | ifconfig eth0 192.168.3.2 122 | route add -net 0.0.0.0 gw 192.168.3.1 eth0 123 | 124 | 3.4 Network filesystem 125 | ---------------------- 126 | 127 | TinyEMU supports the VirtIO 9P filesystem to access local or remote 128 | filesystems. For remote filesystems, it does HTTP requests to download 129 | the files. The protocol is compatible with the vfsync utility. In the 130 | "mount" command, "/dev/rootN" must be used as device name where N is 131 | the index of the filesystem. When N=0 it is omitted. 132 | 133 | The build_filelist tool builds the file list from a root directory. A 134 | simple web server is enough to serve the files. 135 | 136 | The '.preload' file gives a list of files to preload when opening a 137 | given file. 138 | 139 | 3.5 Network block device 140 | ------------------------ 141 | 142 | TinyEMU supports an HTTP block device. The disk image is split into 143 | small files. Use the 'splitimg' utility to generate images. The URL of 144 | the JSON blk.txt file must be provided as disk image filename. 145 | 146 | 4) Technical notes 147 | ------------------ 148 | 149 | 4.1) 128 bit support 150 | 151 | The RISC-V specification does not define all the instruction encodings 152 | for the 128 bit integer and floating point operations. The missing 153 | ones were interpolated from the 32 and 64 ones. 154 | 155 | Unfortunately there is no RISC-V 128 bit toolchain nor OS now 156 | (volunteers for the Linux port ?), so rv128test.bin may be the first 157 | 128 bit code for RISC-V ! 158 | 159 | 4.2) Floating point emulation 160 | 161 | The floating point emulation is bit exact and supports all the 162 | specified instructions for 32, 64 and 128 bit floating point 163 | numbers. It uses the new SoftFP library. 164 | 165 | 4.3) HTIF console 166 | 167 | The standard HTIF console uses registers at variable addresses which 168 | are deduced by loading specific ELF symbols. TinyEMU does not rely on 169 | an ELF loader, so it is much simpler to use registers at fixed 170 | addresses (0x40008000). A small modification was made in the 171 | "riscv-pk" boot loader to support it. The HTIF console is only used to 172 | display boot messages and to power off the virtual system. The OS 173 | should use the VirtIO console. 174 | 175 | 4.4) Javascript version 176 | 177 | The Javascript version (JSLinux) can be compiled with Makefile.js and 178 | emscripten. A complete precompiled and preconfigured demo is available 179 | in the jslinux-yyyy-mm-dd.tar.gz archive (read the readme.txt file 180 | inside the archive). 181 | 182 | 4.5) x86 emulator 183 | 184 | A small x86 emulator is included. It is not really an emulator because 185 | it uses the Linux KVM API to run the x86 code at near native 186 | performance. The x86 emulator uses the same set of VirtIO devices as 187 | the RISCV emulator and is able to run many operating systems. 188 | 189 | The x86 emulator accepts a Linux kernel image (bzImage). No BIOS image 190 | is necessary. 191 | 192 | The x86 emulator comes from my JS/Linux project (2011) which was one 193 | of the first emulator running Linux fully implemented in 194 | Javascript. It is provided to allow easy access to the x86 images 195 | hosted at https://bellard.org/jslinux . 196 | 197 | 198 | 5) License / Credits 199 | -------------------- 200 | 201 | TinyEMU is released under the MIT license. If there is no explicit 202 | license in a file, the license from MIT-LICENSE.txt applies. 203 | 204 | The SLIRP library has its own license (two clause BSD license). 205 | -------------------------------------------------------------------------------- /riscv_cpu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * RISCV CPU emulator 3 | * 4 | * Copyright (c) 2016-2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef RISCV_CPU_H 25 | #define RISCV_CPU_H 26 | 27 | #include 28 | #include "cutils.h" 29 | #include "iomem.h" 30 | 31 | #define MIP_USIP (1 << 0) 32 | #define MIP_SSIP (1 << 1) 33 | #define MIP_HSIP (1 << 2) 34 | #define MIP_MSIP (1 << 3) 35 | #define MIP_UTIP (1 << 4) 36 | #define MIP_STIP (1 << 5) 37 | #define MIP_HTIP (1 << 6) 38 | #define MIP_MTIP (1 << 7) 39 | #define MIP_UEIP (1 << 8) 40 | #define MIP_SEIP (1 << 9) 41 | #define MIP_HEIP (1 << 10) 42 | #define MIP_MEIP (1 << 11) 43 | 44 | typedef struct RISCVCPUState RISCVCPUState; 45 | 46 | typedef struct { 47 | RISCVCPUState *(*riscv_cpu_init)(PhysMemoryMap *mem_map); 48 | void (*riscv_cpu_end)(RISCVCPUState *s); 49 | void (*riscv_cpu_interp)(RISCVCPUState *s, int n_cycles); 50 | uint64_t (*riscv_cpu_get_cycles)(RISCVCPUState *s); 51 | void (*riscv_cpu_set_mip)(RISCVCPUState *s, uint32_t mask); 52 | void (*riscv_cpu_reset_mip)(RISCVCPUState *s, uint32_t mask); 53 | uint32_t (*riscv_cpu_get_mip)(RISCVCPUState *s); 54 | BOOL (*riscv_cpu_get_power_down)(RISCVCPUState *s); 55 | uint32_t (*riscv_cpu_get_misa)(RISCVCPUState *s); 56 | void (*riscv_cpu_flush_tlb_write_range_ram)(RISCVCPUState *s, 57 | uint8_t *ram_ptr, size_t ram_size); 58 | } RISCVCPUClass; 59 | 60 | typedef struct { 61 | const RISCVCPUClass *class_ptr; 62 | } RISCVCPUCommonState; 63 | 64 | int riscv_cpu_get_max_xlen(void); 65 | 66 | extern const RISCVCPUClass riscv_cpu_class32; 67 | extern const RISCVCPUClass riscv_cpu_class64; 68 | extern const RISCVCPUClass riscv_cpu_class128; 69 | 70 | RISCVCPUState *riscv_cpu_init(PhysMemoryMap *mem_map, int max_xlen); 71 | static inline void riscv_cpu_end(RISCVCPUState *s) 72 | { 73 | const RISCVCPUClass *c = ((RISCVCPUCommonState *)s)->class_ptr; 74 | c->riscv_cpu_end(s); 75 | } 76 | static inline void riscv_cpu_interp(RISCVCPUState *s, int n_cycles) 77 | { 78 | const RISCVCPUClass *c = ((RISCVCPUCommonState *)s)->class_ptr; 79 | c->riscv_cpu_interp(s, n_cycles); 80 | } 81 | static inline uint64_t riscv_cpu_get_cycles(RISCVCPUState *s) 82 | { 83 | const RISCVCPUClass *c = ((RISCVCPUCommonState *)s)->class_ptr; 84 | return c->riscv_cpu_get_cycles(s); 85 | } 86 | static inline void riscv_cpu_set_mip(RISCVCPUState *s, uint32_t mask) 87 | { 88 | const RISCVCPUClass *c = ((RISCVCPUCommonState *)s)->class_ptr; 89 | c->riscv_cpu_set_mip(s, mask); 90 | } 91 | static inline void riscv_cpu_reset_mip(RISCVCPUState *s, uint32_t mask) 92 | { 93 | const RISCVCPUClass *c = ((RISCVCPUCommonState *)s)->class_ptr; 94 | c->riscv_cpu_reset_mip(s, mask); 95 | } 96 | static inline uint32_t riscv_cpu_get_mip(RISCVCPUState *s) 97 | { 98 | const RISCVCPUClass *c = ((RISCVCPUCommonState *)s)->class_ptr; 99 | return c->riscv_cpu_get_mip(s); 100 | } 101 | static inline BOOL riscv_cpu_get_power_down(RISCVCPUState *s) 102 | { 103 | const RISCVCPUClass *c = ((RISCVCPUCommonState *)s)->class_ptr; 104 | return c->riscv_cpu_get_power_down(s); 105 | } 106 | static inline uint32_t riscv_cpu_get_misa(RISCVCPUState *s) 107 | { 108 | const RISCVCPUClass *c = ((RISCVCPUCommonState *)s)->class_ptr; 109 | return c->riscv_cpu_get_misa(s); 110 | } 111 | static inline void riscv_cpu_flush_tlb_write_range_ram(RISCVCPUState *s, 112 | uint8_t *ram_ptr, size_t ram_size) 113 | { 114 | const RISCVCPUClass *c = ((RISCVCPUCommonState *)s)->class_ptr; 115 | c->riscv_cpu_flush_tlb_write_range_ram(s, ram_ptr, ram_size); 116 | } 117 | 118 | #endif /* RISCV_CPU_H */ 119 | -------------------------------------------------------------------------------- /sha256.h: -------------------------------------------------------------------------------- 1 | /* 2 | * OpenSSL compatible SHA256 header 3 | * 4 | * Copyright (c) 2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef SHA256_H 25 | #define SHA256_H 26 | 27 | #define SHA256_DIGEST_LENGTH 32 28 | 29 | typedef struct { 30 | uint64_t length; 31 | uint32_t state[8], curlen; 32 | uint8_t buf[64]; 33 | } SHA256_CTX; 34 | 35 | void SHA256_Init(SHA256_CTX *s); 36 | void SHA256_Update(SHA256_CTX *s, const uint8_t *in, unsigned long inlen); 37 | void SHA256_Final(uint8_t *out, SHA256_CTX *s); 38 | void SHA256(const uint8_t *buf, int buf_len, uint8_t *out); 39 | 40 | #endif /* SHA256_H */ 41 | -------------------------------------------------------------------------------- /simplefb.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple frame buffer 3 | * 4 | * Copyright (c) 2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "cutils.h" 32 | #include "iomem.h" 33 | #include "virtio.h" 34 | #include "machine.h" 35 | 36 | //#define DEBUG_VBE 37 | 38 | #define FB_ALLOC_ALIGN 65536 39 | 40 | struct SimpleFBState { 41 | FBDevice *fb_dev; 42 | int fb_page_count; 43 | PhysMemoryRange *mem_range; 44 | }; 45 | 46 | #define MAX_MERGE_DISTANCE 3 47 | 48 | void simplefb_refresh(FBDevice *fb_dev, 49 | SimpleFBDrawFunc *redraw_func, void *opaque, 50 | PhysMemoryRange *mem_range, 51 | int fb_page_count) 52 | { 53 | const uint32_t *dirty_bits; 54 | uint32_t dirty_val; 55 | int y0, y1, page_y0, page_y1, byte_pos, page_index, bit_pos; 56 | 57 | dirty_bits = phys_mem_get_dirty_bits(mem_range); 58 | 59 | page_index = 0; 60 | y0 = y1 = 0; 61 | while (page_index < fb_page_count) { 62 | dirty_val = dirty_bits[page_index >> 5]; 63 | if (dirty_val != 0) { 64 | bit_pos = 0; 65 | while (dirty_val != 0) { 66 | while (((dirty_val >> bit_pos) & 1) == 0) 67 | bit_pos++; 68 | dirty_val &= ~(1 << bit_pos); 69 | 70 | byte_pos = (page_index + bit_pos) * DEVRAM_PAGE_SIZE; 71 | page_y0 = byte_pos / fb_dev->stride; 72 | page_y1 = ((byte_pos + DEVRAM_PAGE_SIZE - 1) / fb_dev->stride) + 1; 73 | page_y1 = min_int(page_y1, fb_dev->height); 74 | if (y0 == y1) { 75 | y0 = page_y0; 76 | y1 = page_y1; 77 | } else if (page_y0 <= (y1 + MAX_MERGE_DISTANCE)) { 78 | /* union with current region */ 79 | y1 = page_y1; 80 | } else { 81 | /* flush */ 82 | redraw_func(fb_dev, opaque, 83 | 0, y0, fb_dev->width, y1 - y0); 84 | y0 = page_y0; 85 | y1 = page_y1; 86 | } 87 | } 88 | } 89 | page_index += 32; 90 | } 91 | 92 | if (y0 != y1) { 93 | redraw_func(fb_dev, opaque, 94 | 0, y0, fb_dev->width, y1 - y0); 95 | } 96 | } 97 | 98 | static void simplefb_refresh1(FBDevice *fb_dev, 99 | SimpleFBDrawFunc *redraw_func, void *opaque) 100 | { 101 | SimpleFBState *s = fb_dev->device_opaque; 102 | simplefb_refresh(fb_dev, redraw_func, opaque, s->mem_range, 103 | s->fb_page_count); 104 | } 105 | 106 | SimpleFBState *simplefb_init(PhysMemoryMap *map, uint64_t phys_addr, 107 | FBDevice *fb_dev, int width, int height) 108 | { 109 | SimpleFBState *s; 110 | 111 | s = mallocz(sizeof(*s)); 112 | s->fb_dev = fb_dev; 113 | 114 | fb_dev->width = width; 115 | fb_dev->height = height; 116 | fb_dev->stride = width * 4; 117 | fb_dev->fb_size = (height * fb_dev->stride + FB_ALLOC_ALIGN - 1) & ~(FB_ALLOC_ALIGN - 1); 118 | s->fb_page_count = fb_dev->fb_size >> DEVRAM_PAGE_SIZE_LOG2; 119 | 120 | s->mem_range = cpu_register_ram(map, phys_addr, fb_dev->fb_size, 121 | DEVRAM_FLAG_DIRTY_BITS); 122 | 123 | fb_dev->fb_data = s->mem_range->phys_mem; 124 | fb_dev->device_opaque = s; 125 | fb_dev->refresh = simplefb_refresh1; 126 | return s; 127 | } 128 | -------------------------------------------------------------------------------- /slirp/bootp.h: -------------------------------------------------------------------------------- 1 | /* bootp/dhcp defines */ 2 | 3 | #define BOOTP_SERVER 67 4 | #define BOOTP_CLIENT 68 5 | 6 | #define BOOTP_REQUEST 1 7 | #define BOOTP_REPLY 2 8 | 9 | #define RFC1533_COOKIE 99, 130, 83, 99 10 | #define RFC1533_PAD 0 11 | #define RFC1533_NETMASK 1 12 | #define RFC1533_TIMEOFFSET 2 13 | #define RFC1533_GATEWAY 3 14 | #define RFC1533_TIMESERVER 4 15 | #define RFC1533_IEN116NS 5 16 | #define RFC1533_DNS 6 17 | #define RFC1533_LOGSERVER 7 18 | #define RFC1533_COOKIESERVER 8 19 | #define RFC1533_LPRSERVER 9 20 | #define RFC1533_IMPRESSSERVER 10 21 | #define RFC1533_RESOURCESERVER 11 22 | #define RFC1533_HOSTNAME 12 23 | #define RFC1533_BOOTFILESIZE 13 24 | #define RFC1533_MERITDUMPFILE 14 25 | #define RFC1533_DOMAINNAME 15 26 | #define RFC1533_SWAPSERVER 16 27 | #define RFC1533_ROOTPATH 17 28 | #define RFC1533_EXTENSIONPATH 18 29 | #define RFC1533_IPFORWARDING 19 30 | #define RFC1533_IPSOURCEROUTING 20 31 | #define RFC1533_IPPOLICYFILTER 21 32 | #define RFC1533_IPMAXREASSEMBLY 22 33 | #define RFC1533_IPTTL 23 34 | #define RFC1533_IPMTU 24 35 | #define RFC1533_IPMTUPLATEAU 25 36 | #define RFC1533_INTMTU 26 37 | #define RFC1533_INTLOCALSUBNETS 27 38 | #define RFC1533_INTBROADCAST 28 39 | #define RFC1533_INTICMPDISCOVER 29 40 | #define RFC1533_INTICMPRESPOND 30 41 | #define RFC1533_INTROUTEDISCOVER 31 42 | #define RFC1533_INTROUTESOLICIT 32 43 | #define RFC1533_INTSTATICROUTES 33 44 | #define RFC1533_LLTRAILERENCAP 34 45 | #define RFC1533_LLARPCACHETMO 35 46 | #define RFC1533_LLETHERNETENCAP 36 47 | #define RFC1533_TCPTTL 37 48 | #define RFC1533_TCPKEEPALIVETMO 38 49 | #define RFC1533_TCPKEEPALIVEGB 39 50 | #define RFC1533_NISDOMAIN 40 51 | #define RFC1533_NISSERVER 41 52 | #define RFC1533_NTPSERVER 42 53 | #define RFC1533_VENDOR 43 54 | #define RFC1533_NBNS 44 55 | #define RFC1533_NBDD 45 56 | #define RFC1533_NBNT 46 57 | #define RFC1533_NBSCOPE 47 58 | #define RFC1533_XFS 48 59 | #define RFC1533_XDM 49 60 | 61 | #define RFC2132_REQ_ADDR 50 62 | #define RFC2132_LEASE_TIME 51 63 | #define RFC2132_MSG_TYPE 53 64 | #define RFC2132_SRV_ID 54 65 | #define RFC2132_PARAM_LIST 55 66 | #define RFC2132_MESSAGE 56 67 | #define RFC2132_MAX_SIZE 57 68 | #define RFC2132_RENEWAL_TIME 58 69 | #define RFC2132_REBIND_TIME 59 70 | 71 | #define DHCPDISCOVER 1 72 | #define DHCPOFFER 2 73 | #define DHCPREQUEST 3 74 | #define DHCPACK 5 75 | #define DHCPNAK 6 76 | 77 | #define RFC1533_VENDOR_MAJOR 0 78 | #define RFC1533_VENDOR_MINOR 0 79 | 80 | #define RFC1533_VENDOR_MAGIC 128 81 | #define RFC1533_VENDOR_ADDPARM 129 82 | #define RFC1533_VENDOR_ETHDEV 130 83 | #define RFC1533_VENDOR_HOWTO 132 84 | #define RFC1533_VENDOR_MNUOPTS 160 85 | #define RFC1533_VENDOR_SELECTION 176 86 | #define RFC1533_VENDOR_MOTD 184 87 | #define RFC1533_VENDOR_NUMOFMOTD 8 88 | #define RFC1533_VENDOR_IMG 192 89 | #define RFC1533_VENDOR_NUMOFIMG 16 90 | 91 | #define RFC1533_END 255 92 | #define BOOTP_VENDOR_LEN 64 93 | #define DHCP_OPT_LEN 312 94 | 95 | struct bootp_t { 96 | struct ip ip; 97 | struct udphdr udp; 98 | uint8_t bp_op; 99 | uint8_t bp_htype; 100 | uint8_t bp_hlen; 101 | uint8_t bp_hops; 102 | uint32_t bp_xid; 103 | uint16_t bp_secs; 104 | uint16_t unused; 105 | struct in_addr bp_ciaddr; 106 | struct in_addr bp_yiaddr; 107 | struct in_addr bp_siaddr; 108 | struct in_addr bp_giaddr; 109 | uint8_t bp_hwaddr[16]; 110 | uint8_t bp_sname[64]; 111 | uint8_t bp_file[128]; 112 | uint8_t bp_vend[DHCP_OPT_LEN]; 113 | }; 114 | 115 | typedef struct { 116 | uint16_t allocated; 117 | uint8_t macaddr[6]; 118 | } BOOTPClient; 119 | 120 | #define NB_BOOTP_CLIENTS 16 121 | 122 | void bootp_input(struct mbuf *m); 123 | -------------------------------------------------------------------------------- /slirp/cksum.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1988, 1992, 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the University nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93 30 | * in_cksum.c,v 1.2 1994/08/02 07:48:16 davidg Exp 31 | */ 32 | 33 | #include "slirp.h" 34 | 35 | /* 36 | * Checksum routine for Internet Protocol family headers (Portable Version). 37 | * 38 | * This routine is very heavily used in the network 39 | * code and should be modified for each CPU to be as fast as possible. 40 | * 41 | * XXX Since we will never span more than 1 mbuf, we can optimise this 42 | */ 43 | 44 | #define ADDCARRY(x) (x > 65535 ? x -= 65535 : x) 45 | #define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; \ 46 | (void)ADDCARRY(sum);} 47 | 48 | int cksum(struct mbuf *m, int len) 49 | { 50 | register uint16_t *w; 51 | register int sum = 0; 52 | register int mlen = 0; 53 | int byte_swapped = 0; 54 | 55 | union { 56 | uint8_t c[2]; 57 | uint16_t s; 58 | } s_util; 59 | union { 60 | uint16_t s[2]; 61 | uint32_t l; 62 | } l_util; 63 | 64 | if (m->m_len == 0) 65 | goto cont; 66 | w = mtod(m, uint16_t *); 67 | 68 | mlen = m->m_len; 69 | 70 | if (len < mlen) 71 | mlen = len; 72 | #ifdef DEBUG 73 | len -= mlen; 74 | #endif 75 | /* 76 | * Force to even boundary. 77 | */ 78 | if ((1 & (long) w) && (mlen > 0)) { 79 | REDUCE; 80 | sum <<= 8; 81 | s_util.c[0] = *(uint8_t *)w; 82 | w = (uint16_t *)((int8_t *)w + 1); 83 | mlen--; 84 | byte_swapped = 1; 85 | } 86 | /* 87 | * Unroll the loop to make overhead from 88 | * branches &c small. 89 | */ 90 | while ((mlen -= 32) >= 0) { 91 | sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; 92 | sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7]; 93 | sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11]; 94 | sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15]; 95 | w += 16; 96 | } 97 | mlen += 32; 98 | while ((mlen -= 8) >= 0) { 99 | sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; 100 | w += 4; 101 | } 102 | mlen += 8; 103 | if (mlen == 0 && byte_swapped == 0) 104 | goto cont; 105 | REDUCE; 106 | while ((mlen -= 2) >= 0) { 107 | sum += *w++; 108 | } 109 | 110 | if (byte_swapped) { 111 | REDUCE; 112 | sum <<= 8; 113 | if (mlen == -1) { 114 | s_util.c[1] = *(uint8_t *)w; 115 | sum += s_util.s; 116 | mlen = 0; 117 | } else 118 | 119 | mlen = -1; 120 | } else if (mlen == -1) 121 | s_util.c[0] = *(uint8_t *)w; 122 | 123 | cont: 124 | #ifdef DEBUG 125 | if (len) { 126 | DEBUG_ERROR((dfd, "cksum: out of data\n")); 127 | DEBUG_ERROR((dfd, " len = %d\n", len)); 128 | } 129 | #endif 130 | if (mlen == -1) { 131 | /* The last mbuf has odd # of bytes. Follow the 132 | standard (the odd byte may be shifted left by 8 bits 133 | or not as determined by endian-ness of the machine) */ 134 | s_util.c[1] = 0; 135 | sum += s_util.s; 136 | } 137 | REDUCE; 138 | return (~sum & 0xffff); 139 | } 140 | -------------------------------------------------------------------------------- /slirp/debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995 Danny Gasparovski. 3 | * 4 | * Please read the file COPYRIGHT for the 5 | * terms and conditions of the copyright. 6 | */ 7 | 8 | //#define DEBUG 1 9 | 10 | #ifdef DEBUG 11 | 12 | #define DBG_CALL 0x1 13 | #define DBG_MISC 0x2 14 | #define DBG_ERROR 0x4 15 | 16 | #define dfd stderr 17 | 18 | extern int slirp_debug; 19 | 20 | #define DEBUG_CALL(x) if (slirp_debug & DBG_CALL) { fprintf(dfd, "%s...\n", x); fflush(dfd); } 21 | #define DEBUG_ARG(x, y) if (slirp_debug & DBG_CALL) { fputc(' ', dfd); fprintf(dfd, x, y); fputc('\n', dfd); fflush(dfd); } 22 | #define DEBUG_ARGS(x) if (slirp_debug & DBG_CALL) { fprintf x ; fflush(dfd); } 23 | #define DEBUG_MISC(x) if (slirp_debug & DBG_MISC) { fprintf x ; fflush(dfd); } 24 | #define DEBUG_ERROR(x) if (slirp_debug & DBG_ERROR) {fprintf x ; fflush(dfd); } 25 | 26 | #else 27 | 28 | #define DEBUG_CALL(x) 29 | #define DEBUG_ARG(x, y) 30 | #define DEBUG_ARGS(x) 31 | #define DEBUG_MISC(x) 32 | #define DEBUG_ERROR(x) 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /slirp/if.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995 Danny Gasparovski. 3 | * 4 | * Please read the file COPYRIGHT for the 5 | * terms and conditions of the copyright. 6 | */ 7 | 8 | #include "slirp.h" 9 | 10 | #define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm)) 11 | 12 | static void 13 | ifs_insque(struct mbuf *ifm, struct mbuf *ifmhead) 14 | { 15 | ifm->ifs_next = ifmhead->ifs_next; 16 | ifmhead->ifs_next = ifm; 17 | ifm->ifs_prev = ifmhead; 18 | ifm->ifs_next->ifs_prev = ifm; 19 | } 20 | 21 | static void 22 | ifs_remque(struct mbuf *ifm) 23 | { 24 | ifm->ifs_prev->ifs_next = ifm->ifs_next; 25 | ifm->ifs_next->ifs_prev = ifm->ifs_prev; 26 | } 27 | 28 | void 29 | if_init(Slirp *slirp) 30 | { 31 | slirp->if_fastq.ifq_next = slirp->if_fastq.ifq_prev = &slirp->if_fastq; 32 | slirp->if_batchq.ifq_next = slirp->if_batchq.ifq_prev = &slirp->if_batchq; 33 | slirp->next_m = &slirp->if_batchq; 34 | } 35 | 36 | /* 37 | * if_output: Queue packet into an output queue. 38 | * There are 2 output queue's, if_fastq and if_batchq. 39 | * Each output queue is a doubly linked list of double linked lists 40 | * of mbufs, each list belonging to one "session" (socket). This 41 | * way, we can output packets fairly by sending one packet from each 42 | * session, instead of all the packets from one session, then all packets 43 | * from the next session, etc. Packets on the if_fastq get absolute 44 | * priority, but if one session hogs the link, it gets "downgraded" 45 | * to the batchq until it runs out of packets, then it'll return 46 | * to the fastq (eg. if the user does an ls -alR in a telnet session, 47 | * it'll temporarily get downgraded to the batchq) 48 | */ 49 | void 50 | if_output(struct socket *so, struct mbuf *ifm) 51 | { 52 | Slirp *slirp = ifm->slirp; 53 | struct mbuf *ifq; 54 | int on_fastq = 1; 55 | 56 | DEBUG_CALL("if_output"); 57 | DEBUG_ARG("so = %lx", (long)so); 58 | DEBUG_ARG("ifm = %lx", (long)ifm); 59 | 60 | /* 61 | * First remove the mbuf from m_usedlist, 62 | * since we're gonna use m_next and m_prev ourselves 63 | * XXX Shouldn't need this, gotta change dtom() etc. 64 | */ 65 | if (ifm->m_flags & M_USEDLIST) { 66 | remque(ifm); 67 | ifm->m_flags &= ~M_USEDLIST; 68 | } 69 | 70 | /* 71 | * See if there's already a batchq list for this session. 72 | * This can include an interactive session, which should go on fastq, 73 | * but gets too greedy... hence it'll be downgraded from fastq to batchq. 74 | * We mustn't put this packet back on the fastq (or we'll send it out of order) 75 | * XXX add cache here? 76 | */ 77 | for (ifq = slirp->if_batchq.ifq_prev; ifq != &slirp->if_batchq; 78 | ifq = ifq->ifq_prev) { 79 | if (so == ifq->ifq_so) { 80 | /* A match! */ 81 | ifm->ifq_so = so; 82 | ifs_insque(ifm, ifq->ifs_prev); 83 | goto diddit; 84 | } 85 | } 86 | 87 | /* No match, check which queue to put it on */ 88 | if (so && (so->so_iptos & IPTOS_LOWDELAY)) { 89 | ifq = slirp->if_fastq.ifq_prev; 90 | on_fastq = 1; 91 | /* 92 | * Check if this packet is a part of the last 93 | * packet's session 94 | */ 95 | if (ifq->ifq_so == so) { 96 | ifm->ifq_so = so; 97 | ifs_insque(ifm, ifq->ifs_prev); 98 | goto diddit; 99 | } 100 | } else 101 | ifq = slirp->if_batchq.ifq_prev; 102 | 103 | /* Create a new doubly linked list for this session */ 104 | ifm->ifq_so = so; 105 | ifs_init(ifm); 106 | insque(ifm, ifq); 107 | 108 | diddit: 109 | slirp->if_queued++; 110 | 111 | if (so) { 112 | /* Update *_queued */ 113 | so->so_queued++; 114 | so->so_nqueued++; 115 | /* 116 | * Check if the interactive session should be downgraded to 117 | * the batchq. A session is downgraded if it has queued 6 118 | * packets without pausing, and at least 3 of those packets 119 | * have been sent over the link 120 | * (XXX These are arbitrary numbers, probably not optimal..) 121 | */ 122 | if (on_fastq && ((so->so_nqueued >= 6) && 123 | (so->so_nqueued - so->so_queued) >= 3)) { 124 | 125 | /* Remove from current queue... */ 126 | remque(ifm->ifs_next); 127 | 128 | /* ...And insert in the new. That'll teach ya! */ 129 | insque(ifm->ifs_next, &slirp->if_batchq); 130 | } 131 | } 132 | 133 | #ifndef FULL_BOLT 134 | /* 135 | * This prevents us from malloc()ing too many mbufs 136 | */ 137 | if_start(ifm->slirp); 138 | #endif 139 | } 140 | 141 | /* 142 | * Send a packet 143 | * We choose a packet based on it's position in the output queues; 144 | * If there are packets on the fastq, they are sent FIFO, before 145 | * everything else. Otherwise we choose the first packet from the 146 | * batchq and send it. the next packet chosen will be from the session 147 | * after this one, then the session after that one, and so on.. So, 148 | * for example, if there are 3 ftp session's fighting for bandwidth, 149 | * one packet will be sent from the first session, then one packet 150 | * from the second session, then one packet from the third, then back 151 | * to the first, etc. etc. 152 | */ 153 | void 154 | if_start(Slirp *slirp) 155 | { 156 | struct mbuf *ifm, *ifqt; 157 | 158 | DEBUG_CALL("if_start"); 159 | 160 | if (slirp->if_queued == 0) 161 | return; /* Nothing to do */ 162 | 163 | again: 164 | /* check if we can really output */ 165 | if (!slirp_can_output(slirp->opaque)) 166 | return; 167 | 168 | /* 169 | * See which queue to get next packet from 170 | * If there's something in the fastq, select it immediately 171 | */ 172 | if (slirp->if_fastq.ifq_next != &slirp->if_fastq) { 173 | ifm = slirp->if_fastq.ifq_next; 174 | } else { 175 | /* Nothing on fastq, see if next_m is valid */ 176 | if (slirp->next_m != &slirp->if_batchq) 177 | ifm = slirp->next_m; 178 | else 179 | ifm = slirp->if_batchq.ifq_next; 180 | 181 | /* Set which packet to send on next iteration */ 182 | slirp->next_m = ifm->ifq_next; 183 | } 184 | /* Remove it from the queue */ 185 | ifqt = ifm->ifq_prev; 186 | remque(ifm); 187 | slirp->if_queued--; 188 | 189 | /* If there are more packets for this session, re-queue them */ 190 | if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) { 191 | insque(ifm->ifs_next, ifqt); 192 | ifs_remque(ifm); 193 | } 194 | 195 | /* Update so_queued */ 196 | if (ifm->ifq_so) { 197 | if (--ifm->ifq_so->so_queued == 0) 198 | /* If there's no more queued, reset nqueued */ 199 | ifm->ifq_so->so_nqueued = 0; 200 | } 201 | 202 | /* Encapsulate the packet for sending */ 203 | if_encap(slirp, (uint8_t *)ifm->m_data, ifm->m_len); 204 | 205 | m_free(ifm); 206 | 207 | if (slirp->if_queued) 208 | goto again; 209 | } 210 | -------------------------------------------------------------------------------- /slirp/if.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995 Danny Gasparovski. 3 | * 4 | * Please read the file COPYRIGHT for the 5 | * terms and conditions of the copyright. 6 | */ 7 | 8 | #ifndef _IF_H_ 9 | #define _IF_H_ 10 | 11 | #define IF_COMPRESS 0x01 /* We want compression */ 12 | #define IF_NOCOMPRESS 0x02 /* Do not do compression */ 13 | #define IF_AUTOCOMP 0x04 /* Autodetect (default) */ 14 | #define IF_NOCIDCOMP 0x08 /* CID compression */ 15 | 16 | #define IF_MTU 1500 17 | #define IF_MRU 1500 18 | #define IF_COMP IF_AUTOCOMP /* Flags for compression */ 19 | 20 | /* 2 for alignment, 14 for ethernet, 40 for TCP/IP */ 21 | #define IF_MAXLINKHDR (2 + 14 + 40) 22 | 23 | #define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm)) 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /slirp/ip_icmp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1982, 1986, 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the University nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93 30 | * ip_icmp.h,v 1.4 1995/05/30 08:09:43 rgrimes Exp 31 | */ 32 | 33 | #ifndef _NETINET_IP_ICMP_H_ 34 | #define _NETINET_IP_ICMP_H_ 35 | 36 | /* 37 | * Interface Control Message Protocol Definitions. 38 | * Per RFC 792, September 1981. 39 | */ 40 | 41 | typedef uint32_t n_time; 42 | 43 | /* 44 | * Structure of an icmp header. 45 | */ 46 | struct icmp { 47 | u_char icmp_type; /* type of message, see below */ 48 | u_char icmp_code; /* type sub code */ 49 | u_short icmp_cksum; /* ones complement cksum of struct */ 50 | union { 51 | u_char ih_pptr; /* ICMP_PARAMPROB */ 52 | struct in_addr ih_gwaddr; /* ICMP_REDIRECT */ 53 | struct ih_idseq { 54 | u_short icd_id; 55 | u_short icd_seq; 56 | } ih_idseq; 57 | int ih_void; 58 | 59 | /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */ 60 | struct ih_pmtu { 61 | u_short ipm_void; 62 | u_short ipm_nextmtu; 63 | } ih_pmtu; 64 | } icmp_hun; 65 | #define icmp_pptr icmp_hun.ih_pptr 66 | #define icmp_gwaddr icmp_hun.ih_gwaddr 67 | #define icmp_id icmp_hun.ih_idseq.icd_id 68 | #define icmp_seq icmp_hun.ih_idseq.icd_seq 69 | #define icmp_void icmp_hun.ih_void 70 | #define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void 71 | #define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu 72 | union { 73 | struct id_ts { 74 | n_time its_otime; 75 | n_time its_rtime; 76 | n_time its_ttime; 77 | } id_ts; 78 | struct id_ip { 79 | struct ip idi_ip; 80 | /* options and then 64 bits of data */ 81 | } id_ip; 82 | uint32_t id_mask; 83 | char id_data[1]; 84 | } icmp_dun; 85 | #define icmp_otime icmp_dun.id_ts.its_otime 86 | #define icmp_rtime icmp_dun.id_ts.its_rtime 87 | #define icmp_ttime icmp_dun.id_ts.its_ttime 88 | #define icmp_ip icmp_dun.id_ip.idi_ip 89 | #define icmp_mask icmp_dun.id_mask 90 | #define icmp_data icmp_dun.id_data 91 | }; 92 | 93 | /* 94 | * Lower bounds on packet lengths for various types. 95 | * For the error advice packets must first insure that the 96 | * packet is large enought to contain the returned ip header. 97 | * Only then can we do the check to see if 64 bits of packet 98 | * data have been returned, since we need to check the returned 99 | * ip header length. 100 | */ 101 | #define ICMP_MINLEN 8 /* abs minimum */ 102 | #define ICMP_TSLEN (8 + 3 * sizeof (n_time)) /* timestamp */ 103 | #define ICMP_MASKLEN 12 /* address mask */ 104 | #define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */ 105 | #define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8) 106 | /* N.B.: must separately check that ip_hl >= 5 */ 107 | 108 | /* 109 | * Definition of type and code field values. 110 | */ 111 | #define ICMP_ECHOREPLY 0 /* echo reply */ 112 | #define ICMP_UNREACH 3 /* dest unreachable, codes: */ 113 | #define ICMP_UNREACH_NET 0 /* bad net */ 114 | #define ICMP_UNREACH_HOST 1 /* bad host */ 115 | #define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */ 116 | #define ICMP_UNREACH_PORT 3 /* bad port */ 117 | #define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */ 118 | #define ICMP_UNREACH_SRCFAIL 5 /* src route failed */ 119 | #define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */ 120 | #define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */ 121 | #define ICMP_UNREACH_ISOLATED 8 /* src host isolated */ 122 | #define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */ 123 | #define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */ 124 | #define ICMP_UNREACH_TOSNET 11 /* bad tos for net */ 125 | #define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */ 126 | #define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */ 127 | #define ICMP_REDIRECT 5 /* shorter route, codes: */ 128 | #define ICMP_REDIRECT_NET 0 /* for network */ 129 | #define ICMP_REDIRECT_HOST 1 /* for host */ 130 | #define ICMP_REDIRECT_TOSNET 2 /* for tos and net */ 131 | #define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */ 132 | #define ICMP_ECHO 8 /* echo service */ 133 | #define ICMP_ROUTERADVERT 9 /* router advertisement */ 134 | #define ICMP_ROUTERSOLICIT 10 /* router solicitation */ 135 | #define ICMP_TIMXCEED 11 /* time exceeded, code: */ 136 | #define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */ 137 | #define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */ 138 | #define ICMP_PARAMPROB 12 /* ip header bad */ 139 | #define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */ 140 | #define ICMP_TSTAMP 13 /* timestamp request */ 141 | #define ICMP_TSTAMPREPLY 14 /* timestamp reply */ 142 | #define ICMP_IREQ 15 /* information request */ 143 | #define ICMP_IREQREPLY 16 /* information reply */ 144 | #define ICMP_MASKREQ 17 /* address mask request */ 145 | #define ICMP_MASKREPLY 18 /* address mask reply */ 146 | 147 | #define ICMP_MAXTYPE 18 148 | 149 | #define ICMP_INFOTYPE(type) \ 150 | ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \ 151 | (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \ 152 | (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \ 153 | (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ 154 | (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) 155 | 156 | void icmp_input(struct mbuf *, int); 157 | void icmp_error(struct mbuf *msrc, u_char type, u_char code, int minsize, 158 | const char *message); 159 | void icmp_reflect(struct mbuf *); 160 | 161 | #endif 162 | -------------------------------------------------------------------------------- /slirp/ip_output.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1982, 1986, 1988, 1990, 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the University nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * @(#)ip_output.c 8.3 (Berkeley) 1/21/94 30 | * ip_output.c,v 1.9 1994/11/16 10:17:10 jkh Exp 31 | */ 32 | 33 | /* 34 | * Changes and additions relating to SLiRP are 35 | * Copyright (c) 1995 Danny Gasparovski. 36 | * 37 | * Please read the file COPYRIGHT for the 38 | * terms and conditions of the copyright. 39 | */ 40 | 41 | #include "slirp.h" 42 | 43 | /* Number of packets queued before we start sending 44 | * (to prevent allocing too many mbufs) */ 45 | #define IF_THRESH 10 46 | 47 | /* 48 | * IP output. The packet in mbuf chain m contains a skeletal IP 49 | * header (with len, off, ttl, proto, tos, src, dst). 50 | * The mbuf chain containing the packet will be freed. 51 | * The mbuf opt, if present, will not be freed. 52 | */ 53 | int 54 | ip_output(struct socket *so, struct mbuf *m0) 55 | { 56 | Slirp *slirp = m0->slirp; 57 | register struct ip *ip; 58 | register struct mbuf *m = m0; 59 | register int hlen = sizeof(struct ip ); 60 | int len, off, error = 0; 61 | 62 | DEBUG_CALL("ip_output"); 63 | DEBUG_ARG("so = %lx", (long)so); 64 | DEBUG_ARG("m0 = %lx", (long)m0); 65 | 66 | ip = mtod(m, struct ip *); 67 | /* 68 | * Fill in IP header. 69 | */ 70 | ip->ip_v = IPVERSION; 71 | ip->ip_off &= IP_DF; 72 | ip->ip_id = htons(slirp->ip_id++); 73 | ip->ip_hl = hlen >> 2; 74 | 75 | /* 76 | * If small enough for interface, can just send directly. 77 | */ 78 | if ((uint16_t)ip->ip_len <= IF_MTU) { 79 | ip->ip_len = htons((uint16_t)ip->ip_len); 80 | ip->ip_off = htons((uint16_t)ip->ip_off); 81 | ip->ip_sum = 0; 82 | ip->ip_sum = cksum(m, hlen); 83 | 84 | if_output(so, m); 85 | goto done; 86 | } 87 | 88 | /* 89 | * Too large for interface; fragment if possible. 90 | * Must be able to put at least 8 bytes per fragment. 91 | */ 92 | if (ip->ip_off & IP_DF) { 93 | error = -1; 94 | goto bad; 95 | } 96 | 97 | len = (IF_MTU - hlen) &~ 7; /* ip databytes per packet */ 98 | if (len < 8) { 99 | error = -1; 100 | goto bad; 101 | } 102 | 103 | { 104 | int mhlen, firstlen = len; 105 | struct mbuf **mnext = &m->m_nextpkt; 106 | 107 | /* 108 | * Loop through length of segment after first fragment, 109 | * make new header and copy data of each part and link onto chain. 110 | */ 111 | m0 = m; 112 | mhlen = sizeof (struct ip); 113 | for (off = hlen + len; off < (uint16_t)ip->ip_len; off += len) { 114 | register struct ip *mhip; 115 | m = m_get(slirp); 116 | if (m == NULL) { 117 | error = -1; 118 | goto sendorfree; 119 | } 120 | m->m_data += IF_MAXLINKHDR; 121 | mhip = mtod(m, struct ip *); 122 | *mhip = *ip; 123 | 124 | m->m_len = mhlen; 125 | mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF); 126 | if (ip->ip_off & IP_MF) 127 | mhip->ip_off |= IP_MF; 128 | if (off + len >= (uint16_t)ip->ip_len) 129 | len = (uint16_t)ip->ip_len - off; 130 | else 131 | mhip->ip_off |= IP_MF; 132 | mhip->ip_len = htons((uint16_t)(len + mhlen)); 133 | 134 | if (m_copy(m, m0, off, len) < 0) { 135 | error = -1; 136 | goto sendorfree; 137 | } 138 | 139 | mhip->ip_off = htons((uint16_t)mhip->ip_off); 140 | mhip->ip_sum = 0; 141 | mhip->ip_sum = cksum(m, mhlen); 142 | *mnext = m; 143 | mnext = &m->m_nextpkt; 144 | } 145 | /* 146 | * Update first fragment by trimming what's been copied out 147 | * and updating header, then send each fragment (in order). 148 | */ 149 | m = m0; 150 | m_adj(m, hlen + firstlen - (uint16_t)ip->ip_len); 151 | ip->ip_len = htons((uint16_t)m->m_len); 152 | ip->ip_off = htons((uint16_t)(ip->ip_off | IP_MF)); 153 | ip->ip_sum = 0; 154 | ip->ip_sum = cksum(m, hlen); 155 | sendorfree: 156 | for (m = m0; m; m = m0) { 157 | m0 = m->m_nextpkt; 158 | m->m_nextpkt = NULL; 159 | if (error == 0) 160 | if_output(so, m); 161 | else 162 | m_freem(m); 163 | } 164 | } 165 | 166 | done: 167 | return (error); 168 | 169 | bad: 170 | m_freem(m0); 171 | goto done; 172 | } 173 | -------------------------------------------------------------------------------- /slirp/libslirp.h: -------------------------------------------------------------------------------- 1 | #ifndef _LIBSLIRP_H 2 | #define _LIBSLIRP_H 3 | 4 | #ifdef CONFIG_SLIRP 5 | 6 | #include 7 | 8 | struct Slirp; 9 | typedef struct Slirp Slirp; 10 | 11 | int get_dns_addr(struct in_addr *pdns_addr); 12 | 13 | Slirp *slirp_init(int restricted, struct in_addr vnetwork, 14 | struct in_addr vnetmask, struct in_addr vhost, 15 | const char *vhostname, const char *tftp_path, 16 | const char *bootfile, struct in_addr vdhcp_start, 17 | struct in_addr vnameserver, void *opaque); 18 | void slirp_cleanup(Slirp *slirp); 19 | 20 | void slirp_select_fill(Slirp *slirp, int *pnfds, 21 | fd_set *readfds, fd_set *writefds, fd_set *xfds); 22 | 23 | void slirp_select_poll(Slirp *slirp, 24 | fd_set *readfds, fd_set *writefds, fd_set *xfds, 25 | int select_error); 26 | 27 | void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len); 28 | 29 | /* you must provide the following functions: */ 30 | int slirp_can_output(void *opaque); 31 | void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len); 32 | 33 | int slirp_add_hostfwd(Slirp *slirp, int is_udp, 34 | struct in_addr host_addr, int host_port, 35 | struct in_addr guest_addr, int guest_port); 36 | int slirp_remove_hostfwd(Slirp *slirp, int is_udp, 37 | struct in_addr host_addr, int host_port); 38 | int slirp_add_exec(Slirp *slirp, int do_pty, const void *args, 39 | struct in_addr *guest_addr, int guest_port); 40 | 41 | void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, 42 | int guest_port, const uint8_t *buf, int size); 43 | size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr, 44 | int guest_port); 45 | int slirp_get_time_ms(void); 46 | 47 | #else /* !CONFIG_SLIRP */ 48 | 49 | static inline void slirp_select_fill(int *pnfds, fd_set *readfds, 50 | fd_set *writefds, fd_set *xfds) { } 51 | 52 | static inline void slirp_select_poll(fd_set *readfds, fd_set *writefds, 53 | fd_set *xfds, int select_error) { } 54 | #endif /* !CONFIG_SLIRP */ 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /slirp/main.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995 Danny Gasparovski. 3 | * 4 | * Please read the file COPYRIGHT for the 5 | * terms and conditions of the copyright. 6 | */ 7 | 8 | #ifdef HAVE_SYS_SELECT_H 9 | #include 10 | #endif 11 | 12 | #define TOWRITEMAX 512 13 | 14 | extern int slirp_socket; 15 | extern int slirp_socket_unit; 16 | extern int slirp_socket_port; 17 | extern uint32_t slirp_socket_addr; 18 | extern char *slirp_socket_passwd; 19 | extern int ctty_closed; 20 | 21 | /* 22 | * Get the difference in 2 times from updtim() 23 | * Allow for wraparound times, "just in case" 24 | * x is the greater of the 2 (current time) and y is 25 | * what it's being compared against. 26 | */ 27 | #define TIME_DIFF(x,y) (x)-(y) < 0 ? ~0-(y)+(x) : (x)-(y) 28 | 29 | extern char *slirp_tty; 30 | extern char *exec_shell; 31 | extern u_int curtime; 32 | extern fd_set *global_readfds, *global_writefds, *global_xfds; 33 | extern struct in_addr loopback_addr; 34 | extern char *username; 35 | extern char *socket_path; 36 | extern int towrite_max; 37 | extern int ppp_exit; 38 | extern int tcp_keepintvl; 39 | 40 | #define PROTO_SLIP 0x1 41 | #ifdef USE_PPP 42 | #define PROTO_PPP 0x2 43 | #endif 44 | 45 | void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len); 46 | ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags); 47 | -------------------------------------------------------------------------------- /slirp/mbuf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995 Danny Gasparovski 3 | * 4 | * Please read the file COPYRIGHT for the 5 | * terms and conditions of the copyright. 6 | */ 7 | 8 | /* 9 | * mbuf's in SLiRP are much simpler than the real mbufs in 10 | * FreeBSD. They are fixed size, determined by the MTU, 11 | * so that one whole packet can fit. Mbuf's cannot be 12 | * chained together. If there's more data than the mbuf 13 | * could hold, an external malloced buffer is pointed to 14 | * by m_ext (and the data pointers) and M_EXT is set in 15 | * the flags 16 | */ 17 | 18 | #include "slirp.h" 19 | 20 | #define MBUF_THRESH 30 21 | 22 | /* 23 | * Find a nice value for msize 24 | * XXX if_maxlinkhdr already in mtu 25 | */ 26 | #define SLIRP_MSIZE (IF_MTU + IF_MAXLINKHDR + offsetof(struct mbuf, m_dat) + 6) 27 | 28 | void 29 | m_init(Slirp *slirp) 30 | { 31 | slirp->m_freelist.m_next = slirp->m_freelist.m_prev = &slirp->m_freelist; 32 | slirp->m_usedlist.m_next = slirp->m_usedlist.m_prev = &slirp->m_usedlist; 33 | } 34 | 35 | /* 36 | * Get an mbuf from the free list, if there are none 37 | * malloc one 38 | * 39 | * Because fragmentation can occur if we alloc new mbufs and 40 | * free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE, 41 | * which tells m_free to actually free() it 42 | */ 43 | struct mbuf * 44 | m_get(Slirp *slirp) 45 | { 46 | register struct mbuf *m; 47 | int flags = 0; 48 | 49 | DEBUG_CALL("m_get"); 50 | 51 | if (slirp->m_freelist.m_next == &slirp->m_freelist) { 52 | m = (struct mbuf *)malloc(SLIRP_MSIZE); 53 | if (m == NULL) goto end_error; 54 | slirp->mbuf_alloced++; 55 | if (slirp->mbuf_alloced > MBUF_THRESH) 56 | flags = M_DOFREE; 57 | m->slirp = slirp; 58 | } else { 59 | m = slirp->m_freelist.m_next; 60 | remque(m); 61 | } 62 | 63 | /* Insert it in the used list */ 64 | insque(m,&slirp->m_usedlist); 65 | m->m_flags = (flags | M_USEDLIST); 66 | 67 | /* Initialise it */ 68 | m->m_size = SLIRP_MSIZE - offsetof(struct mbuf, m_dat); 69 | m->m_data = m->m_dat; 70 | m->m_len = 0; 71 | m->m_nextpkt = NULL; 72 | m->m_prevpkt = NULL; 73 | end_error: 74 | DEBUG_ARG("m = %lx", (long )m); 75 | return m; 76 | } 77 | 78 | void 79 | m_free(struct mbuf *m) 80 | { 81 | 82 | DEBUG_CALL("m_free"); 83 | DEBUG_ARG("m = %lx", (long )m); 84 | 85 | if(m) { 86 | /* Remove from m_usedlist */ 87 | if (m->m_flags & M_USEDLIST) 88 | remque(m); 89 | 90 | /* If it's M_EXT, free() it */ 91 | if (m->m_flags & M_EXT) 92 | free(m->m_ext); 93 | 94 | /* 95 | * Either free() it or put it on the free list 96 | */ 97 | if (m->m_flags & M_DOFREE) { 98 | m->slirp->mbuf_alloced--; 99 | free(m); 100 | } else if ((m->m_flags & M_FREELIST) == 0) { 101 | insque(m,&m->slirp->m_freelist); 102 | m->m_flags = M_FREELIST; /* Clobber other flags */ 103 | } 104 | } /* if(m) */ 105 | } 106 | 107 | /* 108 | * Copy data from one mbuf to the end of 109 | * the other.. if result is too big for one mbuf, malloc() 110 | * an M_EXT data segment 111 | */ 112 | void 113 | m_cat(struct mbuf *m, struct mbuf *n) 114 | { 115 | /* 116 | * If there's no room, realloc 117 | */ 118 | if (M_FREEROOM(m) < n->m_len) 119 | m_inc(m,m->m_size+MINCSIZE); 120 | 121 | memcpy(m->m_data+m->m_len, n->m_data, n->m_len); 122 | m->m_len += n->m_len; 123 | 124 | m_free(n); 125 | } 126 | 127 | 128 | /* make m size bytes large */ 129 | void 130 | m_inc(struct mbuf *m, int size) 131 | { 132 | int datasize; 133 | 134 | /* some compiles throw up on gotos. This one we can fake. */ 135 | if(m->m_size>size) return; 136 | 137 | if (m->m_flags & M_EXT) { 138 | datasize = m->m_data - m->m_ext; 139 | m->m_ext = (char *)realloc(m->m_ext,size); 140 | m->m_data = m->m_ext + datasize; 141 | } else { 142 | char *dat; 143 | datasize = m->m_data - m->m_dat; 144 | dat = (char *)malloc(size); 145 | memcpy(dat, m->m_dat, m->m_size); 146 | 147 | m->m_ext = dat; 148 | m->m_data = m->m_ext + datasize; 149 | m->m_flags |= M_EXT; 150 | } 151 | 152 | m->m_size = size; 153 | 154 | } 155 | 156 | 157 | 158 | void 159 | m_adj(struct mbuf *m, int len) 160 | { 161 | if (m == NULL) 162 | return; 163 | if (len >= 0) { 164 | /* Trim from head */ 165 | m->m_data += len; 166 | m->m_len -= len; 167 | } else { 168 | /* Trim from tail */ 169 | len = -len; 170 | m->m_len -= len; 171 | } 172 | } 173 | 174 | 175 | /* 176 | * Copy len bytes from m, starting off bytes into n 177 | */ 178 | int 179 | m_copy(struct mbuf *n, struct mbuf *m, int off, int len) 180 | { 181 | if (len > M_FREEROOM(n)) 182 | return -1; 183 | 184 | memcpy((n->m_data + n->m_len), (m->m_data + off), len); 185 | n->m_len += len; 186 | return 0; 187 | } 188 | 189 | 190 | /* 191 | * Given a pointer into an mbuf, return the mbuf 192 | * XXX This is a kludge, I should eliminate the need for it 193 | * Fortunately, it's not used often 194 | */ 195 | struct mbuf * 196 | dtom(Slirp *slirp, void *dat) 197 | { 198 | struct mbuf *m; 199 | 200 | DEBUG_CALL("dtom"); 201 | DEBUG_ARG("dat = %lx", (long )dat); 202 | 203 | /* bug corrected for M_EXT buffers */ 204 | for (m = slirp->m_usedlist.m_next; m != &slirp->m_usedlist; 205 | m = m->m_next) { 206 | if (m->m_flags & M_EXT) { 207 | if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) ) 208 | return m; 209 | } else { 210 | if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) ) 211 | return m; 212 | } 213 | } 214 | 215 | DEBUG_ERROR((dfd, "dtom failed")); 216 | 217 | return (struct mbuf *)0; 218 | } 219 | -------------------------------------------------------------------------------- /slirp/mbuf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1982, 1986, 1988, 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the University nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * @(#)mbuf.h 8.3 (Berkeley) 1/21/94 30 | * mbuf.h,v 1.9 1994/11/14 13:54:20 bde Exp 31 | */ 32 | 33 | #ifndef _MBUF_H_ 34 | #define _MBUF_H_ 35 | 36 | #define m_freem m_free 37 | 38 | 39 | #define MINCSIZE 4096 /* Amount to increase mbuf if too small */ 40 | 41 | /* 42 | * Macros for type conversion 43 | * mtod(m,t) - convert mbuf pointer to data pointer of correct type 44 | */ 45 | #define mtod(m,t) ((t)(m)->m_data) 46 | 47 | /* XXX About mbufs for slirp: 48 | * Only one mbuf is ever used in a chain, for each "cell" of data. 49 | * m_nextpkt points to the next packet, if fragmented. 50 | * If the data is too large, the M_EXT is used, and a larger block 51 | * is alloced. Therefore, m_free[m] must check for M_EXT and if set 52 | * free the m_ext. This is inefficient memory-wise, but who cares. 53 | */ 54 | 55 | /* XXX should union some of these! */ 56 | /* header at beginning of each mbuf: */ 57 | struct m_hdr { 58 | struct mbuf *mh_next; /* Linked list of mbufs */ 59 | struct mbuf *mh_prev; 60 | struct mbuf *mh_nextpkt; /* Next packet in queue/record */ 61 | struct mbuf *mh_prevpkt; /* Flags aren't used in the output queue */ 62 | int mh_flags; /* Misc flags */ 63 | 64 | int mh_size; /* Size of data */ 65 | struct socket *mh_so; 66 | 67 | caddr_t mh_data; /* Location of data */ 68 | int mh_len; /* Amount of data in this mbuf */ 69 | }; 70 | 71 | /* 72 | * How much room is in the mbuf, from m_data to the end of the mbuf 73 | */ 74 | #define M_ROOM(m) ((m->m_flags & M_EXT)? \ 75 | (((m)->m_ext + (m)->m_size) - (m)->m_data) \ 76 | : \ 77 | (((m)->m_dat + (m)->m_size) - (m)->m_data)) 78 | 79 | /* 80 | * How much free room there is 81 | */ 82 | #define M_FREEROOM(m) (M_ROOM(m) - (m)->m_len) 83 | #define M_TRAILINGSPACE M_FREEROOM 84 | 85 | struct mbuf { 86 | struct m_hdr m_hdr; 87 | Slirp *slirp; 88 | union M_dat { 89 | char m_dat_[1]; /* ANSI don't like 0 sized arrays */ 90 | char *m_ext_; 91 | } M_dat; 92 | }; 93 | 94 | #define m_next m_hdr.mh_next 95 | #define m_prev m_hdr.mh_prev 96 | #define m_nextpkt m_hdr.mh_nextpkt 97 | #define m_prevpkt m_hdr.mh_prevpkt 98 | #define m_flags m_hdr.mh_flags 99 | #define m_len m_hdr.mh_len 100 | #define m_data m_hdr.mh_data 101 | #define m_size m_hdr.mh_size 102 | #define m_dat M_dat.m_dat_ 103 | #define m_ext M_dat.m_ext_ 104 | #define m_so m_hdr.mh_so 105 | 106 | #define ifq_prev m_prev 107 | #define ifq_next m_next 108 | #define ifs_prev m_prevpkt 109 | #define ifs_next m_nextpkt 110 | #define ifq_so m_so 111 | 112 | #define M_EXT 0x01 /* m_ext points to more (malloced) data */ 113 | #define M_FREELIST 0x02 /* mbuf is on free list */ 114 | #define M_USEDLIST 0x04 /* XXX mbuf is on used list (for dtom()) */ 115 | #define M_DOFREE 0x08 /* when m_free is called on the mbuf, free() 116 | * it rather than putting it on the free list */ 117 | 118 | void m_init(Slirp *); 119 | struct mbuf * m_get(Slirp *); 120 | void m_free(struct mbuf *); 121 | void m_cat(register struct mbuf *, register struct mbuf *); 122 | void m_inc(struct mbuf *, int); 123 | void m_adj(struct mbuf *, int); 124 | int m_copy(struct mbuf *, struct mbuf *, int, int); 125 | struct mbuf * dtom(Slirp *, void *); 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /slirp/misc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995 Danny Gasparovski. 3 | * 4 | * Please read the file COPYRIGHT for the 5 | * terms and conditions of the copyright. 6 | */ 7 | 8 | #ifndef _MISC_H_ 9 | #define _MISC_H_ 10 | 11 | struct ex_list { 12 | int ex_pty; /* Do we want a pty? */ 13 | struct in_addr ex_addr; /* Server address */ 14 | int ex_fport; /* Port to telnet to */ 15 | const char *ex_exec; /* Command line of what to exec */ 16 | struct ex_list *ex_next; 17 | }; 18 | 19 | #ifndef HAVE_STRDUP 20 | char *strdup(const char *); 21 | #endif 22 | 23 | void do_wait(int); 24 | 25 | #define EMU_NONE 0x0 26 | 27 | /* TCP emulations */ 28 | #define EMU_CTL 0x1 29 | #define EMU_FTP 0x2 30 | #define EMU_KSH 0x3 31 | #define EMU_IRC 0x4 32 | #define EMU_REALAUDIO 0x5 33 | #define EMU_RLOGIN 0x6 34 | #define EMU_IDENT 0x7 35 | #define EMU_RSH 0x8 36 | 37 | #define EMU_NOCONNECT 0x10 /* Don't connect */ 38 | 39 | struct tos_t { 40 | uint16_t lport; 41 | uint16_t fport; 42 | uint8_t tos; 43 | uint8_t emu; 44 | }; 45 | 46 | struct emu_t { 47 | uint16_t lport; 48 | uint16_t fport; 49 | uint8_t tos; 50 | uint8_t emu; 51 | struct emu_t *next; 52 | }; 53 | 54 | extern int x_port, x_server, x_display; 55 | 56 | int show_x(char *, struct socket *); 57 | void redir_x(uint32_t, int, int, int); 58 | void slirp_insque(void *, void *); 59 | void slirp_remque(void *); 60 | int add_exec(struct ex_list **, int, char *, struct in_addr, int); 61 | int slirp_openpty(int *, int *); 62 | int fork_exec(struct socket *so, const char *ex, int do_pty); 63 | void snooze_hup(int); 64 | void snooze(void); 65 | void relay(int); 66 | void add_emu(char *); 67 | void fd_nonblock(int); 68 | void fd_block(int); 69 | int rsh_exec(struct socket *, struct socket *, char *, char *, char *); 70 | int os_socket(int domain, int type, int protocol); 71 | uint32_t os_get_time_ms(void); 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /slirp/sbuf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995 Danny Gasparovski. 3 | * 4 | * Please read the file COPYRIGHT for the 5 | * terms and conditions of the copyright. 6 | */ 7 | 8 | #include "slirp.h" 9 | 10 | static void sbappendsb(struct sbuf *sb, struct mbuf *m); 11 | 12 | void 13 | sbfree(struct sbuf *sb) 14 | { 15 | free(sb->sb_data); 16 | } 17 | 18 | void 19 | sbdrop(struct sbuf *sb, int num) 20 | { 21 | /* 22 | * We can only drop how much we have 23 | * This should never succeed 24 | */ 25 | if(num > sb->sb_cc) 26 | num = sb->sb_cc; 27 | sb->sb_cc -= num; 28 | sb->sb_rptr += num; 29 | if(sb->sb_rptr >= sb->sb_data + sb->sb_datalen) 30 | sb->sb_rptr -= sb->sb_datalen; 31 | 32 | } 33 | 34 | void 35 | sbreserve(struct sbuf *sb, int size) 36 | { 37 | if (sb->sb_data) { 38 | /* Already alloced, realloc if necessary */ 39 | if (sb->sb_datalen != size) { 40 | sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)realloc(sb->sb_data, size); 41 | sb->sb_cc = 0; 42 | if (sb->sb_wptr) 43 | sb->sb_datalen = size; 44 | else 45 | sb->sb_datalen = 0; 46 | } 47 | } else { 48 | sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)malloc(size); 49 | sb->sb_cc = 0; 50 | if (sb->sb_wptr) 51 | sb->sb_datalen = size; 52 | else 53 | sb->sb_datalen = 0; 54 | } 55 | } 56 | 57 | /* 58 | * Try and write() to the socket, whatever doesn't get written 59 | * append to the buffer... for a host with a fast net connection, 60 | * this prevents an unnecessary copy of the data 61 | * (the socket is non-blocking, so we won't hang) 62 | */ 63 | void 64 | sbappend(struct socket *so, struct mbuf *m) 65 | { 66 | int ret = 0; 67 | 68 | DEBUG_CALL("sbappend"); 69 | DEBUG_ARG("so = %lx", (long)so); 70 | DEBUG_ARG("m = %lx", (long)m); 71 | DEBUG_ARG("m->m_len = %d", m->m_len); 72 | 73 | /* Shouldn't happen, but... e.g. foreign host closes connection */ 74 | if (m->m_len <= 0) { 75 | m_free(m); 76 | return; 77 | } 78 | 79 | /* 80 | * If there is urgent data, call sosendoob 81 | * if not all was sent, sowrite will take care of the rest 82 | * (The rest of this function is just an optimisation) 83 | */ 84 | if (so->so_urgc) { 85 | sbappendsb(&so->so_rcv, m); 86 | m_free(m); 87 | sosendoob(so); 88 | return; 89 | } 90 | 91 | /* 92 | * We only write if there's nothing in the buffer, 93 | * ottherwise it'll arrive out of order, and hence corrupt 94 | */ 95 | if (!so->so_rcv.sb_cc) 96 | ret = slirp_send(so, m->m_data, m->m_len, 0); 97 | 98 | if (ret <= 0) { 99 | /* 100 | * Nothing was written 101 | * It's possible that the socket has closed, but 102 | * we don't need to check because if it has closed, 103 | * it will be detected in the normal way by soread() 104 | */ 105 | sbappendsb(&so->so_rcv, m); 106 | } else if (ret != m->m_len) { 107 | /* 108 | * Something was written, but not everything.. 109 | * sbappendsb the rest 110 | */ 111 | m->m_len -= ret; 112 | m->m_data += ret; 113 | sbappendsb(&so->so_rcv, m); 114 | } /* else */ 115 | /* Whatever happened, we free the mbuf */ 116 | m_free(m); 117 | } 118 | 119 | /* 120 | * Copy the data from m into sb 121 | * The caller is responsible to make sure there's enough room 122 | */ 123 | static void 124 | sbappendsb(struct sbuf *sb, struct mbuf *m) 125 | { 126 | int len, n, nn; 127 | 128 | len = m->m_len; 129 | 130 | if (sb->sb_wptr < sb->sb_rptr) { 131 | n = sb->sb_rptr - sb->sb_wptr; 132 | if (n > len) n = len; 133 | memcpy(sb->sb_wptr, m->m_data, n); 134 | } else { 135 | /* Do the right edge first */ 136 | n = sb->sb_data + sb->sb_datalen - sb->sb_wptr; 137 | if (n > len) n = len; 138 | memcpy(sb->sb_wptr, m->m_data, n); 139 | len -= n; 140 | if (len) { 141 | /* Now the left edge */ 142 | nn = sb->sb_rptr - sb->sb_data; 143 | if (nn > len) nn = len; 144 | memcpy(sb->sb_data,m->m_data+n,nn); 145 | n += nn; 146 | } 147 | } 148 | 149 | sb->sb_cc += n; 150 | sb->sb_wptr += n; 151 | if (sb->sb_wptr >= sb->sb_data + sb->sb_datalen) 152 | sb->sb_wptr -= sb->sb_datalen; 153 | } 154 | 155 | /* 156 | * Copy data from sbuf to a normal, straight buffer 157 | * Don't update the sbuf rptr, this will be 158 | * done in sbdrop when the data is acked 159 | */ 160 | void 161 | sbcopy(struct sbuf *sb, int off, int len, char *to) 162 | { 163 | char *from; 164 | 165 | from = sb->sb_rptr + off; 166 | if (from >= sb->sb_data + sb->sb_datalen) 167 | from -= sb->sb_datalen; 168 | 169 | if (from < sb->sb_wptr) { 170 | if (len > sb->sb_cc) len = sb->sb_cc; 171 | memcpy(to,from,len); 172 | } else { 173 | /* re-use off */ 174 | off = (sb->sb_data + sb->sb_datalen) - from; 175 | if (off > len) off = len; 176 | memcpy(to,from,off); 177 | len -= off; 178 | if (len) 179 | memcpy(to+off,sb->sb_data,len); 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /slirp/sbuf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995 Danny Gasparovski. 3 | * 4 | * Please read the file COPYRIGHT for the 5 | * terms and conditions of the copyright. 6 | */ 7 | 8 | #ifndef _SBUF_H_ 9 | #define _SBUF_H_ 10 | 11 | #define sbflush(sb) sbdrop((sb),(sb)->sb_cc) 12 | #define sbspace(sb) ((sb)->sb_datalen - (sb)->sb_cc) 13 | 14 | struct sbuf { 15 | u_int sb_cc; /* actual chars in buffer */ 16 | u_int sb_datalen; /* Length of data */ 17 | char *sb_wptr; /* write pointer. points to where the next 18 | * bytes should be written in the sbuf */ 19 | char *sb_rptr; /* read pointer. points to where the next 20 | * byte should be read from the sbuf */ 21 | char *sb_data; /* Actual data */ 22 | }; 23 | 24 | void sbfree(struct sbuf *); 25 | void sbdrop(struct sbuf *, int); 26 | void sbreserve(struct sbuf *, int); 27 | void sbappend(struct socket *, struct mbuf *); 28 | void sbcopy(struct sbuf *, int, int, char *); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /slirp/slirp.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_H__ 2 | #define __COMMON_H__ 3 | 4 | #include 5 | #include "../cutils.h" 6 | #include "slirp_config.h" 7 | 8 | #ifdef _WIN32 9 | # include 10 | 11 | typedef char *caddr_t; 12 | 13 | # include 14 | # include 15 | # include 16 | # include 17 | # include 18 | 19 | # define EWOULDBLOCK WSAEWOULDBLOCK 20 | # define EINPROGRESS WSAEINPROGRESS 21 | # define ENOTCONN WSAENOTCONN 22 | # define EHOSTUNREACH WSAEHOSTUNREACH 23 | # define ENETUNREACH WSAENETUNREACH 24 | # define ECONNREFUSED WSAECONNREFUSED 25 | #else 26 | # define ioctlsocket ioctl 27 | # define closesocket(s) close(s) 28 | # if !defined(__HAIKU__) 29 | # define O_BINARY 0 30 | # endif 31 | #endif 32 | 33 | #include 34 | #ifdef HAVE_SYS_BITYPES_H 35 | # include 36 | #endif 37 | 38 | #include 39 | 40 | #ifdef HAVE_UNISTD_H 41 | # include 42 | #endif 43 | 44 | #ifdef HAVE_STDLIB_H 45 | # include 46 | #endif 47 | 48 | #include 49 | #include 50 | 51 | #ifndef HAVE_MEMMOVE 52 | #define memmove(x, y, z) bcopy(y, x, z) 53 | #endif 54 | 55 | #if TIME_WITH_SYS_TIME 56 | # include 57 | # include 58 | #else 59 | # ifdef HAVE_SYS_TIME_H 60 | # include 61 | # else 62 | # include 63 | # endif 64 | #endif 65 | 66 | #ifdef HAVE_STRING_H 67 | # include 68 | #else 69 | # include 70 | #endif 71 | 72 | #ifndef _WIN32 73 | #include 74 | #endif 75 | 76 | #ifndef _WIN32 77 | #include 78 | #include 79 | #endif 80 | 81 | /* Systems lacking strdup() definition in . */ 82 | #if defined(ultrix) 83 | char *strdup(const char *); 84 | #endif 85 | 86 | /* Systems lacking malloc() definition in . */ 87 | #if defined(ultrix) || defined(hcx) 88 | void *malloc(size_t arg); 89 | void free(void *ptr); 90 | #endif 91 | 92 | #ifndef HAVE_INET_ATON 93 | int inet_aton(const char *cp, struct in_addr *ia); 94 | #endif 95 | 96 | #include 97 | #ifndef NO_UNIX_SOCKETS 98 | #include 99 | #endif 100 | #include 101 | #ifdef HAVE_SYS_SIGNAL_H 102 | # include 103 | #endif 104 | #ifndef _WIN32 105 | #include 106 | #endif 107 | 108 | #if defined(HAVE_SYS_IOCTL_H) 109 | # include 110 | #endif 111 | 112 | #ifdef HAVE_SYS_SELECT_H 113 | # include 114 | #endif 115 | 116 | #ifdef HAVE_SYS_WAIT_H 117 | # include 118 | #endif 119 | 120 | #ifdef HAVE_SYS_FILIO_H 121 | # include 122 | #endif 123 | 124 | #ifdef USE_PPP 125 | #include 126 | #endif 127 | 128 | #ifdef __STDC__ 129 | #include 130 | #else 131 | #include 132 | #endif 133 | 134 | #include 135 | 136 | /* Avoid conflicting with the libc insque() and remque(), which 137 | have different prototypes. */ 138 | #define insque slirp_insque 139 | #define remque slirp_remque 140 | 141 | #ifdef HAVE_SYS_STROPTS_H 142 | #include 143 | #endif 144 | 145 | #include "debug.h" 146 | 147 | #include "libslirp.h" 148 | #include "ip.h" 149 | #include "tcp.h" 150 | #include "tcp_timer.h" 151 | #include "tcp_var.h" 152 | #include "tcpip.h" 153 | #include "udp.h" 154 | #include "mbuf.h" 155 | #include "sbuf.h" 156 | #include "socket.h" 157 | #include "if.h" 158 | #include "main.h" 159 | #include "misc.h" 160 | #ifdef USE_PPP 161 | #include "ppp/pppd.h" 162 | #include "ppp/ppp.h" 163 | #endif 164 | 165 | #include "bootp.h" 166 | #include "tftp.h" 167 | 168 | struct Slirp { 169 | /* virtual network configuration */ 170 | struct in_addr vnetwork_addr; 171 | struct in_addr vnetwork_mask; 172 | struct in_addr vhost_addr; 173 | struct in_addr vdhcp_startaddr; 174 | struct in_addr vnameserver_addr; 175 | 176 | /* ARP cache for the guest IP addresses (XXX: allow many entries) */ 177 | uint8_t client_ethaddr[6]; 178 | 179 | struct in_addr client_ipaddr; 180 | char client_hostname[33]; 181 | 182 | int restricted; 183 | struct timeval tt; 184 | struct ex_list *exec_list; 185 | 186 | /* mbuf states */ 187 | struct mbuf m_freelist, m_usedlist; 188 | int mbuf_alloced; 189 | 190 | /* if states */ 191 | int if_queued; /* number of packets queued so far */ 192 | struct mbuf if_fastq; /* fast queue (for interactive data) */ 193 | struct mbuf if_batchq; /* queue for non-interactive data */ 194 | struct mbuf *next_m; /* pointer to next mbuf to output */ 195 | 196 | /* ip states */ 197 | struct ipq ipq; /* ip reass. queue */ 198 | uint16_t ip_id; /* ip packet ctr, for ids */ 199 | 200 | /* bootp/dhcp states */ 201 | BOOTPClient bootp_clients[NB_BOOTP_CLIENTS]; 202 | char *bootp_filename; 203 | 204 | /* tcp states */ 205 | struct socket tcb; 206 | struct socket *tcp_last_so; 207 | tcp_seq tcp_iss; /* tcp initial send seq # */ 208 | uint32_t tcp_now; /* for RFC 1323 timestamps */ 209 | 210 | /* udp states */ 211 | struct socket udb; 212 | struct socket *udp_last_so; 213 | 214 | /* tftp states */ 215 | char *tftp_prefix; 216 | struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX]; 217 | 218 | void *opaque; 219 | }; 220 | 221 | extern Slirp *slirp_instance; 222 | 223 | #ifndef NULL 224 | #define NULL (void *)0 225 | #endif 226 | 227 | #ifndef FULL_BOLT 228 | void if_start(Slirp *); 229 | #else 230 | void if_start(struct ttys *); 231 | #endif 232 | 233 | #ifndef HAVE_STRERROR 234 | char *strerror(int error); 235 | #endif 236 | 237 | #ifndef HAVE_INDEX 238 | char *index(const char *, int); 239 | #endif 240 | 241 | #ifndef HAVE_GETHOSTID 242 | long gethostid(void); 243 | #endif 244 | 245 | void lprint(const char *, ...) __attribute__((format(printf, 1, 2))); 246 | 247 | #ifndef _WIN32 248 | #include 249 | #endif 250 | 251 | #define DEFAULT_BAUD 115200 252 | 253 | #define SO_OPTIONS DO_KEEPALIVE 254 | #define TCP_MAXIDLE (TCPTV_KEEPCNT * TCPTV_KEEPINTVL) 255 | 256 | /* cksum.c */ 257 | int cksum(struct mbuf *m, int len); 258 | 259 | /* if.c */ 260 | void if_init(Slirp *); 261 | void if_output(struct socket *, struct mbuf *); 262 | 263 | /* ip_input.c */ 264 | void ip_init(Slirp *); 265 | void ip_input(struct mbuf *); 266 | void ip_slowtimo(Slirp *); 267 | void ip_stripoptions(register struct mbuf *, struct mbuf *); 268 | 269 | /* ip_output.c */ 270 | int ip_output(struct socket *, struct mbuf *); 271 | 272 | /* tcp_input.c */ 273 | void tcp_input(register struct mbuf *, int, struct socket *); 274 | int tcp_mss(register struct tcpcb *, u_int); 275 | 276 | /* tcp_output.c */ 277 | int tcp_output(register struct tcpcb *); 278 | void tcp_setpersist(register struct tcpcb *); 279 | 280 | /* tcp_subr.c */ 281 | void tcp_init(Slirp *); 282 | void tcp_template(struct tcpcb *); 283 | void tcp_respond(struct tcpcb *, register struct tcpiphdr *, register struct mbuf *, tcp_seq, tcp_seq, int); 284 | struct tcpcb * tcp_newtcpcb(struct socket *); 285 | struct tcpcb * tcp_close(register struct tcpcb *); 286 | void tcp_sockclosed(struct tcpcb *); 287 | int tcp_fconnect(struct socket *); 288 | void tcp_connect(struct socket *); 289 | int tcp_attach(struct socket *); 290 | uint8_t tcp_tos(struct socket *); 291 | int tcp_emu(struct socket *, struct mbuf *); 292 | int tcp_ctl(struct socket *); 293 | struct tcpcb *tcp_drop(struct tcpcb *tp, int err); 294 | 295 | #ifdef USE_PPP 296 | #define MIN_MRU MINMRU 297 | #define MAX_MRU MAXMRU 298 | #else 299 | #define MIN_MRU 128 300 | #define MAX_MRU 16384 301 | #endif 302 | 303 | #ifndef _WIN32 304 | #define min(x,y) ((x) < (y) ? (x) : (y)) 305 | #define max(x,y) ((x) > (y) ? (x) : (y)) 306 | #endif 307 | 308 | #ifdef _WIN32 309 | #undef errno 310 | #define errno (WSAGetLastError()) 311 | #endif 312 | 313 | #endif 314 | -------------------------------------------------------------------------------- /slirp/slirp_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * User definable configuration options 3 | */ 4 | 5 | /* Define if you want the connection to be probed */ 6 | /* XXX Not working yet, so ignore this for now */ 7 | #undef PROBE_CONN 8 | 9 | /* Define to 1 if you want KEEPALIVE timers */ 10 | #define DO_KEEPALIVE 0 11 | 12 | /* Define to MAX interfaces you expect to use at once */ 13 | /* MAX_INTERFACES determines the max. TOTAL number of interfaces (SLIP and PPP) */ 14 | /* MAX_PPP_INTERFACES determines max. number of PPP interfaces */ 15 | #define MAX_INTERFACES 1 16 | #define MAX_PPP_INTERFACES 1 17 | 18 | /* Define if you want slirp's socket in /tmp */ 19 | /* XXXXXX Do this in ./configure */ 20 | #undef USE_TMPSOCKET 21 | 22 | /* Define if you want slirp to use cfsetXspeed() on the terminal */ 23 | #undef DO_CFSETSPEED 24 | 25 | /* Define this if you want slirp to write to the tty as fast as it can */ 26 | /* This should only be set if you are using load-balancing, slirp does a */ 27 | /* pretty good job on single modems already, and seting this will make */ 28 | /* interactive sessions less responsive */ 29 | /* XXXXX Talk about having fast modem as unit 0 */ 30 | #undef FULL_BOLT 31 | 32 | /* 33 | * Define if you want slirp to use less CPU 34 | * You will notice a small lag in interactive sessions, but it's not that bad 35 | * Things like Netscape/ftp/etc. are completely unaffected 36 | * This is mainly for sysadmins who have many slirp users 37 | */ 38 | #undef USE_LOWCPU 39 | 40 | /* Define this if your compiler doesn't like prototypes */ 41 | #ifndef __STDC__ 42 | #define NO_PROTOTYPES 43 | #endif 44 | 45 | /*********************************************************/ 46 | /* 47 | * Autoconf defined configuration options 48 | * You shouldn't need to touch any of these 49 | */ 50 | 51 | /* Ignore this */ 52 | #undef DUMMY_PPP 53 | 54 | /* Define if you have unistd.h */ 55 | #define HAVE_UNISTD_H 56 | 57 | /* Define if you have stdlib.h */ 58 | #define HAVE_STDLIB_H 59 | 60 | /* Define if you have sys/ioctl.h */ 61 | #undef HAVE_SYS_IOCTL_H 62 | #ifndef _WIN32 63 | #define HAVE_SYS_IOCTL_H 64 | #endif 65 | 66 | /* Define if you have sys/filio.h */ 67 | #undef HAVE_SYS_FILIO_H 68 | #ifdef __APPLE__ 69 | #define HAVE_SYS_FILIO_H 70 | #endif 71 | 72 | /* Define if you have strerror */ 73 | #define HAVE_STRERROR 74 | 75 | /* Define if you have strdup() */ 76 | #define HAVE_STRDUP 77 | 78 | /* Define according to how time.h should be included */ 79 | #define TIME_WITH_SYS_TIME 0 80 | #undef HAVE_SYS_TIME_H 81 | 82 | /* Define if you have sys/bitypes.h */ 83 | #undef HAVE_SYS_BITYPES_H 84 | 85 | /* Define if the machine is big endian */ 86 | //#undef HOST_WORDS_BIGENDIAN 87 | 88 | /* Define if you have readv */ 89 | #undef HAVE_READV 90 | 91 | /* Define if iovec needs to be declared */ 92 | #undef DECLARE_IOVEC 93 | #ifdef _WIN32 94 | #define DECLARE_IOVEC 95 | #endif 96 | 97 | /* Define if you have a POSIX.1 sys/wait.h */ 98 | #undef HAVE_SYS_WAIT_H 99 | 100 | /* Define if you have sys/select.h */ 101 | #undef HAVE_SYS_SELECT_H 102 | #ifndef _WIN32 103 | #define HAVE_SYS_SELECT_H 104 | #endif 105 | 106 | /* Define if you have strings.h */ 107 | #define HAVE_STRING_H 108 | 109 | /* Define if you have arpa/inet.h */ 110 | #undef HAVE_ARPA_INET_H 111 | #ifndef _WIN32 112 | #define HAVE_ARPA_INET_H 113 | #endif 114 | 115 | /* Define if you have sys/signal.h */ 116 | #undef HAVE_SYS_SIGNAL_H 117 | 118 | /* Define if you have sys/stropts.h */ 119 | #undef HAVE_SYS_STROPTS_H 120 | 121 | /* Define to whatever your compiler thinks inline should be */ 122 | //#define inline inline 123 | 124 | /* Define to whatever your compiler thinks const should be */ 125 | //#define const const 126 | 127 | /* Define if your compiler doesn't like prototypes */ 128 | #undef NO_PROTOTYPES 129 | 130 | /* Define to sizeof(char) */ 131 | #define SIZEOF_CHAR 1 132 | 133 | /* Define to sizeof(short) */ 134 | #define SIZEOF_SHORT 2 135 | 136 | /* Define to sizeof(int) */ 137 | #define SIZEOF_INT 4 138 | 139 | /* Define to sizeof(char *) */ 140 | #define SIZEOF_CHAR_P (HOST_LONG_BITS / 8) 141 | 142 | /* Define if you have random() */ 143 | #undef HAVE_RANDOM 144 | 145 | /* Define if you have srandom() */ 146 | #undef HAVE_SRANDOM 147 | 148 | /* Define if you have inet_aton */ 149 | #undef HAVE_INET_ATON 150 | #ifndef _WIN32 151 | #define HAVE_INET_ATON 152 | #endif 153 | 154 | /* Define if you have setenv */ 155 | #undef HAVE_SETENV 156 | 157 | /* Define if you have index() */ 158 | #define HAVE_INDEX 159 | 160 | /* Define if you have bcmp() */ 161 | #undef HAVE_BCMP 162 | 163 | /* Define if you have drand48 */ 164 | #undef HAVE_DRAND48 165 | 166 | /* Define if you have memmove */ 167 | #define HAVE_MEMMOVE 168 | 169 | /* Define if you have gethostid */ 170 | #define HAVE_GETHOSTID 171 | 172 | /* Define if you DON'T have unix-domain sockets */ 173 | #undef NO_UNIX_SOCKETS 174 | #ifdef _WIN32 175 | #define NO_UNIX_SOCKETS 176 | #endif 177 | 178 | /* Define if you have revoke() */ 179 | #undef HAVE_REVOKE 180 | 181 | /* Define if you have the sysv method of opening pty's (/dev/ptmx, etc.) */ 182 | #undef HAVE_GRANTPT 183 | 184 | /* Define if you have fchmod */ 185 | #undef HAVE_FCHMOD 186 | 187 | /* Define if you have */ 188 | #undef HAVE_SYS_TYPES32_H 189 | -------------------------------------------------------------------------------- /slirp/socket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1995 Danny Gasparovski. 3 | * 4 | * Please read the file COPYRIGHT for the 5 | * terms and conditions of the copyright. 6 | */ 7 | 8 | #ifndef _SLIRP_SOCKET_H_ 9 | #define _SLIRP_SOCKET_H_ 10 | 11 | #define SO_EXPIRE 240000 12 | #define SO_EXPIREFAST 10000 13 | 14 | /* 15 | * Our socket structure 16 | */ 17 | 18 | struct socket { 19 | struct socket *so_next,*so_prev; /* For a linked list of sockets */ 20 | 21 | int s; /* The actual socket */ 22 | 23 | Slirp *slirp; /* managing slirp instance */ 24 | 25 | /* XXX union these with not-yet-used sbuf params */ 26 | struct mbuf *so_m; /* Pointer to the original SYN packet, 27 | * for non-blocking connect()'s, and 28 | * PING reply's */ 29 | struct tcpiphdr *so_ti; /* Pointer to the original ti within 30 | * so_mconn, for non-blocking connections */ 31 | int so_urgc; 32 | struct in_addr so_faddr; /* foreign host table entry */ 33 | struct in_addr so_laddr; /* local host table entry */ 34 | uint16_t so_fport; /* foreign port */ 35 | uint16_t so_lport; /* local port */ 36 | 37 | uint8_t so_iptos; /* Type of service */ 38 | uint8_t so_emu; /* Is the socket emulated? */ 39 | 40 | u_char so_type; /* Type of socket, UDP or TCP */ 41 | int so_state; /* internal state flags SS_*, below */ 42 | 43 | struct tcpcb *so_tcpcb; /* pointer to TCP protocol control block */ 44 | u_int so_expire; /* When the socket will expire */ 45 | 46 | int so_queued; /* Number of packets queued from this socket */ 47 | int so_nqueued; /* Number of packets queued in a row 48 | * Used to determine when to "downgrade" a session 49 | * from fastq to batchq */ 50 | 51 | struct sbuf so_rcv; /* Receive buffer */ 52 | struct sbuf so_snd; /* Send buffer */ 53 | void * extra; /* Extra pointer */ 54 | }; 55 | 56 | 57 | /* 58 | * Socket state bits. (peer means the host on the Internet, 59 | * local host means the host on the other end of the modem) 60 | */ 61 | #define SS_NOFDREF 0x001 /* No fd reference */ 62 | 63 | #define SS_ISFCONNECTING 0x002 /* Socket is connecting to peer (non-blocking connect()'s) */ 64 | #define SS_ISFCONNECTED 0x004 /* Socket is connected to peer */ 65 | #define SS_FCANTRCVMORE 0x008 /* Socket can't receive more from peer (for half-closes) */ 66 | #define SS_FCANTSENDMORE 0x010 /* Socket can't send more to peer (for half-closes) */ 67 | #define SS_FWDRAIN 0x040 /* We received a FIN, drain data and set SS_FCANTSENDMORE */ 68 | 69 | #define SS_CTL 0x080 70 | #define SS_FACCEPTCONN 0x100 /* Socket is accepting connections from a host on the internet */ 71 | #define SS_FACCEPTONCE 0x200 /* If set, the SS_FACCEPTCONN socket will die after one accept */ 72 | 73 | #define SS_PERSISTENT_MASK 0xf000 /* Unremovable state bits */ 74 | #define SS_HOSTFWD 0x1000 /* Socket describes host->guest forwarding */ 75 | #define SS_INCOMING 0x2000 /* Connection was initiated by a host on the internet */ 76 | 77 | struct socket * solookup(struct socket *, struct in_addr, u_int, struct in_addr, u_int); 78 | struct socket * socreate(Slirp *); 79 | void sofree(struct socket *); 80 | int soread(struct socket *); 81 | void sorecvoob(struct socket *); 82 | int sosendoob(struct socket *); 83 | int sowrite(struct socket *); 84 | void sorecvfrom(struct socket *); 85 | int sosendto(struct socket *, struct mbuf *); 86 | struct socket * tcp_listen(Slirp *, uint32_t, u_int, uint32_t, u_int, 87 | int); 88 | void soisfconnecting(register struct socket *); 89 | void soisfconnected(register struct socket *); 90 | void sofwdrain(struct socket *); 91 | struct iovec; /* For win32 */ 92 | size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np); 93 | int soreadbuf(struct socket *so, const char *buf, int size); 94 | 95 | #endif /* _SOCKET_H_ */ 96 | -------------------------------------------------------------------------------- /slirp/tcp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1982, 1986, 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the University nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * @(#)tcp.h 8.1 (Berkeley) 6/10/93 30 | * tcp.h,v 1.3 1994/08/21 05:27:34 paul Exp 31 | */ 32 | 33 | #ifndef _TCP_H_ 34 | #define _TCP_H_ 35 | 36 | typedef uint32_t tcp_seq; 37 | 38 | #define PR_SLOWHZ 2 /* 2 slow timeouts per second (approx) */ 39 | #define PR_FASTHZ 5 /* 5 fast timeouts per second (not important) */ 40 | 41 | #define TCP_SNDSPACE 8192 42 | #define TCP_RCVSPACE 8192 43 | 44 | /* 45 | * TCP header. 46 | * Per RFC 793, September, 1981. 47 | */ 48 | struct tcphdr { 49 | uint16_t th_sport; /* source port */ 50 | uint16_t th_dport; /* destination port */ 51 | tcp_seq th_seq; /* sequence number */ 52 | tcp_seq th_ack; /* acknowledgement number */ 53 | #ifdef HOST_WORDS_BIGENDIAN 54 | u_int th_off:4, /* data offset */ 55 | th_x2:4; /* (unused) */ 56 | #else 57 | u_int th_x2:4, /* (unused) */ 58 | th_off:4; /* data offset */ 59 | #endif 60 | uint8_t th_flags; 61 | #define TH_FIN 0x01 62 | #define TH_SYN 0x02 63 | #define TH_RST 0x04 64 | #define TH_PUSH 0x08 65 | #define TH_ACK 0x10 66 | #define TH_URG 0x20 67 | uint16_t th_win; /* window */ 68 | uint16_t th_sum; /* checksum */ 69 | uint16_t th_urp; /* urgent pointer */ 70 | }; 71 | 72 | #include "tcp_var.h" 73 | 74 | #define TCPOPT_EOL 0 75 | #define TCPOPT_NOP 1 76 | #define TCPOPT_MAXSEG 2 77 | #define TCPOLEN_MAXSEG 4 78 | #define TCPOPT_WINDOW 3 79 | #define TCPOLEN_WINDOW 3 80 | #define TCPOPT_SACK_PERMITTED 4 /* Experimental */ 81 | #define TCPOLEN_SACK_PERMITTED 2 82 | #define TCPOPT_SACK 5 /* Experimental */ 83 | #define TCPOPT_TIMESTAMP 8 84 | #define TCPOLEN_TIMESTAMP 10 85 | #define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */ 86 | 87 | #define TCPOPT_TSTAMP_HDR \ 88 | (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP) 89 | 90 | /* 91 | * Default maximum segment size for TCP. 92 | * With an IP MSS of 576, this is 536, 93 | * but 512 is probably more convenient. 94 | * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)). 95 | * 96 | * We make this 1460 because we only care about Ethernet in the qemu context. 97 | */ 98 | #define TCP_MSS 1460 99 | 100 | #define TCP_MAXWIN 65535 /* largest value for (unscaled) window */ 101 | 102 | #define TCP_MAX_WINSHIFT 14 /* maximum window shift */ 103 | 104 | /* 105 | * User-settable options (used with setsockopt). 106 | * 107 | * We don't use the system headers on unix because we have conflicting 108 | * local structures. We can't avoid the system definitions on Windows, 109 | * so we undefine them. 110 | */ 111 | #undef TCP_NODELAY 112 | #define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ 113 | #undef TCP_MAXSEG 114 | 115 | /* 116 | * TCP FSM state definitions. 117 | * Per RFC793, September, 1981. 118 | */ 119 | 120 | #define TCP_NSTATES 11 121 | 122 | #define TCPS_CLOSED 0 /* closed */ 123 | #define TCPS_LISTEN 1 /* listening for connection */ 124 | #define TCPS_SYN_SENT 2 /* active, have sent syn */ 125 | #define TCPS_SYN_RECEIVED 3 /* have send and received syn */ 126 | /* states < TCPS_ESTABLISHED are those where connections not established */ 127 | #define TCPS_ESTABLISHED 4 /* established */ 128 | #define TCPS_CLOSE_WAIT 5 /* rcvd fin, waiting for close */ 129 | /* states > TCPS_CLOSE_WAIT are those where user has closed */ 130 | #define TCPS_FIN_WAIT_1 6 /* have closed, sent fin */ 131 | #define TCPS_CLOSING 7 /* closed xchd FIN; await FIN ACK */ 132 | #define TCPS_LAST_ACK 8 /* had fin and close; await FIN ACK */ 133 | /* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */ 134 | #define TCPS_FIN_WAIT_2 9 /* have closed, fin is acked */ 135 | #define TCPS_TIME_WAIT 10 /* in 2*msl quiet wait after close */ 136 | 137 | #define TCPS_HAVERCVDSYN(s) ((s) >= TCPS_SYN_RECEIVED) 138 | #define TCPS_HAVEESTABLISHED(s) ((s) >= TCPS_ESTABLISHED) 139 | #define TCPS_HAVERCVDFIN(s) ((s) >= TCPS_TIME_WAIT) 140 | 141 | /* 142 | * TCP sequence numbers are 32 bit integers operated 143 | * on with modular arithmetic. These macros can be 144 | * used to compare such integers. 145 | */ 146 | #define SEQ_LT(a,b) ((int)((a)-(b)) < 0) 147 | #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) 148 | #define SEQ_GT(a,b) ((int)((a)-(b)) > 0) 149 | #define SEQ_GEQ(a,b) ((int)((a)-(b)) >= 0) 150 | 151 | /* 152 | * Macros to initialize tcp sequence numbers for 153 | * send and receive from initial send and receive 154 | * sequence numbers. 155 | */ 156 | #define tcp_rcvseqinit(tp) \ 157 | (tp)->rcv_adv = (tp)->rcv_nxt = (tp)->irs + 1 158 | 159 | #define tcp_sendseqinit(tp) \ 160 | (tp)->snd_una = (tp)->snd_nxt = (tp)->snd_max = (tp)->snd_up = (tp)->iss 161 | 162 | #define TCP_ISSINCR (125*1024) /* increment for tcp_iss each second */ 163 | 164 | #endif 165 | -------------------------------------------------------------------------------- /slirp/tcp_timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1982, 1986, 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the University nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * @(#)tcp_timer.h 8.1 (Berkeley) 6/10/93 30 | * tcp_timer.h,v 1.4 1994/08/21 05:27:38 paul Exp 31 | */ 32 | 33 | #ifndef _TCP_TIMER_H_ 34 | #define _TCP_TIMER_H_ 35 | 36 | /* 37 | * Definitions of the TCP timers. These timers are counted 38 | * down PR_SLOWHZ times a second. 39 | */ 40 | #define TCPT_NTIMERS 4 41 | 42 | #define TCPT_REXMT 0 /* retransmit */ 43 | #define TCPT_PERSIST 1 /* retransmit persistence */ 44 | #define TCPT_KEEP 2 /* keep alive */ 45 | #define TCPT_2MSL 3 /* 2*msl quiet time timer */ 46 | 47 | /* 48 | * The TCPT_REXMT timer is used to force retransmissions. 49 | * The TCP has the TCPT_REXMT timer set whenever segments 50 | * have been sent for which ACKs are expected but not yet 51 | * received. If an ACK is received which advances tp->snd_una, 52 | * then the retransmit timer is cleared (if there are no more 53 | * outstanding segments) or reset to the base value (if there 54 | * are more ACKs expected). Whenever the retransmit timer goes off, 55 | * we retransmit one unacknowledged segment, and do a backoff 56 | * on the retransmit timer. 57 | * 58 | * The TCPT_PERSIST timer is used to keep window size information 59 | * flowing even if the window goes shut. If all previous transmissions 60 | * have been acknowledged (so that there are no retransmissions in progress), 61 | * and the window is too small to bother sending anything, then we start 62 | * the TCPT_PERSIST timer. When it expires, if the window is nonzero, 63 | * we go to transmit state. Otherwise, at intervals send a single byte 64 | * into the peer's window to force him to update our window information. 65 | * We do this at most as often as TCPT_PERSMIN time intervals, 66 | * but no more frequently than the current estimate of round-trip 67 | * packet time. The TCPT_PERSIST timer is cleared whenever we receive 68 | * a window update from the peer. 69 | * 70 | * The TCPT_KEEP timer is used to keep connections alive. If an 71 | * connection is idle (no segments received) for TCPTV_KEEP_INIT amount of time, 72 | * but not yet established, then we drop the connection. Once the connection 73 | * is established, if the connection is idle for TCPTV_KEEP_IDLE time 74 | * (and keepalives have been enabled on the socket), we begin to probe 75 | * the connection. We force the peer to send us a segment by sending: 76 | * 77 | * This segment is (deliberately) outside the window, and should elicit 78 | * an ack segment in response from the peer. If, despite the TCPT_KEEP 79 | * initiated segments we cannot elicit a response from a peer in TCPT_MAXIDLE 80 | * amount of time probing, then we drop the connection. 81 | */ 82 | 83 | /* 84 | * Time constants. 85 | */ 86 | #define TCPTV_MSL ( 5*PR_SLOWHZ) /* max seg lifetime (hah!) */ 87 | 88 | #define TCPTV_SRTTBASE 0 /* base roundtrip time; 89 | if 0, no idea yet */ 90 | #define TCPTV_SRTTDFLT ( 3*PR_SLOWHZ) /* assumed RTT if no info */ 91 | 92 | #define TCPTV_PERSMIN ( 5*PR_SLOWHZ) /* retransmit persistence */ 93 | #define TCPTV_PERSMAX ( 60*PR_SLOWHZ) /* maximum persist interval */ 94 | 95 | #define TCPTV_KEEP_INIT ( 75*PR_SLOWHZ) /* initial connect keep alive */ 96 | #define TCPTV_KEEP_IDLE (120*60*PR_SLOWHZ) /* dflt time before probing */ 97 | #define TCPTV_KEEPINTVL ( 75*PR_SLOWHZ) /* default probe interval */ 98 | #define TCPTV_KEEPCNT 8 /* max probes before drop */ 99 | 100 | #define TCPTV_MIN ( 1*PR_SLOWHZ) /* minimum allowable value */ 101 | #define TCPTV_REXMTMAX ( 12*PR_SLOWHZ) /* max allowable REXMT value */ 102 | 103 | #define TCP_LINGERTIME 120 /* linger at most 2 minutes */ 104 | 105 | #define TCP_MAXRXTSHIFT 12 /* maximum retransmits */ 106 | 107 | 108 | /* 109 | * Force a time value to be in a certain range. 110 | */ 111 | #define TCPT_RANGESET(tv, value, tvmin, tvmax) { \ 112 | (tv) = (value); \ 113 | if ((tv) < (tvmin)) \ 114 | (tv) = (tvmin); \ 115 | else if ((tv) > (tvmax)) \ 116 | (tv) = (tvmax); \ 117 | } 118 | 119 | extern const int tcp_backoff[]; 120 | 121 | struct tcpcb; 122 | 123 | void tcp_fasttimo(Slirp *); 124 | void tcp_slowtimo(Slirp *); 125 | void tcp_canceltimers(struct tcpcb *); 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /slirp/tcp_var.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1982, 1986, 1993, 1994 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the University nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * @(#)tcp_var.h 8.3 (Berkeley) 4/10/94 30 | * tcp_var.h,v 1.3 1994/08/21 05:27:39 paul Exp 31 | */ 32 | 33 | #ifndef _TCP_VAR_H_ 34 | #define _TCP_VAR_H_ 35 | 36 | #include "tcpip.h" 37 | #include "tcp_timer.h" 38 | 39 | /* 40 | * Tcp control block, one per tcp; fields: 41 | */ 42 | struct tcpcb { 43 | struct tcpiphdr *seg_next; /* sequencing queue */ 44 | struct tcpiphdr *seg_prev; 45 | short t_state; /* state of this connection */ 46 | short t_timer[TCPT_NTIMERS]; /* tcp timers */ 47 | short t_rxtshift; /* log(2) of rexmt exp. backoff */ 48 | short t_rxtcur; /* current retransmit value */ 49 | short t_dupacks; /* consecutive dup acks recd */ 50 | u_short t_maxseg; /* maximum segment size */ 51 | char t_force; /* 1 if forcing out a byte */ 52 | u_short t_flags; 53 | #define TF_ACKNOW 0x0001 /* ack peer immediately */ 54 | #define TF_DELACK 0x0002 /* ack, but try to delay it */ 55 | #define TF_NODELAY 0x0004 /* don't delay packets to coalesce */ 56 | #define TF_NOOPT 0x0008 /* don't use tcp options */ 57 | #define TF_SENTFIN 0x0010 /* have sent FIN */ 58 | #define TF_REQ_SCALE 0x0020 /* have/will request window scaling */ 59 | #define TF_RCVD_SCALE 0x0040 /* other side has requested scaling */ 60 | #define TF_REQ_TSTMP 0x0080 /* have/will request timestamps */ 61 | #define TF_RCVD_TSTMP 0x0100 /* a timestamp was received in SYN */ 62 | #define TF_SACK_PERMIT 0x0200 /* other side said I could SACK */ 63 | 64 | struct tcpiphdr t_template; /* static skeletal packet for xmit */ 65 | 66 | struct socket *t_socket; /* back pointer to socket */ 67 | /* 68 | * The following fields are used as in the protocol specification. 69 | * See RFC783, Dec. 1981, page 21. 70 | */ 71 | /* send sequence variables */ 72 | tcp_seq snd_una; /* send unacknowledged */ 73 | tcp_seq snd_nxt; /* send next */ 74 | tcp_seq snd_up; /* send urgent pointer */ 75 | tcp_seq snd_wl1; /* window update seg seq number */ 76 | tcp_seq snd_wl2; /* window update seg ack number */ 77 | tcp_seq iss; /* initial send sequence number */ 78 | uint32_t snd_wnd; /* send window */ 79 | /* receive sequence variables */ 80 | uint32_t rcv_wnd; /* receive window */ 81 | tcp_seq rcv_nxt; /* receive next */ 82 | tcp_seq rcv_up; /* receive urgent pointer */ 83 | tcp_seq irs; /* initial receive sequence number */ 84 | /* 85 | * Additional variables for this implementation. 86 | */ 87 | /* receive variables */ 88 | tcp_seq rcv_adv; /* advertised window */ 89 | /* retransmit variables */ 90 | tcp_seq snd_max; /* highest sequence number sent; 91 | * used to recognize retransmits 92 | */ 93 | /* congestion control (for slow start, source quench, retransmit after loss) */ 94 | uint32_t snd_cwnd; /* congestion-controlled window */ 95 | uint32_t snd_ssthresh; /* snd_cwnd size threshold for 96 | * for slow start exponential to 97 | * linear switch 98 | */ 99 | /* 100 | * transmit timing stuff. See below for scale of srtt and rttvar. 101 | * "Variance" is actually smoothed difference. 102 | */ 103 | short t_idle; /* inactivity time */ 104 | short t_rtt; /* round trip time */ 105 | tcp_seq t_rtseq; /* sequence number being timed */ 106 | short t_srtt; /* smoothed round-trip time */ 107 | short t_rttvar; /* variance in round-trip time */ 108 | u_short t_rttmin; /* minimum rtt allowed */ 109 | uint32_t max_sndwnd; /* largest window peer has offered */ 110 | 111 | /* out-of-band data */ 112 | char t_oobflags; /* have some */ 113 | char t_iobc; /* input character */ 114 | #define TCPOOB_HAVEDATA 0x01 115 | #define TCPOOB_HADDATA 0x02 116 | short t_softerror; /* possible error not yet reported */ 117 | 118 | /* RFC 1323 variables */ 119 | u_char snd_scale; /* window scaling for send window */ 120 | u_char rcv_scale; /* window scaling for recv window */ 121 | u_char request_r_scale; /* pending window scaling */ 122 | u_char requested_s_scale; 123 | uint32_t ts_recent; /* timestamp echo data */ 124 | uint32_t ts_recent_age; /* when last updated */ 125 | tcp_seq last_ack_sent; 126 | 127 | }; 128 | 129 | #define sototcpcb(so) ((so)->so_tcpcb) 130 | 131 | /* 132 | * The smoothed round-trip time and estimated variance 133 | * are stored as fixed point numbers scaled by the values below. 134 | * For convenience, these scales are also used in smoothing the average 135 | * (smoothed = (1/scale)sample + ((scale-1)/scale)smoothed). 136 | * With these scales, srtt has 3 bits to the right of the binary point, 137 | * and thus an "ALPHA" of 0.875. rttvar has 2 bits to the right of the 138 | * binary point, and is smoothed with an ALPHA of 0.75. 139 | */ 140 | #define TCP_RTT_SCALE 8 /* multiplier for srtt; 3 bits frac. */ 141 | #define TCP_RTT_SHIFT 3 /* shift for srtt; 3 bits frac. */ 142 | #define TCP_RTTVAR_SCALE 4 /* multiplier for rttvar; 2 bits */ 143 | #define TCP_RTTVAR_SHIFT 2 /* multiplier for rttvar; 2 bits */ 144 | 145 | /* 146 | * The initial retransmission should happen at rtt + 4 * rttvar. 147 | * Because of the way we do the smoothing, srtt and rttvar 148 | * will each average +1/2 tick of bias. When we compute 149 | * the retransmit timer, we want 1/2 tick of rounding and 150 | * 1 extra tick because of +-1/2 tick uncertainty in the 151 | * firing of the timer. The bias will give us exactly the 152 | * 1.5 tick we need. But, because the bias is 153 | * statistical, we have to test that we don't drop below 154 | * the minimum feasible timer (which is 2 ticks). 155 | * This macro assumes that the value of TCP_RTTVAR_SCALE 156 | * is the same as the multiplier for rttvar. 157 | */ 158 | #define TCP_REXMTVAL(tp) \ 159 | (((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar) 160 | 161 | #endif 162 | -------------------------------------------------------------------------------- /slirp/tcpip.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1982, 1986, 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the University nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * @(#)tcpip.h 8.1 (Berkeley) 6/10/93 30 | * tcpip.h,v 1.3 1994/08/21 05:27:40 paul Exp 31 | */ 32 | 33 | #ifndef _TCPIP_H_ 34 | #define _TCPIP_H_ 35 | 36 | /* 37 | * Tcp+ip header, after ip options removed. 38 | */ 39 | struct tcpiphdr { 40 | struct ipovly ti_i; /* overlaid ip structure */ 41 | struct tcphdr ti_t; /* tcp header */ 42 | }; 43 | #define ti_mbuf ti_i.ih_mbuf.mptr 44 | #define ti_x1 ti_i.ih_x1 45 | #define ti_pr ti_i.ih_pr 46 | #define ti_len ti_i.ih_len 47 | #define ti_src ti_i.ih_src 48 | #define ti_dst ti_i.ih_dst 49 | #define ti_sport ti_t.th_sport 50 | #define ti_dport ti_t.th_dport 51 | #define ti_seq ti_t.th_seq 52 | #define ti_ack ti_t.th_ack 53 | #define ti_x2 ti_t.th_x2 54 | #define ti_off ti_t.th_off 55 | #define ti_flags ti_t.th_flags 56 | #define ti_win ti_t.th_win 57 | #define ti_sum ti_t.th_sum 58 | #define ti_urp ti_t.th_urp 59 | 60 | #define tcpiphdr2qlink(T) ((struct qlink*)(((char*)(T)) - sizeof(struct qlink))) 61 | #define qlink2tcpiphdr(Q) ((struct tcpiphdr*)(((char*)(Q)) + sizeof(struct qlink))) 62 | #define tcpiphdr_next(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->next) 63 | #define tcpiphdr_prev(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->prev) 64 | #define tcpfrag_list_first(T) qlink2tcpiphdr((T)->seg_next) 65 | #define tcpfrag_list_end(F, T) (tcpiphdr2qlink(F) == (struct qlink*)(T)) 66 | #define tcpfrag_list_empty(T) ((T)->seg_next == (struct tcpiphdr*)(T)) 67 | 68 | /* 69 | * Just a clean way to get to the first byte 70 | * of the packet 71 | */ 72 | struct tcpiphdr_2 { 73 | struct tcpiphdr dummy; 74 | char first_char; 75 | }; 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /slirp/tftp.h: -------------------------------------------------------------------------------- 1 | /* tftp defines */ 2 | 3 | #define TFTP_SESSIONS_MAX 3 4 | 5 | #define TFTP_SERVER 69 6 | 7 | #define TFTP_RRQ 1 8 | #define TFTP_WRQ 2 9 | #define TFTP_DATA 3 10 | #define TFTP_ACK 4 11 | #define TFTP_ERROR 5 12 | #define TFTP_OACK 6 13 | 14 | #define TFTP_FILENAME_MAX 512 15 | 16 | struct tftp_t { 17 | struct ip ip; 18 | struct udphdr udp; 19 | uint16_t tp_op; 20 | union { 21 | struct { 22 | uint16_t tp_block_nr; 23 | uint8_t tp_buf[512]; 24 | } tp_data; 25 | struct { 26 | uint16_t tp_error_code; 27 | uint8_t tp_msg[512]; 28 | } tp_error; 29 | uint8_t tp_buf[512 + 2]; 30 | } x; 31 | }; 32 | 33 | struct tftp_session { 34 | Slirp *slirp; 35 | char *filename; 36 | 37 | struct in_addr client_ip; 38 | uint16_t client_port; 39 | 40 | int timestamp; 41 | }; 42 | 43 | void tftp_input(struct mbuf *m); 44 | -------------------------------------------------------------------------------- /slirp/udp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1982, 1986, 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the University nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * @(#)udp.h 8.1 (Berkeley) 6/10/93 30 | * udp.h,v 1.3 1994/08/21 05:27:41 paul Exp 31 | */ 32 | 33 | #ifndef _UDP_H_ 34 | #define _UDP_H_ 35 | 36 | #define UDP_TTL 0x60 37 | #define UDP_UDPDATALEN 16192 38 | 39 | /* 40 | * Udp protocol header. 41 | * Per RFC 768, September, 1981. 42 | */ 43 | struct udphdr { 44 | uint16_t uh_sport; /* source port */ 45 | uint16_t uh_dport; /* destination port */ 46 | int16_t uh_ulen; /* udp length */ 47 | uint16_t uh_sum; /* udp checksum */ 48 | }; 49 | 50 | /* 51 | * UDP kernel structures and variables. 52 | */ 53 | struct udpiphdr { 54 | struct ipovly ui_i; /* overlaid ip structure */ 55 | struct udphdr ui_u; /* udp header */ 56 | }; 57 | #define ui_mbuf ui_i.ih_mbuf.mptr 58 | #define ui_x1 ui_i.ih_x1 59 | #define ui_pr ui_i.ih_pr 60 | #define ui_len ui_i.ih_len 61 | #define ui_src ui_i.ih_src 62 | #define ui_dst ui_i.ih_dst 63 | #define ui_sport ui_u.uh_sport 64 | #define ui_dport ui_u.uh_dport 65 | #define ui_ulen ui_u.uh_ulen 66 | #define ui_sum ui_u.uh_sum 67 | 68 | /* 69 | * Names for UDP sysctl objects 70 | */ 71 | #define UDPCTL_CHECKSUM 1 /* checksum UDP packets */ 72 | #define UDPCTL_MAXID 2 73 | 74 | struct mbuf; 75 | 76 | void udp_init(Slirp *); 77 | void udp_input(register struct mbuf *, int); 78 | int udp_output(struct socket *, struct mbuf *, struct sockaddr_in *); 79 | int udp_attach(struct socket *); 80 | void udp_detach(struct socket *); 81 | struct socket * udp_listen(Slirp *, uint32_t, u_int, uint32_t, u_int, 82 | int); 83 | int udp_output2(struct socket *so, struct mbuf *m, 84 | struct sockaddr_in *saddr, struct sockaddr_in *daddr, 85 | int iptos); 86 | #endif 87 | -------------------------------------------------------------------------------- /softfp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SoftFP Library 3 | * 4 | * Copyright (c) 2016 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "cutils.h" 30 | #include "softfp.h" 31 | 32 | static inline int clz32(uint32_t a) 33 | { 34 | int r; 35 | if (a == 0) { 36 | r = 32; 37 | } else { 38 | r = __builtin_clz(a); 39 | } 40 | return r; 41 | } 42 | 43 | static inline int clz64(uint64_t a) 44 | { 45 | int r; 46 | if (a == 0) { 47 | r = 64; 48 | } else 49 | { 50 | r = __builtin_clzll(a); 51 | } 52 | return r; 53 | } 54 | 55 | #ifdef HAVE_INT128 56 | static inline int clz128(uint128_t a) 57 | { 58 | int r; 59 | if (a == 0) { 60 | r = 128; 61 | } else 62 | { 63 | uint64_t ah, al; 64 | ah = a >> 64; 65 | al = a; 66 | if (ah != 0) 67 | r = __builtin_clzll(ah); 68 | else 69 | r = __builtin_clzll(al) + 64; 70 | } 71 | return r; 72 | } 73 | #endif 74 | 75 | #define F_SIZE 32 76 | #include "softfp_template.h" 77 | 78 | #define F_SIZE 64 79 | #include "softfp_template.h" 80 | 81 | #ifdef HAVE_INT128 82 | 83 | #define F_SIZE 128 84 | #include "softfp_template.h" 85 | 86 | #endif 87 | 88 | -------------------------------------------------------------------------------- /softfp_template_icvt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SoftFP Library 3 | * 4 | * Copyright (c) 2016 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #if ICVT_SIZE == 32 25 | #define ICVT_UINT uint32_t 26 | #define ICVT_INT int32_t 27 | #elif ICVT_SIZE == 64 28 | #define ICVT_UINT uint64_t 29 | #define ICVT_INT int64_t 30 | #elif ICVT_SIZE == 128 31 | #define ICVT_UINT uint128_t 32 | #define ICVT_INT int128_t 33 | #else 34 | #error unsupported icvt 35 | #endif 36 | 37 | /* conversions between float and integers */ 38 | static ICVT_INT glue(glue(glue(internal_cvt_sf, F_SIZE), _i), ICVT_SIZE)(F_UINT a, RoundingModeEnum rm, 39 | uint32_t *pfflags, BOOL is_unsigned) 40 | { 41 | uint32_t a_sign, addend, rnd_bits; 42 | int32_t a_exp; 43 | F_UINT a_mant; 44 | ICVT_UINT r, r_max; 45 | 46 | a_sign = a >> (F_SIZE - 1); 47 | a_exp = (a >> MANT_SIZE) & EXP_MASK; 48 | a_mant = a & MANT_MASK; 49 | if (a_exp == EXP_MASK && a_mant != 0) 50 | a_sign = 0; /* NaN is like +infinity */ 51 | if (a_exp == 0) { 52 | a_exp = 1; 53 | } else { 54 | a_mant |= (F_UINT)1 << MANT_SIZE; 55 | } 56 | a_mant <<= RND_SIZE; 57 | a_exp = a_exp - (EXP_MASK / 2) - MANT_SIZE; 58 | 59 | if (is_unsigned) 60 | r_max = (ICVT_UINT)a_sign - 1; 61 | else 62 | r_max = ((ICVT_UINT)1 << (ICVT_SIZE - 1)) - (ICVT_UINT)(a_sign ^ 1); 63 | if (a_exp >= 0) { 64 | if (a_exp <= (ICVT_SIZE - 1 - MANT_SIZE)) { 65 | r = (ICVT_UINT)(a_mant >> RND_SIZE) << a_exp; 66 | if (r > r_max) 67 | goto overflow; 68 | } else { 69 | overflow: 70 | *pfflags |= FFLAG_INVALID_OP; 71 | return r_max; 72 | } 73 | } else { 74 | a_mant = rshift_rnd(a_mant, -a_exp); 75 | 76 | switch(rm) { 77 | case RM_RNE: 78 | case RM_RMM: 79 | addend = (1 << (RND_SIZE - 1)); 80 | break; 81 | case RM_RTZ: 82 | addend = 0; 83 | break; 84 | default: 85 | case RM_RDN: 86 | case RM_RUP: 87 | if (a_sign ^ (rm & 1)) 88 | addend = (1 << RND_SIZE) - 1; 89 | else 90 | addend = 0; 91 | break; 92 | } 93 | 94 | rnd_bits = a_mant & ((1 << RND_SIZE ) - 1); 95 | a_mant = (a_mant + addend) >> RND_SIZE; 96 | /* half way: select even result */ 97 | if (rm == RM_RNE && rnd_bits == (1 << (RND_SIZE - 1))) 98 | a_mant &= ~1; 99 | if (a_mant > r_max) 100 | goto overflow; 101 | r = a_mant; 102 | if (rnd_bits != 0) 103 | *pfflags |= FFLAG_INEXACT; 104 | } 105 | if (a_sign) 106 | r = -r; 107 | return r; 108 | } 109 | 110 | ICVT_INT glue(glue(glue(cvt_sf, F_SIZE), _i), ICVT_SIZE)(F_UINT a, RoundingModeEnum rm, 111 | uint32_t *pfflags) 112 | { 113 | return glue(glue(glue(internal_cvt_sf, F_SIZE), _i), ICVT_SIZE)(a, rm, 114 | pfflags, FALSE); 115 | } 116 | 117 | ICVT_UINT glue(glue(glue(cvt_sf, F_SIZE), _u), ICVT_SIZE)(F_UINT a, RoundingModeEnum rm, 118 | uint32_t *pfflags) 119 | { 120 | return glue(glue(glue(internal_cvt_sf, F_SIZE), _i), ICVT_SIZE) (a, rm, 121 | pfflags, TRUE); 122 | } 123 | 124 | /* conversions between float and integers */ 125 | static F_UINT glue(glue(glue(internal_cvt_i, ICVT_SIZE), _sf), F_SIZE)(ICVT_INT a, 126 | RoundingModeEnum rm, 127 | uint32_t *pfflags, 128 | BOOL is_unsigned) 129 | { 130 | uint32_t a_sign; 131 | int32_t a_exp; 132 | F_UINT a_mant; 133 | ICVT_UINT r, mask; 134 | int l; 135 | 136 | if (!is_unsigned && a < 0) { 137 | a_sign = 1; 138 | r = -(ICVT_UINT)a; 139 | } else { 140 | a_sign = 0; 141 | r = a; 142 | } 143 | a_exp = (EXP_MASK / 2) + F_SIZE - 2; 144 | /* need to reduce range before generic float normalization */ 145 | l = ICVT_SIZE - glue(clz, ICVT_SIZE)(r) - (F_SIZE - 1); 146 | if (l > 0) { 147 | mask = r & (((ICVT_UINT)1 << l) - 1); 148 | r = (r >> l) | ((r & mask) != 0); 149 | a_exp += l; 150 | } 151 | a_mant = r; 152 | return normalize_sf(a_sign, a_exp, a_mant, rm, pfflags); 153 | } 154 | 155 | F_UINT glue(glue(glue(cvt_i, ICVT_SIZE), _sf), F_SIZE)(ICVT_INT a, 156 | RoundingModeEnum rm, 157 | uint32_t *pfflags) 158 | { 159 | return glue(glue(glue(internal_cvt_i, ICVT_SIZE), _sf), F_SIZE)(a, rm, pfflags, FALSE); 160 | } 161 | 162 | F_UINT glue(glue(glue(cvt_u, ICVT_SIZE), _sf), F_SIZE)(ICVT_UINT a, 163 | RoundingModeEnum rm, 164 | uint32_t *pfflags) 165 | { 166 | return glue(glue(glue(internal_cvt_i, ICVT_SIZE), _sf), F_SIZE)(a, rm, pfflags, TRUE); 167 | } 168 | 169 | #undef ICVT_SIZE 170 | #undef ICVT_INT 171 | #undef ICVT_UINT 172 | -------------------------------------------------------------------------------- /splitimg.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Disk image splitter 3 | * 4 | * Copyright (c) 2016 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | int main(int argc, char **argv) 32 | { 33 | int blocksize, ret, i; 34 | const char *infilename, *outpath; 35 | FILE *f, *fo; 36 | char buf1[1024]; 37 | uint8_t *buf; 38 | 39 | if ((optind + 1) >= argc) { 40 | printf("splitimg version " CONFIG_VERSION ", Copyright (c) 2011-2016 Fabrice Bellard\n" 41 | "usage: splitimg infile outpath [blocksize]\n" 42 | "Create a multi-file disk image for the RISCVEMU HTTP block device\n" 43 | "\n" 44 | "outpath must be a directory\n" 45 | "blocksize is the block size in KB\n"); 46 | exit(1); 47 | } 48 | 49 | infilename = argv[optind++]; 50 | outpath = argv[optind++]; 51 | blocksize = 256; 52 | if (optind < argc) 53 | blocksize = strtol(argv[optind++], NULL, 0); 54 | 55 | blocksize *= 1024; 56 | 57 | buf = malloc(blocksize); 58 | 59 | f = fopen(infilename, "rb"); 60 | if (!f) { 61 | perror(infilename); 62 | exit(1); 63 | } 64 | i = 0; 65 | for(;;) { 66 | ret = fread(buf, 1, blocksize, f); 67 | if (ret < 0) { 68 | perror("fread"); 69 | exit(1); 70 | } 71 | if (ret == 0) 72 | break; 73 | if (ret < blocksize) { 74 | printf("warning: last block is not full\n"); 75 | memset(buf + ret, 0, blocksize - ret); 76 | } 77 | snprintf(buf1, sizeof(buf1), "%s/blk%09u.bin", outpath, i); 78 | fo = fopen(buf1, "wb"); 79 | if (!fo) { 80 | perror(buf1); 81 | exit(1); 82 | } 83 | fwrite(buf, 1, blocksize, fo); 84 | fclose(fo); 85 | i++; 86 | } 87 | fclose(f); 88 | printf("%d blocks\n", i); 89 | 90 | snprintf(buf1, sizeof(buf1), "%s/blk.txt", outpath); 91 | fo = fopen(buf1, "wb"); 92 | if (!fo) { 93 | perror(buf1); 94 | exit(1); 95 | } 96 | fprintf(fo, "{\n"); 97 | fprintf(fo, " block_size: %d,\n", blocksize / 1024); 98 | fprintf(fo, " n_block: %d,\n", i); 99 | fprintf(fo, "}\n"); 100 | fclose(fo); 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /virtio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * VIRTIO driver 3 | * 4 | * Copyright (c) 2016 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef VIRTIO_H 25 | #define VIRTIO_H 26 | 27 | #include 28 | 29 | #include "iomem.h" 30 | #include "pci.h" 31 | 32 | #define VIRTIO_PAGE_SIZE 4096 33 | 34 | #if defined(EMSCRIPTEN) 35 | #define VIRTIO_ADDR_BITS 32 36 | #else 37 | #define VIRTIO_ADDR_BITS 64 38 | #endif 39 | 40 | #if VIRTIO_ADDR_BITS == 64 41 | typedef uint64_t virtio_phys_addr_t; 42 | #else 43 | typedef uint32_t virtio_phys_addr_t; 44 | #endif 45 | 46 | typedef struct { 47 | /* PCI only: */ 48 | PCIBus *pci_bus; 49 | /* MMIO only: */ 50 | PhysMemoryMap *mem_map; 51 | uint64_t addr; 52 | IRQSignal *irq; 53 | } VIRTIOBusDef; 54 | 55 | typedef struct VIRTIODevice VIRTIODevice; 56 | 57 | #define VIRTIO_DEBUG_IO (1 << 0) 58 | #define VIRTIO_DEBUG_9P (1 << 1) 59 | 60 | void virtio_set_debug(VIRTIODevice *s, int debug_flags); 61 | 62 | /* block device */ 63 | 64 | typedef void BlockDeviceCompletionFunc(void *opaque, int ret); 65 | 66 | typedef struct BlockDevice BlockDevice; 67 | 68 | struct BlockDevice { 69 | int64_t (*get_sector_count)(BlockDevice *bs); 70 | int (*read_async)(BlockDevice *bs, 71 | uint64_t sector_num, uint8_t *buf, int n, 72 | BlockDeviceCompletionFunc *cb, void *opaque); 73 | int (*write_async)(BlockDevice *bs, 74 | uint64_t sector_num, const uint8_t *buf, int n, 75 | BlockDeviceCompletionFunc *cb, void *opaque); 76 | void *opaque; 77 | }; 78 | 79 | VIRTIODevice *virtio_block_init(VIRTIOBusDef *bus, BlockDevice *bs); 80 | 81 | /* network device */ 82 | 83 | typedef struct EthernetDevice EthernetDevice; 84 | 85 | struct EthernetDevice { 86 | uint8_t mac_addr[6]; /* mac address of the interface */ 87 | void (*write_packet)(EthernetDevice *net, 88 | const uint8_t *buf, int len); 89 | void *opaque; 90 | #if !defined(EMSCRIPTEN) 91 | void (*select_fill)(EthernetDevice *net, int *pfd_max, 92 | fd_set *rfds, fd_set *wfds, fd_set *efds, 93 | int *pdelay); 94 | void (*select_poll)(EthernetDevice *net, 95 | fd_set *rfds, fd_set *wfds, fd_set *efds, 96 | int select_ret); 97 | #endif 98 | /* the following is set by the device */ 99 | void *device_opaque; 100 | BOOL (*device_can_write_packet)(EthernetDevice *net); 101 | void (*device_write_packet)(EthernetDevice *net, 102 | const uint8_t *buf, int len); 103 | void (*device_set_carrier)(EthernetDevice *net, BOOL carrier_state); 104 | }; 105 | 106 | VIRTIODevice *virtio_net_init(VIRTIOBusDef *bus, EthernetDevice *es); 107 | 108 | /* console device */ 109 | 110 | typedef struct { 111 | void *opaque; 112 | void (*write_data)(void *opaque, const uint8_t *buf, int len); 113 | int (*read_data)(void *opaque, uint8_t *buf, int len); 114 | } CharacterDevice; 115 | 116 | VIRTIODevice *virtio_console_init(VIRTIOBusDef *bus, CharacterDevice *cs); 117 | BOOL virtio_console_can_write_data(VIRTIODevice *s); 118 | int virtio_console_get_write_len(VIRTIODevice *s); 119 | int virtio_console_write_data(VIRTIODevice *s, const uint8_t *buf, int buf_len); 120 | void virtio_console_resize_event(VIRTIODevice *s, int width, int height); 121 | 122 | /* input device */ 123 | 124 | typedef enum { 125 | VIRTIO_INPUT_TYPE_KEYBOARD, 126 | VIRTIO_INPUT_TYPE_MOUSE, 127 | VIRTIO_INPUT_TYPE_TABLET, 128 | } VirtioInputTypeEnum; 129 | 130 | #define VIRTIO_INPUT_ABS_SCALE 32768 131 | 132 | int virtio_input_send_key_event(VIRTIODevice *s, BOOL is_down, 133 | uint16_t key_code); 134 | int virtio_input_send_mouse_event(VIRTIODevice *s, int dx, int dy, int dz, 135 | unsigned int buttons); 136 | 137 | VIRTIODevice *virtio_input_init(VIRTIOBusDef *bus, VirtioInputTypeEnum type); 138 | 139 | /* 9p filesystem device */ 140 | 141 | #include "fs.h" 142 | 143 | VIRTIODevice *virtio_9p_init(VIRTIOBusDef *bus, FSDevice *fs, 144 | const char *mount_tag); 145 | 146 | #endif /* VIRTIO_H */ 147 | -------------------------------------------------------------------------------- /vmmouse.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VM mouse emulation 3 | * 4 | * Copyright (c) 2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "cutils.h" 31 | #include "iomem.h" 32 | #include "ps2.h" 33 | 34 | #define VMPORT_MAGIC 0x564D5868 35 | 36 | #define REG_EAX 0 37 | #define REG_EBX 1 38 | #define REG_ECX 2 39 | #define REG_EDX 3 40 | #define REG_ESI 4 41 | #define REG_EDI 5 42 | 43 | #define FIFO_SIZE (4 * 16) 44 | 45 | struct VMMouseState { 46 | PS2MouseState *ps2_mouse; 47 | int fifo_count, fifo_rindex, fifo_windex; 48 | BOOL enabled; 49 | BOOL absolute; 50 | uint32_t fifo_buf[FIFO_SIZE]; 51 | }; 52 | 53 | static void put_queue(VMMouseState *s, uint32_t val) 54 | { 55 | if (s->fifo_count >= FIFO_SIZE) 56 | return; 57 | s->fifo_buf[s->fifo_windex] = val; 58 | if (++s->fifo_windex == FIFO_SIZE) 59 | s->fifo_windex = 0; 60 | s->fifo_count++; 61 | } 62 | 63 | static void read_data(VMMouseState *s, uint32_t *regs, int size) 64 | { 65 | int i; 66 | if (size > 6 || size > s->fifo_count) { 67 | // printf("vmmouse: read error req=%d count=%d\n", size, s->fifo_count); 68 | s->enabled = FALSE; 69 | return; 70 | } 71 | for(i = 0; i < size; i++) { 72 | regs[i] = s->fifo_buf[s->fifo_rindex]; 73 | if (++s->fifo_rindex == FIFO_SIZE) 74 | s->fifo_rindex = 0; 75 | } 76 | s->fifo_count -= size; 77 | } 78 | 79 | void vmmouse_send_mouse_event(VMMouseState *s, int x, int y, int dz, 80 | int buttons) 81 | { 82 | int state; 83 | 84 | if (!s->enabled) { 85 | ps2_mouse_event(s->ps2_mouse, x, y, dz, buttons); 86 | return; 87 | } 88 | 89 | if ((s->fifo_count + 4) > FIFO_SIZE) 90 | return; 91 | 92 | state = 0; 93 | if (buttons & 1) 94 | state |= 0x20; 95 | if (buttons & 2) 96 | state |= 0x10; 97 | if (buttons & 4) 98 | state |= 0x08; 99 | if (s->absolute) { 100 | /* range = 0 ... 65535 */ 101 | x *= 2; 102 | y *= 2; 103 | } 104 | 105 | put_queue(s, state); 106 | put_queue(s, x); 107 | put_queue(s, y); 108 | put_queue(s, -dz); 109 | 110 | /* send PS/2 mouse event */ 111 | ps2_mouse_event(s->ps2_mouse, 1, 0, 0, 0); 112 | } 113 | 114 | void vmmouse_handler(VMMouseState *s, uint32_t *regs) 115 | { 116 | uint32_t cmd; 117 | 118 | cmd = regs[REG_ECX] & 0xff; 119 | switch(cmd) { 120 | case 10: /* get version */ 121 | regs[REG_EBX] = VMPORT_MAGIC; 122 | break; 123 | case 39: /* VMMOUSE_DATA */ 124 | read_data(s, regs, regs[REG_EBX]); 125 | break; 126 | case 40: /* VMMOUSE_STATUS */ 127 | regs[REG_EAX] = ((s->enabled ? 0 : 0xffff) << 16) | s->fifo_count; 128 | break; 129 | case 41: /* VMMOUSE_COMMAND */ 130 | switch(regs[REG_EBX]) { 131 | case 0x45414552: /* read id */ 132 | if (s->fifo_count < FIFO_SIZE) { 133 | put_queue(s, 0x3442554a); 134 | s->enabled = TRUE; 135 | } 136 | break; 137 | case 0x000000f5: /* disable */ 138 | s->enabled = FALSE; 139 | break; 140 | case 0x4c455252: /* set relative */ 141 | s->absolute = 0; 142 | break; 143 | case 0x53424152: /* set absolute */ 144 | s->absolute = 1; 145 | break; 146 | } 147 | break; 148 | } 149 | } 150 | 151 | BOOL vmmouse_is_absolute(VMMouseState *s) 152 | { 153 | return s->absolute; 154 | } 155 | 156 | VMMouseState *vmmouse_init(PS2MouseState *ps2_mouse) 157 | { 158 | VMMouseState *s; 159 | s = mallocz(sizeof(*s)); 160 | s->ps2_mouse = ps2_mouse; 161 | return s; 162 | } 163 | -------------------------------------------------------------------------------- /x86_cpu.c: -------------------------------------------------------------------------------- 1 | /* 2 | * x86 CPU emulator stub 3 | * 4 | * Copyright (c) 2011-2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "cutils.h" 32 | #include "x86_cpu.h" 33 | 34 | X86CPUState *x86_cpu_init(PhysMemoryMap *mem_map) 35 | { 36 | fprintf(stderr, "x86 emulator is not supported\n"); 37 | exit(1); 38 | } 39 | 40 | void x86_cpu_end(X86CPUState *s) 41 | { 42 | } 43 | 44 | void x86_cpu_interp(X86CPUState *s, int max_cycles1) 45 | { 46 | } 47 | 48 | void x86_cpu_set_irq(X86CPUState *s, BOOL set) 49 | { 50 | } 51 | 52 | void x86_cpu_set_reg(X86CPUState *s, int reg, uint32_t val) 53 | { 54 | } 55 | 56 | uint32_t x86_cpu_get_reg(X86CPUState *s, int reg) 57 | { 58 | return 0; 59 | } 60 | 61 | void x86_cpu_set_seg(X86CPUState *s, int seg, const X86CPUSeg *sd) 62 | { 63 | } 64 | 65 | void x86_cpu_set_get_hard_intno(X86CPUState *s, 66 | int (*get_hard_intno)(void *opaque), 67 | void *opaque) 68 | { 69 | } 70 | 71 | void x86_cpu_set_get_tsc(X86CPUState *s, 72 | uint64_t (*get_tsc)(void *opaque), 73 | void *opaque) 74 | { 75 | } 76 | 77 | void x86_cpu_set_port_io(X86CPUState *s, 78 | DeviceReadFunc *port_read, DeviceWriteFunc *port_write, 79 | void *opaque) 80 | { 81 | } 82 | 83 | int64_t x86_cpu_get_cycles(X86CPUState *s) 84 | { 85 | return 0; 86 | } 87 | 88 | BOOL x86_cpu_get_power_down(X86CPUState *s) 89 | { 90 | return FALSE; 91 | } 92 | 93 | void x86_cpu_flush_tlb_write_range_ram(X86CPUState *s, 94 | uint8_t *ram_ptr, size_t ram_size) 95 | { 96 | } 97 | -------------------------------------------------------------------------------- /x86_cpu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * x86 CPU emulator 3 | * 4 | * Copyright (c) 2011-2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include "iomem.h" 25 | 26 | typedef struct X86CPUState X86CPUState; 27 | 28 | /* get_reg/set_reg additional constants */ 29 | #define X86_CPU_REG_EIP 8 30 | #define X86_CPU_REG_CR0 9 31 | #define X86_CPU_REG_CR2 10 32 | 33 | #define X86_CPU_SEG_ES 0 34 | #define X86_CPU_SEG_CS 1 35 | #define X86_CPU_SEG_SS 2 36 | #define X86_CPU_SEG_DS 3 37 | #define X86_CPU_SEG_FS 4 38 | #define X86_CPU_SEG_GS 5 39 | #define X86_CPU_SEG_LDT 6 40 | #define X86_CPU_SEG_TR 7 41 | #define X86_CPU_SEG_GDT 8 42 | #define X86_CPU_SEG_IDT 9 43 | 44 | typedef struct { 45 | uint16_t sel; 46 | uint16_t flags; 47 | uint32_t base; 48 | uint32_t limit; 49 | } X86CPUSeg; 50 | 51 | X86CPUState *x86_cpu_init(PhysMemoryMap *mem_map); 52 | void x86_cpu_end(X86CPUState *s); 53 | void x86_cpu_interp(X86CPUState *s, int max_cycles1); 54 | void x86_cpu_set_irq(X86CPUState *s, BOOL set); 55 | void x86_cpu_set_reg(X86CPUState *s, int reg, uint32_t val); 56 | uint32_t x86_cpu_get_reg(X86CPUState *s, int reg); 57 | void x86_cpu_set_seg(X86CPUState *s, int seg, const X86CPUSeg *sd); 58 | void x86_cpu_set_get_hard_intno(X86CPUState *s, 59 | int (*get_hard_intno)(void *opaque), 60 | void *opaque); 61 | void x86_cpu_set_get_tsc(X86CPUState *s, 62 | uint64_t (*get_tsc)(void *opaque), 63 | void *opaque); 64 | void x86_cpu_set_port_io(X86CPUState *s, 65 | DeviceReadFunc *port_read, DeviceWriteFunc *port_write, 66 | void *opaque); 67 | int64_t x86_cpu_get_cycles(X86CPUState *s); 68 | BOOL x86_cpu_get_power_down(X86CPUState *s); 69 | void x86_cpu_flush_tlb_write_range_ram(X86CPUState *s, 70 | uint8_t *ram_ptr, size_t ram_size); 71 | --------------------------------------------------------------------------------