├── .gitignore ├── Makefile ├── README.md ├── boot ├── bochsrc └── isolinux │ ├── isolinux.bin │ ├── ldlinux.c32 │ ├── libcom32.c32 │ └── mboot.c32 ├── drivers ├── acpi.c ├── cga.c ├── kbd.c ├── membuf.c ├── pci.c ├── uart_8250.c └── uart_porte9.c ├── hv6 ├── Makefrag ├── arch │ ├── cc.h │ └── sys_arch.h ├── crt0.S ├── device.c ├── device.h ├── entry.S ├── fd.c ├── fd.h ├── initbin.S ├── invariants.c ├── invariants.h ├── ioport.c ├── ioport.h ├── ipc.c ├── ipc.h ├── kernel_verif.c ├── main.c ├── memlayout.h ├── mmap.c ├── mmap.h ├── param.h ├── proc.c ├── proc.h ├── spec │ ├── base.py │ ├── kernel │ │ ├── datatypes.py │ │ ├── main.py │ │ ├── spec │ │ │ ├── __init__.py │ │ │ ├── equiv.py │ │ │ ├── helpers.py │ │ │ ├── invariants.py │ │ │ ├── specs.py │ │ │ └── top.py │ │ └── syscall_spec.py │ └── user │ │ ├── datatypes.py │ │ ├── main.py │ │ └── spec.py ├── syscall.c ├── syscall.h ├── sysctl.c ├── test.py ├── trap.c ├── trap_entry.S ├── types.h ├── user │ ├── Makefrag │ ├── bench.c │ ├── bench.h │ ├── bounce.c │ ├── cat.c │ ├── cpio.c │ ├── daytime.c │ ├── dmesg.c │ ├── echo.c │ ├── fault.c │ ├── fcntl.h │ ├── freelist.c │ ├── fs │ │ ├── bio.c │ │ ├── file.c │ │ ├── fs.c │ │ ├── fs.h │ │ ├── fslayout.h │ │ ├── ide.c │ │ ├── inode.c │ │ ├── log.c │ │ ├── memdisk.c │ │ ├── memfs.S │ │ ├── mkfs.c │ │ ├── nvmedisk.c │ │ ├── pipe.c │ │ ├── stat.h │ │ ├── uiommu.c │ │ └── uiommu.h │ ├── genustub.py │ ├── grep.c │ ├── httpd.c │ ├── httpget.c │ ├── init.c │ ├── initcode.S │ ├── kill.c │ ├── lib │ │ ├── exec.c │ │ ├── fcntl.c │ │ ├── fork.c │ │ ├── linux.c │ │ ├── printf.c │ │ ├── readline.c │ │ ├── socket.c │ │ ├── trap.c │ │ ├── trap_entry.S │ │ ├── ubrk.c │ │ ├── ulib.c │ │ ├── ulib.lds │ │ ├── ulib_entry.S │ │ ├── umalloc.c │ │ └── usys.S │ ├── linux │ │ ├── bench_linux │ │ ├── bench_linux.c │ │ ├── compile │ │ ├── gzip │ │ ├── hello │ │ ├── hello.c │ │ ├── hello.lua │ │ ├── linux.h │ │ ├── lua │ │ ├── sha1sum │ │ ├── tcc │ │ ├── ter-x16n.psf │ │ ├── test.smt2 │ │ └── z3 │ ├── ls.c │ ├── lwip │ ├── lwipopts.h │ ├── mkdir.c │ ├── ns.c │ ├── ns.h │ ├── ps.c │ ├── pstree.c │ ├── readline.h │ ├── readylist.c │ ├── rm.c │ ├── sh.c │ ├── socket.h │ ├── timer.c │ ├── user.h │ ├── vmstat.c │ ├── vncd.c │ ├── wc.c │ └── wttr.c ├── vm.c └── vm.h ├── include └── uapi │ ├── assym.h │ ├── bitset.h │ ├── cdefs.h │ ├── console.h │ ├── container.h │ ├── e1000.h │ ├── elf.h │ ├── errno.h │ ├── image.h │ ├── machine │ ├── cpufunc.h │ ├── io.h │ ├── mmu.h │ ├── msr.h │ ├── segment.h │ ├── trap.h │ ├── trap_genassym.c │ └── trap_support.h │ ├── nvme.h │ ├── pci.h │ ├── pcidb.h │ ├── pcireg.h │ ├── psf.h │ ├── queue.h │ ├── syscall.h │ └── sysctl.h ├── irpy ├── .gitignore ├── Makefrag ├── compiler │ ├── Emitter.cc │ ├── Emitter.hh │ ├── PyEmitter.cc │ ├── PyEmitter.hh │ ├── PyLLVMEmitter.cc │ ├── PyLLVMEmitter.hh │ └── irpy.cc ├── libirpy │ ├── __init__.py │ ├── ctx.py │ ├── datatypes.py │ ├── eval.py │ ├── ex.py │ ├── itypes.py │ ├── server.py │ ├── solver.py │ ├── solver_utils.py │ ├── tests │ │ ├── __init__.py │ │ ├── test_ctx.py │ │ ├── test_reference.py │ │ └── test_types.py │ ├── util.py │ └── z3eval.py └── test │ ├── add.c │ ├── add_overflow.c │ ├── add_overflow_check.c │ ├── alloca.c │ ├── alloca_alias.c │ ├── array_arith.c │ ├── array_test.c │ ├── array_test2.c │ ├── big_shift.c │ ├── bool_zext.c │ ├── call_return.c │ ├── cond.c │ ├── cond2.c │ ├── cond_global.c │ ├── loop2.c │ ├── loop3.c │ ├── loop4.c │ ├── lsh.c │ ├── mul_overflow.c │ ├── path.c │ ├── poison_cond.c │ ├── ptrptr.c │ ├── rsh.c │ ├── sdiv.c │ ├── sext.c │ ├── srem.c │ ├── struct_.c │ ├── struct_cond.c │ ├── struct_t.c │ ├── switch.c │ ├── switch_table.c │ ├── test.py │ ├── trunc.c │ ├── udiv.c │ ├── urem.c │ ├── zero_div.c │ └── zext.c ├── kernel ├── Makefrag ├── amd_iommu.c ├── amd_iommu.h ├── config.h ├── cpuid.c ├── cpuid.h ├── fpu.c ├── hvm.c ├── hvm_support.S ├── include │ ├── acpi.h │ ├── bootmem.h │ ├── ctype.h │ ├── hvm.h │ ├── init.h │ ├── iommu.h │ ├── machine │ │ ├── env.h │ │ └── memlayout.h │ ├── multiboot.h │ ├── pagemap.h │ ├── stdio.h │ ├── stdlib.h │ ├── string.h │ ├── symtable.h │ └── time.h ├── intel_iommu.c ├── intel_iommu.h ├── ioapic.c ├── iommu.c ├── kernel.lds.S ├── locore.S ├── mtrr.c ├── pic.c ├── pmap.c ├── svm.c ├── svm.h ├── svm_entry.S ├── svm_genassym.c ├── tsc.c ├── vmx.c ├── vmx.h ├── vmx_entry.S ├── xapic.c └── xapic.h ├── lib ├── bootmem.c ├── console.c ├── panic.c ├── stdio.c ├── stdlib.c ├── string.c └── syslog.c ├── scripts ├── check-hv6-invariants.py ├── configure_bochs.sh ├── configure_qemu.sh ├── genassym.sh ├── gensymtable.py ├── isohybrid.pl ├── ldcheck.py ├── no_undef.sh ├── pytest ├── stackcheck.py └── stackcheck_config.py ├── user ├── lwip │ ├── FILES │ ├── Filelists.mk │ ├── api │ │ ├── api_lib.c │ │ ├── api_msg.c │ │ ├── err.c │ │ ├── netbuf.c │ │ ├── netdb.c │ │ ├── netifapi.c │ │ ├── sockets.c │ │ └── tcpip.c │ ├── apps │ │ ├── httpd │ │ │ ├── fs.c │ │ │ ├── fs │ │ │ │ ├── 404.html │ │ │ │ ├── img │ │ │ │ │ └── sics.gif │ │ │ │ └── index.html │ │ │ ├── fsdata.c │ │ │ ├── fsdata.h │ │ │ ├── httpd.c │ │ │ ├── httpd_structs.h │ │ │ └── makefsdata │ │ │ │ ├── makefsdata │ │ │ │ ├── makefsdata.c │ │ │ │ └── readme.txt │ │ ├── lwiperf │ │ │ └── lwiperf.c │ │ ├── mdns │ │ │ └── mdns.c │ │ ├── mqtt │ │ │ └── mqtt.c │ │ ├── netbiosns │ │ │ └── netbiosns.c │ │ ├── snmp │ │ │ ├── snmp_asn1.c │ │ │ ├── snmp_asn1.h │ │ │ ├── snmp_core.c │ │ │ ├── snmp_core_priv.h │ │ │ ├── snmp_mib2.c │ │ │ ├── snmp_mib2_icmp.c │ │ │ ├── snmp_mib2_interfaces.c │ │ │ ├── snmp_mib2_ip.c │ │ │ ├── snmp_mib2_snmp.c │ │ │ ├── snmp_mib2_system.c │ │ │ ├── snmp_mib2_tcp.c │ │ │ ├── snmp_mib2_udp.c │ │ │ ├── snmp_msg.c │ │ │ ├── snmp_msg.h │ │ │ ├── snmp_netconn.c │ │ │ ├── snmp_pbuf_stream.c │ │ │ ├── snmp_pbuf_stream.h │ │ │ ├── snmp_raw.c │ │ │ ├── snmp_scalar.c │ │ │ ├── snmp_table.c │ │ │ ├── snmp_threadsync.c │ │ │ ├── snmp_traps.c │ │ │ ├── snmpv3.c │ │ │ ├── snmpv3_dummy.c │ │ │ ├── snmpv3_mbedtls.c │ │ │ └── snmpv3_priv.h │ │ ├── sntp │ │ │ └── sntp.c │ │ └── tftp │ │ │ └── tftp_server.c │ ├── core │ │ ├── def.c │ │ ├── dns.c │ │ ├── inet_chksum.c │ │ ├── init.c │ │ ├── ip.c │ │ ├── ipv4 │ │ │ ├── autoip.c │ │ │ ├── dhcp.c │ │ │ ├── etharp.c │ │ │ ├── icmp.c │ │ │ ├── igmp.c │ │ │ ├── ip4.c │ │ │ ├── ip4_addr.c │ │ │ └── ip4_frag.c │ │ ├── ipv6 │ │ │ ├── dhcp6.c │ │ │ ├── ethip6.c │ │ │ ├── icmp6.c │ │ │ ├── inet6.c │ │ │ ├── ip6.c │ │ │ ├── ip6_addr.c │ │ │ ├── ip6_frag.c │ │ │ ├── mld6.c │ │ │ └── nd6.c │ │ ├── mem.c │ │ ├── memp.c │ │ ├── netif.c │ │ ├── pbuf.c │ │ ├── raw.c │ │ ├── stats.c │ │ ├── sys.c │ │ ├── tcp.c │ │ ├── tcp_in.c │ │ ├── tcp_out.c │ │ ├── timeouts.c │ │ └── udp.c │ ├── include │ │ ├── lwip │ │ │ ├── api.h │ │ │ ├── apps │ │ │ │ ├── FILES │ │ │ │ ├── fs.h │ │ │ │ ├── httpd.h │ │ │ │ ├── httpd_opts.h │ │ │ │ ├── lwiperf.h │ │ │ │ ├── mdns.h │ │ │ │ ├── mdns_opts.h │ │ │ │ ├── mdns_priv.h │ │ │ │ ├── mqtt.h │ │ │ │ ├── mqtt_opts.h │ │ │ │ ├── netbiosns.h │ │ │ │ ├── netbiosns_opts.h │ │ │ │ ├── snmp.h │ │ │ │ ├── snmp_core.h │ │ │ │ ├── snmp_mib2.h │ │ │ │ ├── snmp_opts.h │ │ │ │ ├── snmp_scalar.h │ │ │ │ ├── snmp_table.h │ │ │ │ ├── snmp_threadsync.h │ │ │ │ ├── snmpv3.h │ │ │ │ ├── sntp.h │ │ │ │ ├── sntp_opts.h │ │ │ │ ├── tftp_opts.h │ │ │ │ └── tftp_server.h │ │ │ ├── arch.h │ │ │ ├── autoip.h │ │ │ ├── debug.h │ │ │ ├── def.h │ │ │ ├── dhcp.h │ │ │ ├── dhcp6.h │ │ │ ├── dns.h │ │ │ ├── err.h │ │ │ ├── errno.h │ │ │ ├── etharp.h │ │ │ ├── ethip6.h │ │ │ ├── icmp.h │ │ │ ├── icmp6.h │ │ │ ├── igmp.h │ │ │ ├── inet.h │ │ │ ├── inet_chksum.h │ │ │ ├── init.h │ │ │ ├── ip.h │ │ │ ├── ip4.h │ │ │ ├── ip4_addr.h │ │ │ ├── ip4_frag.h │ │ │ ├── ip6.h │ │ │ ├── ip6_addr.h │ │ │ ├── ip6_frag.h │ │ │ ├── ip_addr.h │ │ │ ├── mem.h │ │ │ ├── memp.h │ │ │ ├── mld6.h │ │ │ ├── nd6.h │ │ │ ├── netbuf.h │ │ │ ├── netdb.h │ │ │ ├── netif.h │ │ │ ├── netifapi.h │ │ │ ├── opt.h │ │ │ ├── pbuf.h │ │ │ ├── priv │ │ │ │ ├── api_msg.h │ │ │ │ ├── memp_priv.h │ │ │ │ ├── memp_std.h │ │ │ │ ├── nd6_priv.h │ │ │ │ ├── tcp_priv.h │ │ │ │ └── tcpip_priv.h │ │ │ ├── prot │ │ │ │ ├── autoip.h │ │ │ │ ├── dhcp.h │ │ │ │ ├── dns.h │ │ │ │ ├── etharp.h │ │ │ │ ├── ethernet.h │ │ │ │ ├── icmp.h │ │ │ │ ├── icmp6.h │ │ │ │ ├── igmp.h │ │ │ │ ├── ip.h │ │ │ │ ├── ip4.h │ │ │ │ ├── ip6.h │ │ │ │ ├── mld6.h │ │ │ │ ├── nd6.h │ │ │ │ ├── tcp.h │ │ │ │ └── udp.h │ │ │ ├── raw.h │ │ │ ├── sio.h │ │ │ ├── snmp.h │ │ │ ├── sockets.h │ │ │ ├── stats.h │ │ │ ├── sys.h │ │ │ ├── tcp.h │ │ │ ├── tcpip.h │ │ │ ├── timeouts.h │ │ │ └── udp.h │ │ ├── netif │ │ │ ├── etharp.h │ │ │ ├── ethernet.h │ │ │ ├── lowpan6.h │ │ │ ├── lowpan6_opts.h │ │ │ ├── ppp │ │ │ │ ├── ccp.h │ │ │ │ ├── chap-md5.h │ │ │ │ ├── chap-new.h │ │ │ │ ├── chap_ms.h │ │ │ │ ├── eap.h │ │ │ │ ├── ecp.h │ │ │ │ ├── eui64.h │ │ │ │ ├── fsm.h │ │ │ │ ├── ipcp.h │ │ │ │ ├── ipv6cp.h │ │ │ │ ├── lcp.h │ │ │ │ ├── magic.h │ │ │ │ ├── mppe.h │ │ │ │ ├── polarssl │ │ │ │ │ ├── arc4.h │ │ │ │ │ ├── des.h │ │ │ │ │ ├── md4.h │ │ │ │ │ ├── md5.h │ │ │ │ │ └── sha1.h │ │ │ │ ├── ppp.h │ │ │ │ ├── ppp_impl.h │ │ │ │ ├── ppp_opts.h │ │ │ │ ├── pppapi.h │ │ │ │ ├── pppcrypt.h │ │ │ │ ├── pppdebug.h │ │ │ │ ├── pppoe.h │ │ │ │ ├── pppol2tp.h │ │ │ │ ├── pppos.h │ │ │ │ ├── upap.h │ │ │ │ └── vj.h │ │ │ └── slipif.h │ │ └── posix │ │ │ ├── errno.h │ │ │ ├── netdb.h │ │ │ └── sys │ │ │ └── socket.h │ └── netif │ │ ├── FILES │ │ ├── ethernet.c │ │ ├── ethernetif.c │ │ ├── lowpan6.c │ │ ├── ppp │ │ ├── PPPD_FOLLOWUP │ │ ├── auth.c │ │ ├── ccp.c │ │ ├── chap-md5.c │ │ ├── chap-new.c │ │ ├── chap_ms.c │ │ ├── demand.c │ │ ├── eap.c │ │ ├── ecp.c │ │ ├── eui64.c │ │ ├── fsm.c │ │ ├── ipcp.c │ │ ├── ipv6cp.c │ │ ├── lcp.c │ │ ├── magic.c │ │ ├── mppe.c │ │ ├── multilink.c │ │ ├── polarssl │ │ │ ├── README │ │ │ ├── arc4.c │ │ │ ├── des.c │ │ │ ├── md4.c │ │ │ ├── md5.c │ │ │ └── sha1.c │ │ ├── ppp.c │ │ ├── pppapi.c │ │ ├── pppcrypt.c │ │ ├── pppoe.c │ │ ├── pppol2tp.c │ │ ├── pppos.c │ │ ├── upap.c │ │ ├── utils.c │ │ └── vj.c │ │ └── slipif.c ├── trap.c └── trap_entry.S └── web ├── d3.v4.min.js ├── jquery.min.js ├── memmap.html ├── pstree.html └── sh.html /.gitignore: -------------------------------------------------------------------------------- 1 | /.gdb_history 2 | /config.mk 3 | /o.* 4 | /tags 5 | /.vscode 6 | .DS_Store 7 | *.sw[op] 8 | .cache/ 9 | *.pyc 10 | irpy.prof 11 | -------------------------------------------------------------------------------- /boot/bochsrc: -------------------------------------------------------------------------------- 1 | cpu: model=$CPU, reset_on_triple_fault=0, count=$NR_CPUS 2 | megs: 1024 3 | ata0-slave: type=cdrom, path=$ISO, status=inserted 4 | boot: cdrom 5 | com1: enabled=1, mode=file, dev=/dev/stdout 6 | port_e9_hack: enabled=1 7 | #display_library: nogui 8 | #e1000: enabled=1, mac=52:54:00:12:34:56 9 | -------------------------------------------------------------------------------- /boot/isolinux/isolinux.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uw-unsat/hyperkernel/50d6bada5de63c56376bdc4dba6159788847cc95/boot/isolinux/isolinux.bin -------------------------------------------------------------------------------- /boot/isolinux/ldlinux.c32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uw-unsat/hyperkernel/50d6bada5de63c56376bdc4dba6159788847cc95/boot/isolinux/ldlinux.c32 -------------------------------------------------------------------------------- /boot/isolinux/libcom32.c32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uw-unsat/hyperkernel/50d6bada5de63c56376bdc4dba6159788847cc95/boot/isolinux/libcom32.c32 -------------------------------------------------------------------------------- /boot/isolinux/mboot.c32: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uw-unsat/hyperkernel/50d6bada5de63c56376bdc4dba6159788847cc95/boot/isolinux/mboot.c32 -------------------------------------------------------------------------------- /drivers/cga.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define BACKSPACE 0x100 7 | 8 | static void cga_putc(void *arg, int c) 9 | { 10 | uint16_t *crt = arg; 11 | int pos; 12 | 13 | /* cursor position: col + 80*row */ 14 | outb(PORT_CRT, 14); 15 | pos = inb(PORT_CRT + 1) << 8; 16 | outb(PORT_CRT, 15); 17 | pos |= inb(PORT_CRT + 1); 18 | 19 | if (c == '\n') { 20 | pos += 80 - pos % 80; 21 | } else if (c == BACKSPACE) { 22 | if (pos > 0) 23 | --pos; 24 | } else { 25 | crt[pos++] = (c & 0xff) | 0x0700; /* black on white */ 26 | } 27 | 28 | if (pos < 0 || pos > 25 * 80) 29 | panic("pos under/overflow"); 30 | 31 | if (pos / 80 >= 24) { /* scroll up */ 32 | memmove(crt, crt + 80, sizeof(crt[0]) * 23 * 80); 33 | pos -= 80; 34 | memset(crt + pos, 0, sizeof(crt[0]) * (24 * 80 - pos)); 35 | } 36 | 37 | outb(PORT_CRT, 14); 38 | outb(PORT_CRT + 1, pos >> 8); 39 | outb(PORT_CRT, 15); 40 | outb(PORT_CRT + 1, pos); 41 | crt[pos] = ' ' | 0x0700; 42 | } 43 | 44 | void cga_write(void *arg, const char *s, size_t n) 45 | { 46 | size_t i; 47 | 48 | for (i = 0; i < n; ++i) 49 | cga_putc(arg, (uint8_t)s[i]); 50 | } 51 | 52 | void cga_init(void *arg) 53 | { 54 | #if ENABLED(CONFIG_CGA) 55 | static struct console_device dev = { 56 | .write = cga_write, 57 | }; 58 | 59 | dev.arg = arg; 60 | console_register(&dev); 61 | #endif 62 | } 63 | -------------------------------------------------------------------------------- /drivers/membuf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define BACKSPACE 0x08 5 | #define DELETE 0x7f 6 | 7 | static uint8_t buf[80 * 25]; 8 | static int pos; 9 | 10 | static void membuf_putc(uint8_t c) 11 | { 12 | if (c == '\n') { 13 | pos += 80 - pos % 80; 14 | } else if (c == '\r') { 15 | /* do nothing */ 16 | } else if (c == BACKSPACE || c == DELETE) { 17 | if (pos > 0) 18 | --pos; 19 | } else { 20 | buf[pos++] = c; 21 | } 22 | 23 | if (pos < 0 || pos > 25 * 80) 24 | panic("pos under/overflow"); 25 | 26 | if (pos / 80 >= 24) { /* scroll up */ 27 | memmove(buf, buf + 80, 23 * 80); 28 | pos -= 80; 29 | memset(buf + pos, 0, 24 * 80 - pos); 30 | } 31 | } 32 | 33 | static void membuf_write(void *arg, const char *s, size_t n) 34 | { 35 | size_t i; 36 | int escape = 0; 37 | 38 | for (i = 0; i < n; ++i) { 39 | uint8_t c = s[i]; 40 | 41 | if (escape) { 42 | if (c == 'm') 43 | escape = 0; 44 | continue; 45 | } 46 | if (c == '\x1b') { 47 | escape = 1; 48 | continue; 49 | } 50 | membuf_putc(c); 51 | } 52 | } 53 | 54 | int membuf_get(void *s) 55 | { 56 | memcpy(s, buf, sizeof(buf)); 57 | return pos; 58 | } 59 | 60 | void membuf_init(void) 61 | { 62 | static struct console_device dev = { 63 | .write = membuf_write, 64 | }; 65 | 66 | console_register(&dev); 67 | } 68 | -------------------------------------------------------------------------------- /drivers/uart_porte9.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static void porte9_write(void *arg, const char *s, size_t n) 5 | { 6 | outsb(0xe9, s, n); 7 | } 8 | 9 | static struct console_device dev = { 10 | .write = porte9_write, 11 | }; 12 | 13 | void porte9_init(void) 14 | { 15 | console_register(&dev); 16 | } 17 | -------------------------------------------------------------------------------- /hv6/arch/cc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "user.h" 4 | 5 | #define LWIP_PLATFORM_DIAG(x) \ 6 | do { \ 7 | cprintf x; \ 8 | } while (0) 9 | #define LWIP_PLATFORM_ASSERT(x) panic(x) 10 | 11 | #ifndef LITTLE_ENDIAN 12 | #error LITTLE_ENDIAN not defined 13 | #endif 14 | #define BYTE_ORDER LITTLE_ENDIAN 15 | 16 | #define PACK_STRUCT_STRUCT __packed 17 | 18 | /* suppress compiler warning */ 19 | #define X8_F "02x" 20 | 21 | #define LWIP_RAND rdtsc 22 | 23 | /* some platforms do not have inttypes.h */ 24 | #define LWIP_NO_INTTYPES_H 1 25 | #define U16_F "hu" 26 | #define S16_F "hd" 27 | #define X16_F "hx" 28 | #define U32_F "u" 29 | #define S32_F "d" 30 | #define X32_F "x" 31 | -------------------------------------------------------------------------------- /hv6/arch/sys_arch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define lwip_htons __bultin_bswap16 4 | #define lwip_ntohs __bultin_bswap16 5 | -------------------------------------------------------------------------------- /hv6/crt0.S: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | .section .text 4 | 5 | .global _start 6 | _start: 7 | movq $0, %rbp 8 | pop %rdi /* argc */ 9 | movq %rsp, %rsi /* argv */ 10 | push %rbp /* align the stack */ 11 | call main 12 | spin: 13 | call exit 14 | jmp spin 15 | -------------------------------------------------------------------------------- /hv6/device.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "param.h" 4 | #include "types.h" 5 | 6 | extern struct pci_dev devices[NPCIDEV]; 7 | extern volatile uint8_t dmapages[NDMAPAGE][PAGE_SIZE]; 8 | 9 | int sys_map_pcipage(pn_t pt, size_t index, pn_t pcipn, pte_t perm); 10 | /* 11 | * We don't have sys_unmap_pcipage here as it's not useful. 12 | * We assume the common use of a process (e.g., servers) is 13 | * not to give up pci pages until it's dead. 14 | */ 15 | 16 | int sys_alloc_iommu_root(devid_t devid, pn_t pn); 17 | int sys_alloc_iommu_pdpt(pn_t from, size_t index, pn_t to, iommu_pte_t perm); 18 | int sys_alloc_iommu_pd(pn_t from, size_t index, pn_t to, iommu_pte_t perm); 19 | int sys_alloc_iommu_pt(pn_t from, size_t index, pn_t to, iommu_pte_t perm); 20 | int sys_alloc_iommu_frame(pn_t from, size_t index, dmapn_t to, iommu_pte_t perm); 21 | int sys_map_iommu_frame(pn_t pt, size_t index, dmapn_t to, pte_t perm); 22 | int sys_reclaim_iommu_frame(dmapn_t dmapn); 23 | /* 24 | * iommu root is only reclaimed for zombies; this is easier to reclaim 25 | * other resources (e.g., pcipages). 26 | */ 27 | int sys_reclaim_iommu_root(devid_t devid); 28 | 29 | int sys_alloc_vector(uint8_t vector); 30 | /* 31 | * There is no free here; IR table might refer to a vector. 32 | */ 33 | int sys_reclaim_vector(uint8_t vector); 34 | void reserve_vector(uint8_t vector); 35 | void reserve_vectors(uint8_t vector, size_t n); 36 | 37 | int sys_alloc_intremap(size_t index, devid_t devid, uint8_t irq); 38 | int sys_reclaim_intremap(size_t index); 39 | int sys_ack_intr(uint8_t irq); 40 | 41 | int extintr(uint8_t irq); 42 | 43 | void device_add(struct pci_func *f); 44 | -------------------------------------------------------------------------------- /hv6/entry.S: -------------------------------------------------------------------------------- 1 | #include 2 | #include "config.h" 3 | 4 | /* 5 | * Don't return from functions in this file. Instead, call run_current. 6 | * 7 | * Upon entry the rax field in struct trap_reg may be the vmcs; 8 | * once we change it, we cannot simply return. 9 | * 10 | * Flush hvm state from cpu state to memory before each call. This is 11 | * necessary for context switching. 12 | */ 13 | 14 | .macro SYS_WRAP proc 15 | /* save all GP registers (except %rax) */ 16 | SAVE_EXTRA_REGS offset=8 17 | SAVE_FPU_REGS offset=8 18 | /* set default return value to 0 */ 19 | movq $0, TRAP_REGS_RAX+8(%rsp) 20 | /* align the stack */ 21 | push %rbp 22 | movq %rsp, %rbp 23 | /* restore parameters */ 24 | LOAD_C_REGS offset=16 25 | call \proc 26 | pop %rbp 27 | /* set the return value */ 28 | movq %rax, TRAP_REGS_RAX+8(%rsp) 29 | jmp run_current 30 | .endm 31 | 32 | .global sys_clone 33 | sys_clone: 34 | SYS_WRAP clone_proc 35 | 36 | .global sys_switch 37 | sys_switch: 38 | SYS_WRAP sys_switch_helper 39 | 40 | .global sys_send 41 | sys_send: 42 | SYS_WRAP send_proc 43 | 44 | .global sys_recv 45 | sys_recv: 46 | SYS_WRAP recv_proc 47 | 48 | .global sys_call 49 | sys_call: 50 | SYS_WRAP call_proc 51 | 52 | .global sys_reply_wait 53 | sys_reply_wait: 54 | SYS_WRAP reply_wait_proc 55 | -------------------------------------------------------------------------------- /hv6/fd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | extern struct file file_table[NFILE]; 6 | 7 | int sys_create(int fd, fn_t fn, uint64_t type, uint64_t value, uint64_t mode); 8 | int sys_close(pid_t pid, int fd); 9 | int sys_dup(int oldfd, pid_t pid, int newfd); 10 | int sys_dup2(int oldfd, pid_t pid, int newfd); 11 | int sys_lseek(int fd, off_t offset); 12 | 13 | static inline struct file *get_file(fn_t fn) 14 | { 15 | assert(is_fn_valid(fn), "fn must be valid"); 16 | return &file_table[fn]; 17 | } 18 | 19 | static inline bool is_file_type(fn_t fn, enum file_type type) 20 | { 21 | return is_fn_valid(fn) && get_file(fn)->type == type; 22 | } 23 | -------------------------------------------------------------------------------- /hv6/initbin.S: -------------------------------------------------------------------------------- 1 | .section .rodata 2 | 3 | .global _binary_init_start 4 | .global _binary_init_end 5 | _binary_init_start: 6 | .incbin "init" 7 | _binary_init_end: 8 | 9 | .global _binary_ulib_start 10 | .global _binary_ulib_end 11 | _binary_ulib_start: 12 | .incbin "ulib" 13 | _binary_ulib_end: 14 | -------------------------------------------------------------------------------- /hv6/invariants.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void check_invariants(void); 4 | -------------------------------------------------------------------------------- /hv6/ioport.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "proc.h" 4 | 5 | int sys_alloc_io_bitmap(pn_t pn1, pn_t pn2, pn_t pn3); 6 | int sys_alloc_port(uint16_t port); 7 | int sys_reclaim_port(uint16_t port); 8 | 9 | /* kernel will reserve certain ports */ 10 | void reserve_port(uint16_t port); 11 | void reserve_ports(uint16_t port, size_t n); 12 | void allow_port(uint16_t port); 13 | void allow_ports(uint16_t port, size_t n); 14 | -------------------------------------------------------------------------------- /hv6/ipc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | int sys_send(pid_t pid, uint64_t val, pn_t pn, size_t size, int fd); 6 | int sys_recv(pid_t pid, pn_t pn, int fd); 7 | int sys_reply_wait(pid_t pid, uint64_t val, pn_t inpn, size_t size, int infd, pn_t outpn); 8 | int sys_call(pid_t pid, uint64_t val, pn_t inpn, size_t size, pn_t outpn, int outfd); 9 | -------------------------------------------------------------------------------- /hv6/kernel_verif.c: -------------------------------------------------------------------------------- 1 | #include "proc.c" 2 | #include "syscall.c" 3 | #include "vm.c" 4 | #include "device.c" 5 | #include "fd.c" 6 | #include "ipc.c" 7 | #include "sched.c" 8 | #include "invariants.c" 9 | -------------------------------------------------------------------------------- /hv6/memlayout.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "param.h" 5 | 6 | #define ULIB_START UINT64_C(0xffff800000000000) 7 | 8 | #define USYSCALL_START (ULIB_START + PAGE_SIZE) 9 | #define USYSCALL_END (USYSCALL_START + PAGE_SIZE) 10 | 11 | #define UPAGES_START (USYSCALL_END + PAGE_SIZE) 12 | #define UPAGES_END (UPAGES_START + roundup(NPAGE * sizeof(struct page_desc), PAGE_SIZE)) 13 | 14 | #define UPROCS_START (UPAGES_END + PAGE_SIZE) 15 | #define UPROCS_END (UPROCS_START + roundup(NPROC * sizeof(struct proc), PAGE_SIZE)) 16 | 17 | #define UDEVS_START (UPROCS_END + PAGE_SIZE) 18 | #define UDEVS_END (UDEVS_START + roundup(NPCIDEV * sizeof(struct pci_dev), PAGE_SIZE)) 19 | 20 | #define UFILES_START (UDEVS_END + PAGE_SIZE) 21 | #define UFILES_END (UFILES_START + roundup(NFILE * sizeof(struct file), PAGE_SIZE)) 22 | 23 | #define UECAM_START (UFILES_END + PAGE_SIZE) 24 | #define UECAM_END (UECAM_START + SZ_256M) 25 | 26 | /* 0xffff880000000000 - */ 27 | #define UVPML4_INDEX UINT64_C(272) 28 | #define UVPT (ULIB_START | (UVPML4_INDEX << PML4_SHIFT)) 29 | #define UVPD (UVPT | (UVPML4_INDEX << PDPT_SHIFT)) 30 | #define UVPDPT (UVPD | (UVPML4_INDEX << PD_SHIFT)) 31 | #define UVPML4 (UVPDPT | (UVPML4_INDEX << PT_SHIFT)) 32 | 33 | /* leave one page unmapped at the top of the canonical lower half */ 34 | #define USTACK_TOP (BIT64(47) - PAGE_SIZE) 35 | #define USTACK_SIZE SZ_64K 36 | 37 | /* kernel command line */ 38 | #define UCMDLINE (USTACK_TOP - USTACK_SIZE - 2 * PAGE_SIZE) 39 | 40 | #define UBRK_START SZ_1G 41 | #define UPCI_START SZ_1T 42 | -------------------------------------------------------------------------------- /hv6/mmap.c: -------------------------------------------------------------------------------- 1 | #include "mmap.h" 2 | #include "proc.h" 3 | #include "vm.h" 4 | 5 | static int walk(pn_t pn, size_t index, pn_t *outpn) 6 | { 7 | pte_t *entries, pte; 8 | 9 | entries = get_page(pn); 10 | pte = entries[index]; 11 | if (!pte_valid(pte)) { 12 | *outpn = page_desc_table[0].link.next; 13 | return -ENOENT; 14 | } 15 | 16 | /* invariant: pfn here must be a valid pn */ 17 | *outpn = pfn_to_pn(PTE_ADDR(pte) / PAGE_SIZE); 18 | return 0; 19 | } 20 | 21 | int sys_mmap_page(uintptr_t va, pte_t perm) 22 | { 23 | pid_t pid = current; 24 | size_t index; 25 | pn_t pml4, pdpt, pd, pt, frame; 26 | int r; 27 | 28 | pml4 = get_proc(pid)->page_table_root; 29 | 30 | index = PML4_INDEX(va); 31 | if (walk(pml4, index, &pdpt)) { 32 | r = sys_alloc_pdpt(pid, pml4, index, pdpt, PTE_P|PTE_W); 33 | if (r) 34 | return r; 35 | } 36 | 37 | index = PDPT_INDEX(va); 38 | if (walk(pdpt, index, &pd)) { 39 | r = sys_alloc_pd(pid, pdpt, index, pd, PTE_P|PTE_W); 40 | if (r) 41 | return r; 42 | } 43 | 44 | index = PD_INDEX(va); 45 | if (walk(pd, index, &pt)) { 46 | r = sys_alloc_pd(pid, pd, index, pt, PTE_P|PTE_W); 47 | if (r) 48 | return r; 49 | } 50 | 51 | index = PT_INDEX(va); 52 | if (walk(pt, index, &frame)) { 53 | r = sys_alloc_frame(pid, pt, index, frame, perm); 54 | return r; 55 | } 56 | 57 | /* map_page() returns -EINVAL if the entry exists */ 58 | return -EINVAL; 59 | } 60 | 61 | int sys_munmap_page(uintptr_t va) 62 | { 63 | pn_t pml4, pdpt, pd, pt, frame; 64 | size_t index; 65 | 66 | pml4 = get_proc(current)->page_table_root; 67 | 68 | if (walk(pml4, PML4_INDEX(va), &pdpt)) 69 | goto notfound; 70 | 71 | if (walk(pdpt, PDPT_INDEX(va), &pd)) 72 | goto notfound; 73 | 74 | if (walk(pd, PD_INDEX(va), &pt)) 75 | goto notfound; 76 | 77 | index = PT_INDEX(va); 78 | if (walk(pt, index, &frame)) 79 | goto notfound; 80 | 81 | return sys_free_frame(pt, index, frame); 82 | 83 | notfound: 84 | return -EINVAL; 85 | } 86 | -------------------------------------------------------------------------------- /hv6/mmap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "types.h" 3 | 4 | int sys_mmap_page(uintptr_t va, pte_t perm); 5 | int sys_munmap_page(uintptr_t va); 6 | -------------------------------------------------------------------------------- /hv6/param.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define NPAGE 8192 /* maximum number of pages */ 6 | #define NDMAPAGE 512 /* maximum number of DMA pages */ 7 | #define NPROC 64 /* maximum number of processes */ 8 | #define NTSLICE 128 /* Number of scheduler timeslices */ 9 | #define NOFILE 16 /* open files per process */ 10 | #define NFILE 128 /* open files per system */ 11 | #define MAXARG 32 /* max exec arguments */ 12 | #define MAXPATH 256 /* max path length */ 13 | #define NPCIDEV 64 /* maximum number of PCI devices */ 14 | #define NINTREMAP 8 /* maximum number of interrupt remapping entries */ 15 | #define NPCIPAGE ((PCI_END - PCI_START) / PAGE_SIZE) 16 | -------------------------------------------------------------------------------- /hv6/proc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "fd.h" 5 | #include "vm.h" 6 | 7 | extern struct proc proc_table[NPROC]; 8 | 9 | extern pid_t current; 10 | 11 | int alloc_proc(pid_t pid, pn_t page_table_root, pn_t stack, pn_t hvm); 12 | noreturn void run_current(void); 13 | 14 | /* defined in entry.S */ 15 | int sys_clone(pid_t pid, pn_t pml4, pn_t stack, pn_t hvm); 16 | int sys_set_proc_name(uint64_t name0, uint64_t name1); 17 | int sys_set_runnable(pid_t pid); 18 | /* defined in entry.S */ 19 | int sys_switch(pid_t pid); 20 | int sys_kill(pid_t pid); 21 | int sys_reap(pid_t pid); 22 | int sys_reparent(pid_t pid); 23 | 24 | void preempt(void); 25 | void fault(void); 26 | 27 | static struct proc *get_proc(pid_t pid) 28 | { 29 | assert(is_pid_valid(pid), "pid must be valid"); 30 | return &proc_table[pid]; 31 | } 32 | 33 | static inline bool is_proc_state(pid_t pid, enum proc_state state) 34 | { 35 | return is_pid_valid(pid) && get_proc(pid)->state == state; 36 | } 37 | 38 | /* permission check: we allow a pid to modify itself or its embryo */ 39 | static inline bool is_current_or_embryo(pid_t pid) 40 | { 41 | struct proc *proc; 42 | 43 | if (pid == current) 44 | return true; 45 | proc = get_proc(pid); 46 | if (proc->ppid == current && proc->state == PROC_EMBRYO) 47 | return true; 48 | return false; 49 | } 50 | 51 | static inline fn_t get_fd(pid_t pid, int fd) 52 | { 53 | assert(is_fd_valid(fd), "fd must be valid"); 54 | return get_proc(pid)->ofile[fd]; 55 | } 56 | 57 | static inline bool is_fd_empty(pid_t pid, int fd) 58 | { 59 | return is_fd_valid(fd) && is_fn_valid(get_fd(pid, fd)); 60 | } 61 | 62 | static inline void set_fd(pid_t pid, int fd, fn_t fn) 63 | { 64 | struct proc *proc; 65 | struct file *file; 66 | 67 | assert(get_fd(pid, fd) == 0, "fd must be valid"); 68 | proc = get_proc(pid); 69 | file = get_file(fn); 70 | proc->ofile[fd] = fn; 71 | ++proc->nr_fds; 72 | ++file->refcnt; 73 | } 74 | 75 | static inline void proc_ready_add(struct proc *proc) 76 | { 77 | FREELIST_ADD_TAIL(proc_table, ready, proc - proc_table, current); 78 | } 79 | 80 | static inline void proc_ready_del(struct proc *proc) 81 | { 82 | FREELIST_DEL(proc_table, ready, proc - proc_table); 83 | } 84 | -------------------------------------------------------------------------------- /hv6/spec/kernel/spec/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Hyperkernel Authors 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | from equiv import * 18 | from invariants import * 19 | from specs import * 20 | from top import * 21 | -------------------------------------------------------------------------------- /hv6/spec/user/datatypes.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Hyperkernel Authors 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | from hv6py.base import BaseStruct, Map 18 | import hv6py.kernel.spec.datatypes as kdt 19 | 20 | 21 | class UserState(BaseStruct): 22 | writable = Map(kdt.pid_t, kdt.size_t, kdt.size_t, kdt.size_t, kdt.size_t, kdt.bool_t) 23 | -------------------------------------------------------------------------------- /hv6/syscall.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define SYS_map_page_desc 3 6 | #define SYS_map_pml4 4 7 | #define SYS_map_proc 5 8 | #define SYS_map_dev 6 9 | #define SYS_map_file 7 10 | #define SYS_clone 10 11 | #define SYS_set_proc_name 11 12 | #define SYS_set_runnable 12 13 | #define SYS_switch 13 14 | #define SYS_kill 14 15 | #define SYS_reap 16 16 | #define SYS_reparent 17 17 | #define SYS_alloc_pdpt 20 18 | #define SYS_alloc_pd 21 19 | #define SYS_alloc_pt 22 20 | #define SYS_alloc_frame 23 21 | #define SYS_copy_frame 24 22 | #define SYS_protect_frame 25 23 | #define SYS_free_pdpt 26 24 | #define SYS_free_pd 27 25 | #define SYS_free_pt 28 26 | #define SYS_free_frame 29 27 | #define SYS_reclaim_page 30 28 | #define SYS_create 34 29 | #define SYS_close 35 30 | #define SYS_dup 36 31 | #define SYS_dup2 37 32 | #define SYS_lseek 38 33 | #define SYS_send 40 34 | #define SYS_recv 41 35 | #define SYS_reply_wait 42 36 | #define SYS_call 43 37 | #define SYS_map_pcipage 46 38 | #define SYS_alloc_iommu_root 47 39 | #define SYS_alloc_iommu_pdpt 48 40 | #define SYS_alloc_iommu_pd 49 41 | #define SYS_alloc_iommu_pt 50 42 | #define SYS_alloc_iommu_frame 51 43 | #define SYS_map_iommu_frame 52 44 | #define SYS_reclaim_iommu_frame 53 45 | #define SYS_reclaim_iommu_root 54 46 | #define SYS_alloc_vector 55 47 | #define SYS_reclaim_vector 56 48 | #define SYS_alloc_intremap 57 49 | #define SYS_reclaim_intremap 58 50 | #define SYS_ack_intr 59 51 | #define SYS_alloc_io_bitmap 70 52 | #define SYS_alloc_port 71 53 | #define SYS_reclaim_port 72 54 | #define SYS_mmap_page 80 55 | #define SYS_munmap_page 81 56 | #define SYS_debug_exit 123 57 | #define SYS_debug_print_console 124 58 | #define SYS_debug_print_screen 125 59 | #define SYS_debug_dmesg 126 60 | #define SYS_debug_sysctl 127 61 | -------------------------------------------------------------------------------- /hv6/sysctl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "types.h" 6 | 7 | uint64_t sys_debug_sysctl(uint64_t id) 8 | { 9 | switch (id) { 10 | case SYSCTL_ECAM_ADDRESS: 11 | return pci_config_base; 12 | case SYSCTL_IOMMU_VENDOR: 13 | return iommu_vendor; 14 | case SYSCTL_TSC_KHZ: 15 | return ms_to_cycles(1); 16 | } 17 | 18 | return UINT64_MAX; 19 | } 20 | -------------------------------------------------------------------------------- /hv6/test.py: -------------------------------------------------------------------------------- 1 | import signal 2 | import re 3 | import os 4 | import subprocess 5 | import unittest 6 | 7 | DEVNULL = open(os.devnull, 'wb') 8 | 9 | 10 | class TestCase(unittest.TestCase): 11 | def runQemu(self, cmd): 12 | args = "make hv6-qemu QEMUEXTRA='-device isa-debug-exit -append \"%s\"'" % ( 13 | cmd,) 14 | try: 15 | self.output = subprocess.check_output( 16 | args, shell=True, stderr=DEVNULL) 17 | except subprocess.CalledProcessError as err: 18 | self.output = err.output 19 | 20 | def assertRegexpMatches(self, text, expected_regexp, msg=None): 21 | # patch multiline 22 | if isinstance(expected_regexp, basestring): 23 | expected_regexp = re.compile(expected_regexp, re.MULTILINE) 24 | if not expected_regexp.search(text): 25 | msg = msg or "Regexp didn't match" 26 | msg = '%s: %r not found in %r' % ( 27 | msg, expected_regexp.pattern, text) 28 | raise self.failureException(msg) 29 | 30 | def assertMatch(self, *args): 31 | for r in args: 32 | self.assertRegexpMatches(self.output, r) 33 | 34 | 35 | class TestCmds(TestCase): 36 | def test_hello(self): 37 | self.runQemu("hello") 38 | self.assertMatch(r"^Hello from Linux$") 39 | 40 | def test_ls(self): 41 | self.runQemu("ls") 42 | self.assertMatch(r"^\.\s*1\s*1") 43 | self.assertMatch(r"^\..\s*1\s*1") 44 | self.assertMatch(r"^README.md\s*2") 45 | self.assertMatch(r"^console\s*3") 46 | 47 | 48 | if __name__ == "__main__": 49 | signal.alarm(30) 50 | unittest.main() 51 | -------------------------------------------------------------------------------- /hv6/trap.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | static struct gate_desc idt[256] = {{0}}; 9 | 10 | static struct pseudo_desc idt_desc = { 11 | sizeof(idt) - 1, (uint64_t)idt, 12 | }; 13 | 14 | void trap_init(void) 15 | { 16 | size_t i; 17 | extern void *trap_vectors[]; 18 | 19 | for (i = 0; i < countof(idt); ++i) 20 | set_gate_desc(&idt[i], 0, GDT_CS, trap_vectors[i], KERNEL_PL); 21 | lidt(&idt_desc); 22 | } 23 | 24 | void trap(struct trap_frame *tf, uint8_t nr) 25 | { 26 | /* svm helper for external interrupts */ 27 | if (nr >= TRAP_IRQ0) { 28 | if (hvm_extintr) 29 | hvm_extintr(nr); 30 | xapic_eoi(); 31 | return; 32 | } 33 | 34 | panic("trap %d err %lu on rip 0x%lx addr 0x%lx", nr, tf->err, tf->rip, 35 | rcr2()); 36 | } 37 | -------------------------------------------------------------------------------- /hv6/trap_entry.S: -------------------------------------------------------------------------------- 1 | ../user/trap_entry.S -------------------------------------------------------------------------------- /hv6/user/bench.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * bench.h - shared definitions for all benchmarks 4 | */ 5 | 6 | #define NRPGS 100 7 | #define N 10000 8 | 9 | static inline void synch_tsc(void) 10 | { 11 | asm volatile("cpuid" : : : "%rax", "%rbx", "%rcx", "%rdx"); 12 | } 13 | 14 | static inline unsigned long rdtscll(void) 15 | { 16 | unsigned int a, d; 17 | asm volatile("rdtsc" : "=a"(a), "=d"(d) : : "%rbx", "%rcx"); 18 | return ((unsigned long)a) | (((unsigned long)d) << 32); 19 | } 20 | 21 | static inline unsigned long rdtscllp(void) 22 | { 23 | unsigned int a, d; 24 | asm volatile("rdtscp" : "=a"(a), "=d"(d) : : "%rbx", "%rcx"); 25 | return ((unsigned long)a) | (((unsigned long)d) << 32); 26 | } 27 | 28 | static unsigned long measure_tsc_overhead(void) 29 | { 30 | unsigned long t0, t1, overhead = ~0UL; 31 | int i; 32 | 33 | for (i = 0; i < N; i++) { 34 | t0 = rdtscll(); 35 | asm volatile(""); 36 | t1 = rdtscllp(); 37 | if (t1 - t0 < overhead) 38 | overhead = t1 - t0; 39 | } 40 | 41 | return overhead; 42 | } 43 | -------------------------------------------------------------------------------- /hv6/user/bounce.c: -------------------------------------------------------------------------------- 1 | #include "stat.h" 2 | #include "types.h" 3 | #include "user.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | pid_t self; 8 | 9 | fork(); 10 | self = getpid(); 11 | for (int i = 0;; ++i) printf(1, "Hello from %ld: %d\n", self, i); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /hv6/user/cat.c: -------------------------------------------------------------------------------- 1 | #include "stat.h" 2 | #include "types.h" 3 | #include "user.h" 4 | 5 | char buf[512]; 6 | 7 | void cat(int fd) 8 | { 9 | int n; 10 | 11 | while ((n = read(fd, buf, sizeof(buf))) > 0) { 12 | if (write(1, buf, n) != n) { 13 | printf(1, "cat: write error\n"); 14 | exit(); 15 | } 16 | } 17 | if (n < 0) { 18 | printf(1, "cat: read error\n"); 19 | exit(); 20 | } 21 | } 22 | 23 | int main(int argc, char *argv[]) 24 | { 25 | int fd, i; 26 | 27 | if (argc <= 1) { 28 | cat(0); 29 | exit(); 30 | } 31 | 32 | for (i = 1; i < argc; i++) { 33 | if ((fd = open(argv[i], 0)) < 0) { 34 | printf(1, "cat: cannot open %s\n", argv[i]); 35 | exit(); 36 | } 37 | cat(fd); 38 | close(fd); 39 | } 40 | exit(); 41 | } 42 | -------------------------------------------------------------------------------- /hv6/user/daytime.c: -------------------------------------------------------------------------------- 1 | #include "socket.h" 2 | #include "user.h" 3 | 4 | /* RFC 867: Daytime Protocol */ 5 | #define SERVER_HOST "utcnist.colorado.edu" 6 | #define SERVER_PORT 13 7 | 8 | int main(int argc, char **argv) 9 | { 10 | struct hostent *hp; 11 | int sockfd, r; 12 | struct sockaddr_in addr = { 13 | .sin_family = PF_INET, .sin_port = htons(SERVER_PORT), 14 | }; 15 | 16 | hp = gethostbyname(SERVER_HOST); 17 | assert(hp, "gethostbyname"); 18 | addr.sin_addr = *(struct in_addr *)(hp->h_addr); 19 | dprintf(1, "daytime: %s %s\n", hp->h_name, inet_ntoa(addr.sin_addr)); 20 | 21 | sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 22 | assert(sockfd >= 0, "socket"); 23 | 24 | r = connect(sockfd, (const struct sockaddr *)&addr, sizeof(struct sockaddr_in)); 25 | assert(r == 0, "connect"); 26 | 27 | while (1) { 28 | char buf[512]; 29 | ssize_t n; 30 | 31 | n = recv(sockfd, buf, sizeof(buf), 0); 32 | if (n <= 0) 33 | break; 34 | write(1, buf, n); 35 | } 36 | 37 | close(sockfd); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /hv6/user/dmesg.c: -------------------------------------------------------------------------------- 1 | #include "user.h" 2 | 3 | static char buf[PAGE_SIZE] __aligned(PAGE_SIZE); 4 | 5 | int main(int argc, char **argv) 6 | { 7 | int r; 8 | size_t offset = 0; 9 | 10 | while (1) { 11 | r = sys_debug_dmesg(virt_to_phys(buf), sizeof(buf), offset); 12 | if (r <= 0) 13 | break; 14 | write(1, buf, r); 15 | offset += r; 16 | } 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /hv6/user/echo.c: -------------------------------------------------------------------------------- 1 | #include "user.h" 2 | 3 | int main(int argc, char *argv[]) 4 | { 5 | int i; 6 | 7 | for (i = 1; i < argc; i++) 8 | printf(1, "%s%s", argv[i], i + 1 < argc ? " " : "\n"); 9 | exit(); 10 | } 11 | -------------------------------------------------------------------------------- /hv6/user/fault.c: -------------------------------------------------------------------------------- 1 | #include "user.h" 2 | 3 | static void test(struct trap_frame *tf) 4 | { 5 | dprintf(2, "fault: address 0x%016" PRIx64 "\n", rcr2()); 6 | inb(0); 7 | } 8 | 9 | int main(int argc, char **argv) 10 | { 11 | volatile int *p = NULL; 12 | 13 | register_trap_handler(TRAP_PF, test); 14 | *p = 0xdead; 15 | exit(); 16 | } 17 | -------------------------------------------------------------------------------- /hv6/user/fcntl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define O_RDONLY 00000000 4 | #define O_WRONLY 00000001 5 | #define O_RDWR 00000002 6 | 7 | #define O_CREAT 00000100 8 | #define O_EXCL 00000200 9 | #define O_TRUNC 00001000 10 | #define O_APPEND 00002000 11 | #define O_CLOEXEC 02000000 12 | -------------------------------------------------------------------------------- /hv6/user/freelist.c: -------------------------------------------------------------------------------- 1 | #include "user.h" 2 | 3 | static void freelist(void) 4 | { 5 | static bool freelist[NPAGE]; 6 | pn_t i; 7 | size_t count; 8 | 9 | for (i = upages[0].link.next, count = 0; i != 0; i = upages[i].link.next) { 10 | freelist[i] = true; 11 | assert(upages[i].type == PAGE_TYPE_FREE, "must be free page"); 12 | count++; 13 | } 14 | printf(1, "Found %zu free pages in freelist\n", count); 15 | 16 | for (i = 0, count = 0; i < NPAGE; i++) 17 | if (upages[i].type == PAGE_TYPE_FREE && !freelist[i]) 18 | count++; 19 | 20 | printf(1, "Found %zu free pages not in freelist\n", count); 21 | } 22 | 23 | int main(int argc, char *argv[]) 24 | { 25 | freelist(); 26 | exit(); 27 | } 28 | -------------------------------------------------------------------------------- /hv6/user/fs/ide.c: -------------------------------------------------------------------------------- 1 | #include "fs.h" 2 | 3 | void iderw(struct buf *b) 4 | { 5 | if (!(b->flags & B_BUSY)) 6 | panic("iderw: buf not busy"); 7 | if ((b->flags & (B_VALID | B_DIRTY)) == B_VALID) 8 | panic("iderw: nothing to do"); 9 | 10 | if (b->flags & B_DIRTY) { 11 | unix_write(b->sector, b->data); 12 | b->flags &= ~B_DIRTY; 13 | } else { 14 | unix_read(b->sector, b->data); 15 | b->flags |= B_VALID; 16 | } 17 | } 18 | 19 | void ideflush() 20 | { 21 | unix_flush(); 22 | } 23 | -------------------------------------------------------------------------------- /hv6/user/fs/memdisk.c: -------------------------------------------------------------------------------- 1 | #if ENABLED(CONFIG_MEMFS) 2 | 3 | #include "fs.h" 4 | 5 | extern char _binary_fs_img_start[], _binary_fs_img_end[]; 6 | 7 | void unix_init(void) 8 | { 9 | pr_info("fs: use memfs\n"); 10 | } 11 | 12 | void unix_read(uint64_t block, void *buf) 13 | { 14 | memcpy(buf, _binary_fs_img_start + block * BSIZE, BSIZE); 15 | } 16 | 17 | void unix_write(uint64_t block, const void *buf) 18 | { 19 | memcpy(_binary_fs_img_start + block * BSIZE, buf, BSIZE); 20 | } 21 | 22 | void unix_flush(void) 23 | { 24 | } 25 | #endif /* CONFIG_MEMFS */ 26 | -------------------------------------------------------------------------------- /hv6/user/fs/memfs.S: -------------------------------------------------------------------------------- 1 | #if ENABLED(CONFIG_MEMFS) 2 | 3 | #include 4 | 5 | .section .data 6 | 7 | .global _binary_fs_img_start 8 | .global _binary_fs_img_end 9 | 10 | .balign PAGE_SIZE 11 | _binary_fs_img_start: 12 | .incbin "fs.img" 13 | _binary_fs_img_end: 14 | 15 | #endif /* CONFIG_MEMFS */ 16 | -------------------------------------------------------------------------------- /hv6/user/fs/pipe.c: -------------------------------------------------------------------------------- 1 | #include "fs.h" 2 | 3 | #define PIPESIZE 512 4 | 5 | struct pipe { 6 | struct spinlock lock; 7 | char data[PIPESIZE]; 8 | uint nread; /* number of bytes read */ 9 | uint nwrite; /* number of bytes written */ 10 | int readopen; /* read fd is still open */ 11 | int writeopen; /* write fd is still open */ 12 | }; 13 | 14 | int pipealloc(int fds[2]) 15 | { 16 | struct pipe *p; 17 | int fd0, fd1, r; 18 | 19 | p = malloc(sizeof(struct pipe)); 20 | assert(p, "malloc"); 21 | p->readopen = 1; 22 | p->writeopen = 1; 23 | p->nwrite = 0; 24 | p->nread = 0; 25 | 26 | fd0 = find_lowest_free_fd(); 27 | fd1 = find_free_fd(fd0 + 1); 28 | r = sys_create(fd0, find_free_fn(), FD_PIPE, (uintptr_t)p, O_RDONLY); 29 | assert(r == 0, "sys_create"); 30 | r = sys_create(fd1, find_free_fn(), FD_PIPE, (uintptr_t)p, O_WRONLY); 31 | assert(r == 0, "sys_create"); 32 | fds[0] = fd0; 33 | fds[1] = fd1; 34 | return 0; 35 | } 36 | 37 | void pipeclose(struct pipe *p, int writable) 38 | { 39 | acquire(&p->lock); 40 | if (writable) { 41 | p->writeopen = 0; 42 | wakeup(&p->nread); 43 | } else { 44 | p->readopen = 0; 45 | wakeup(&p->nwrite); 46 | } 47 | if (p->readopen == 0 && p->writeopen == 0) { 48 | release(&p->lock); 49 | free((char *)p); 50 | } else 51 | release(&p->lock); 52 | } 53 | 54 | int pipewrite(struct pipe *p, char *addr, int n) 55 | { 56 | int i; 57 | 58 | acquire(&p->lock); 59 | for (i = 0; i < n; i++) { 60 | /* pipewrite-full */ 61 | if (p->nwrite == p->nread + PIPESIZE) { 62 | if (p->readopen == 0) { 63 | release(&p->lock); 64 | return -EPIPE; 65 | } 66 | release(&p->lock); 67 | return i ? i : -EAGAIN; 68 | } 69 | p->data[p->nwrite++ % PIPESIZE] = addr[i]; 70 | } 71 | release(&p->lock); 72 | return n; 73 | } 74 | 75 | int piperead(struct pipe *p, char *addr, int n) 76 | { 77 | int i; 78 | 79 | acquire(&p->lock); 80 | /* pipe-empty */ 81 | if (p->nread == p->nwrite && p->writeopen) { 82 | release(&p->lock); 83 | return -EAGAIN; 84 | } 85 | for (i = 0; i < n; i++) { 86 | if (p->nread == p->nwrite) 87 | break; 88 | addr[i] = p->data[p->nread++ % PIPESIZE]; 89 | } 90 | release(&p->lock); 91 | return i; 92 | } 93 | -------------------------------------------------------------------------------- /hv6/user/fs/stat.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define T_DIR 1 /* directory */ 6 | #define T_FILE 2 /* file */ 7 | #define T_DEV 3 /* device */ 8 | 9 | struct stat { 10 | short type; /* type of file */ 11 | int dev; /* file system's disk device */ 12 | uint32_t ino; /* inode number */ 13 | short nlink; /* number of links to file */ 14 | uint32_t size; /* size of file in bytes */ 15 | int atime; 16 | int mtime; 17 | int ctime; 18 | }; 19 | -------------------------------------------------------------------------------- /hv6/user/fs/uiommu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "user.h" 4 | 5 | pn_t iommu_alloc_root(size_t i, uintptr_t va, int bar); 6 | void iommu_map(pn_t root, void *va, size_t n); 7 | -------------------------------------------------------------------------------- /hv6/user/genustub.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import fileinput 4 | 5 | for line in fileinput.input(): 6 | e = line.strip().split() 7 | assert len(e) == 3 8 | addr, typ, name = e 9 | if typ != 'T': 10 | continue 11 | if name in ['_start', 'main']: 12 | continue 13 | print('.global\t{}'.format(name)) 14 | print('{}:'.format(name)) 15 | print('\tmovq\t$0x{}, %rax'.format(addr)) 16 | print('\tjmpq\t*%rax') 17 | print('') 18 | -------------------------------------------------------------------------------- /hv6/user/httpget.c: -------------------------------------------------------------------------------- 1 | #include "socket.h" 2 | #include "user.h" 3 | 4 | int main(int argc, char **argv) 5 | { 6 | const char *url, *path; 7 | char host[64], buf[512]; 8 | ssize_t i, n; 9 | struct hostent *hp; 10 | int sockfd, r; 11 | struct sockaddr_in addr = { 12 | .sin_family = PF_INET, .sin_port = htons(80), 13 | }; 14 | 15 | if (argc < 2) { 16 | dprintf(2, "usage: httpget url\n"); 17 | return 0; 18 | } 19 | url = argv[1]; 20 | 21 | path = strchr(url, '/'); 22 | if (path) { 23 | memcpy(host, url, path - url); 24 | host[path - url] = 0; 25 | } else { 26 | strcpy(host, url); 27 | path = "/"; 28 | } 29 | 30 | hp = gethostbyname(host); 31 | assert(hp, "gethostbyname"); 32 | addr.sin_addr = *(struct in_addr *)(hp->h_addr); 33 | dprintf(1, "* Trying %s (%s)\n", hp->h_name, inet_ntoa(addr.sin_addr)); 34 | 35 | sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 36 | assert(sockfd >= 0, "socket"); 37 | 38 | r = connect(sockfd, (const struct sockaddr *)&addr, sizeof(struct sockaddr_in)); 39 | assert(r == 0, "connect"); 40 | 41 | /* send http request */ 42 | snprintf(buf, sizeof(buf), "GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: curl\r\n\r\n", path, host); 43 | for (i = 0, n = strlen(buf); i < n;) { 44 | r = send(sockfd, buf + i, n - i, 0); 45 | assert(r > 0, "send"); 46 | i += r; 47 | } 48 | write(1, buf, n); 49 | 50 | /* print http response */ 51 | while (1) { 52 | n = recv(sockfd, buf, sizeof(buf), 0); 53 | if (n <= 0) 54 | break; 55 | write(1, buf, n); 56 | } 57 | 58 | close(sockfd); 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /hv6/user/init.c: -------------------------------------------------------------------------------- 1 | #include "user.h" 2 | 3 | noreturn void fs_main(void); 4 | 5 | noreturn void main(void) 6 | { 7 | pid_t pid; 8 | int r; 9 | 10 | set_proc_name("init"); 11 | 12 | /* start file server */ 13 | pid = fork(); 14 | if (!pid) 15 | fs_main(); 16 | /* wait until fs starts */ 17 | assert(pid == FSPID, "fs pid must be FSPID"); 18 | while (uprocs[pid].state != PROC_SLEEPING) 19 | yield(); 20 | 21 | /* start network server */ 22 | pid = spawnl("ns", "ns", NULL); 23 | /* wait until ns starts */ 24 | assert(pid == NSPID, "ns pid must be NSPID"); 25 | while (uprocs[pid].state != PROC_SLEEPING && uprocs[pid].state != PROC_ZOMBIE) 26 | yield(); 27 | 28 | /* stdin */ 29 | r = open("console", O_RDWR); 30 | if (r < 0) { 31 | r = mknod("console", DEV_CONSOLE, 0); 32 | assert(r == 0, "mknod"); 33 | r = open("console", O_RDWR); 34 | } 35 | assert(r == 0, "open: 0"); 36 | 37 | /* stdout */ 38 | r = dup(0); 39 | assert(r == 1, "dup: 0 -> 1"); 40 | 41 | /* stderr */ 42 | r = dup(0); 43 | assert(r == 2, "dup: 0 -> 2"); 44 | 45 | /* run unittests from kernel command line */ 46 | if (is_page_mapped(UCMDLINE)) { 47 | char *p; 48 | 49 | p = strchr((void *)(uintptr_t)UCMDLINE, ' '); 50 | if (p && *(p + 1)) { 51 | cprintf("init: run %s\n", p + 1); 52 | r = system(p + 1); 53 | sys_debug_exit(r); 54 | } 55 | } 56 | 57 | /* start app servers */ 58 | if (uprocs[NSPID].state != PROC_ZOMBIE) { 59 | dprintf(1, "init: starting httpd\n"); 60 | spawnl("httpd", "httpd", NULL); 61 | dprintf(1, "init: starting vncd\n"); 62 | spawnl("vncd", "vncd", NULL); 63 | } 64 | 65 | /* start sh */ 66 | dprintf(1, "init: starting sh\n"); 67 | while (1) { 68 | pid = spawnl("sh", "sh", NULL); 69 | while (pid != wait()) 70 | ; 71 | } 72 | panic("TBD"); 73 | } 74 | -------------------------------------------------------------------------------- /hv6/user/initcode.S: -------------------------------------------------------------------------------- 1 | #include "memlayout.h" 2 | 3 | .section .text 4 | 5 | .global _start 6 | _start: 7 | movq $stack_top, %rsp 8 | /* ulib entry point */ 9 | movq $0xffffffff80000000, %rax 10 | call *%rax 11 | /* return from ulib_init */ 12 | call main 13 | spin: 14 | jmp spin 15 | 16 | .section .bss 17 | .balign PAGE_SIZE 18 | .space USTACK_SIZE 19 | stack_top: 20 | -------------------------------------------------------------------------------- /hv6/user/kill.c: -------------------------------------------------------------------------------- 1 | #include "stat.h" 2 | #include "types.h" 3 | #include "user.h" 4 | 5 | int main(int argc, char **argv) 6 | { 7 | int i; 8 | 9 | if (argc < 2) { 10 | printf(2, "usage: kill pid...\n"); 11 | exit(); 12 | } 13 | for (i = 1; i < argc; i++) 14 | kill(atoi(argv[i])); 15 | exit(); 16 | } 17 | -------------------------------------------------------------------------------- /hv6/user/lib/trap.c: -------------------------------------------------------------------------------- 1 | ../../../user/trap.c -------------------------------------------------------------------------------- /hv6/user/lib/trap_entry.S: -------------------------------------------------------------------------------- 1 | ../../../user/trap_entry.S -------------------------------------------------------------------------------- /hv6/user/lib/ubrk.c: -------------------------------------------------------------------------------- 1 | #include "user.h" 2 | 3 | static uintptr_t brk_ptr; 4 | 5 | static uintptr_t allocuvm(uintptr_t oldsz, uintptr_t newsz) 6 | { 7 | uintptr_t a; 8 | pid_t pid = getpid(); 9 | int r; 10 | 11 | assert(oldsz <= newsz, "newsz should be larger"); 12 | 13 | a = roundup(oldsz, PAGE_SIZE); 14 | for (; a < newsz; a += PAGE_SIZE) { 15 | pn_t pt, frame; 16 | 17 | pt = page_walk(a); 18 | frame = find_free_page(); 19 | r = sys_alloc_frame(pid, pt, PT_INDEX(a), frame, PTE_P | PTE_W); 20 | assert(r == 0, "sys_alloc_frame"); 21 | } 22 | return newsz; 23 | } 24 | 25 | static uintptr_t deallocuvm(uintptr_t oldsz, uintptr_t newsz) 26 | { 27 | uintptr_t a; 28 | int r; 29 | 30 | assert(oldsz >= newsz, "newsz should be smaller"); 31 | 32 | a = roundup(newsz, PAGE_SIZE); 33 | for (; a < oldsz; a += PAGE_SIZE) { 34 | pn_t pt, frame; 35 | 36 | pt = page_walk(a); 37 | frame = virt_to_pn((void *)a); 38 | r = sys_free_frame(pt, PT_INDEX(a), frame); 39 | assert(r == 0, "sys_free_frame"); 40 | } 41 | return newsz; 42 | } 43 | 44 | void *sbrk(intptr_t n) 45 | { 46 | uintptr_t result = brk_ptr, sz = brk_ptr; 47 | 48 | if (n > 0) { 49 | sz = allocuvm(sz, sz + n); 50 | assert(sz, "allocuvm failed"); 51 | } else if (n < 0) { 52 | sz = deallocuvm(sz, sz + n); 53 | } 54 | brk_ptr = sz; 55 | return (void *)result; 56 | } 57 | 58 | /* internal use */ 59 | void reset_ubrk(uintptr_t va) 60 | { 61 | brk_ptr = va; 62 | } 63 | -------------------------------------------------------------------------------- /hv6/user/lib/ulib.lds: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH(i386:x86-64) 2 | 3 | ENTRY(_start) 4 | 5 | SECTIONS 6 | { 7 | . = 0xffffffff80000000; 8 | 9 | .text : { 10 | *(.head.text) 11 | *(.text .text.*) 12 | } 13 | 14 | .rodata : { 15 | *(.rodata .rodata.*) 16 | } 17 | 18 | .data : { 19 | *(.data .data.*) 20 | } 21 | 22 | .bss : { 23 | *(.bss .bss.*) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /hv6/user/lib/ulib_entry.S: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | .section .head.text 4 | 5 | .global _start 6 | _start: 7 | push %rbp 8 | movq %rsp, %rbp 9 | movq $ulib_stack_top, %rsp 10 | call ulib_init 11 | movq %rbp, %rsp 12 | pop %rbp 13 | ret 14 | 15 | .section .bss 16 | .balign PAGE_SIZE 17 | .global ulib_stack_top 18 | .space SZ_64K 19 | ulib_stack_top: 20 | -------------------------------------------------------------------------------- /hv6/user/linux/bench_linux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uw-unsat/hyperkernel/50d6bada5de63c56376bdc4dba6159788847cc95/hv6/user/linux/bench_linux -------------------------------------------------------------------------------- /hv6/user/linux/compile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uw-unsat/hyperkernel/50d6bada5de63c56376bdc4dba6159788847cc95/hv6/user/linux/compile -------------------------------------------------------------------------------- /hv6/user/linux/gzip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uw-unsat/hyperkernel/50d6bada5de63c56376bdc4dba6159788847cc95/hv6/user/linux/gzip -------------------------------------------------------------------------------- /hv6/user/linux/hello: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uw-unsat/hyperkernel/50d6bada5de63c56376bdc4dba6159788847cc95/hv6/user/linux/hello -------------------------------------------------------------------------------- /hv6/user/linux/hello.c: -------------------------------------------------------------------------------- 1 | int printf(const char * format, ...); 2 | double sqrt(double x); 3 | 4 | int main(void) 5 | { 6 | printf("Hello from Linux\n"); 7 | printf("sqrt(2) = %f\n", sqrt(2)); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /hv6/user/linux/hello.lua: -------------------------------------------------------------------------------- 1 | -- https://www.lua.org/cgi-bin/demo?hello 2 | -- 3 | -- hello.lua 4 | -- the first program in every language 5 | 6 | io.write("Hello world, from ",_VERSION,"!\n") 7 | -------------------------------------------------------------------------------- /hv6/user/linux/lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uw-unsat/hyperkernel/50d6bada5de63c56376bdc4dba6159788847cc95/hv6/user/linux/lua -------------------------------------------------------------------------------- /hv6/user/linux/sha1sum: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uw-unsat/hyperkernel/50d6bada5de63c56376bdc4dba6159788847cc95/hv6/user/linux/sha1sum -------------------------------------------------------------------------------- /hv6/user/linux/tcc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uw-unsat/hyperkernel/50d6bada5de63c56376bdc4dba6159788847cc95/hv6/user/linux/tcc -------------------------------------------------------------------------------- /hv6/user/linux/ter-x16n.psf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uw-unsat/hyperkernel/50d6bada5de63c56376bdc4dba6159788847cc95/hv6/user/linux/ter-x16n.psf -------------------------------------------------------------------------------- /hv6/user/linux/test.smt2: -------------------------------------------------------------------------------- 1 | (declare-fun q () Bool) 2 | (declare-fun p () Bool) 3 | (assert 4 | (=> p q)) 5 | (assert 6 | p) 7 | (assert 8 | (not q)) 9 | (check-sat) 10 | -------------------------------------------------------------------------------- /hv6/user/linux/z3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uw-unsat/hyperkernel/50d6bada5de63c56376bdc4dba6159788847cc95/hv6/user/linux/z3 -------------------------------------------------------------------------------- /hv6/user/ls.c: -------------------------------------------------------------------------------- 1 | #include "fs.h" 2 | 3 | char *fmtname(char *path) 4 | { 5 | static char buf[16]; 6 | char *p; 7 | 8 | /* find first character after last slash */ 9 | for (p = path + strlen(path); p >= path && *p != '/'; p--) 10 | ; 11 | p++; 12 | 13 | /* return blank-padded name */ 14 | if (strlen(p) >= sizeof(buf) - 1) 15 | return p; 16 | memmove(buf, p, strlen(p)); 17 | memset(buf + strlen(p), ' ', sizeof(buf) - 1 - strlen(p)); 18 | return buf; 19 | } 20 | 21 | void ls(char *path) 22 | { 23 | char buf[512], *p; 24 | int fd; 25 | struct dirent de; 26 | struct stat st; 27 | 28 | if ((fd = open(path, 0)) < 0) { 29 | printf(2, "ls: cannot open %s\n", path); 30 | return; 31 | } 32 | 33 | if (fstat(fd, &st) < 0) { 34 | printf(2, "ls: cannot stat %s\n", path); 35 | close(fd); 36 | return; 37 | } 38 | 39 | switch (st.type) { 40 | case T_FILE: 41 | printf(1, "%s %d %u %u\n", fmtname(path), st.type, st.ino, st.size); 42 | break; 43 | 44 | case T_DIR: 45 | if (strlen(path) + 1 + DIRSIZ + 1 > sizeof buf) { 46 | printf(1, "ls: path too long\n"); 47 | break; 48 | } 49 | strcpy(buf, path); 50 | p = buf + strlen(buf); 51 | *p++ = '/'; 52 | while (read(fd, &de, sizeof(de)) == sizeof(de)) { 53 | if (de.inum == 0) 54 | continue; 55 | memmove(p, de.name, DIRSIZ); 56 | p[DIRSIZ] = 0; 57 | if (stat(buf, &st) < 0) { 58 | printf(1, "ls: cannot stat %s\n", buf); 59 | continue; 60 | } 61 | printf(1, "%s %d %u %u\n", fmtname(buf), st.type, st.ino, st.size); 62 | } 63 | break; 64 | } 65 | close(fd); 66 | } 67 | 68 | int main(int argc, char *argv[]) 69 | { 70 | int i; 71 | 72 | if (argc < 2) { 73 | ls("."); 74 | exit(); 75 | } 76 | for (i = 1; i < argc; i++) 77 | ls(argv[i]); 78 | exit(); 79 | } 80 | -------------------------------------------------------------------------------- /hv6/user/lwip: -------------------------------------------------------------------------------- 1 | ../../user/lwip -------------------------------------------------------------------------------- /hv6/user/lwipopts.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* no threads, semaphores, mutexes, mboxes */ 4 | #define NO_SYS 1 5 | 6 | #define SYS_LIGHTWEIGHT_PROT 0 7 | 8 | #define LWIP_NETCONN 0 9 | #define LWIP_SOCKET 0 10 | 11 | #define LWIP_ARP 1 12 | #define LWIP_DHCP 1 13 | #define LWIP_DNS 1 14 | #define LWIP_ETHERNET 1 15 | 16 | #define LWIP_DEBUG 1 17 | #if 0 18 | #define DHCP_DEBUG LWIP_DBG_ON 19 | #define NETIF_DEBUG LWIP_DBG_ON 20 | #define TCP_OUTPUT_DEBUG LWIP_DBG_ON 21 | #endif 22 | 23 | #define LWIP_EVENT_API 1 24 | 25 | #define TCP_LISTEN_BACKLOG 1 26 | 27 | #define SO_REUSE 1 28 | -------------------------------------------------------------------------------- /hv6/user/mkdir.c: -------------------------------------------------------------------------------- 1 | #include "stat.h" 2 | #include "types.h" 3 | #include "user.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | int i; 8 | 9 | if (argc < 2) { 10 | printf(2, "Usage: mkdir files...\n"); 11 | exit(); 12 | } 13 | 14 | for (i = 1; i < argc; i++) { 15 | if (mkdir(argv[i], 0777) < 0) { 16 | printf(2, "mkdir: %s failed to create\n", argv[i]); 17 | break; 18 | } 19 | } 20 | 21 | exit(); 22 | } 23 | -------------------------------------------------------------------------------- /hv6/user/ns.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "user.h" 4 | 5 | enum { 6 | NSIPC_TIMER = 1, 7 | NSIPC_GETHOSTBYNAME, 8 | NSIPC_SOCKET, 9 | NSIPC_GETSOCKOPT, 10 | NSIPC_CONNECT, 11 | NSIPC_BIND, 12 | NSIPC_LISTEN, 13 | NSIPC_ACCEPT, 14 | NSIPC_SEND, 15 | NSIPC_RECV, 16 | }; 17 | 18 | struct nsipc_ping { 19 | union { 20 | struct { 21 | int domain; 22 | int type; 23 | int protocol; 24 | } socket; 25 | struct { 26 | int sockfd; 27 | int level; 28 | int optname; 29 | } getsockopt; 30 | struct { 31 | int sockfd; 32 | uint32_t addr; 33 | uint16_t port; 34 | } connect; 35 | struct { 36 | int sockfd; 37 | uint32_t addr; 38 | uint16_t port; 39 | } bind; 40 | struct { 41 | int sockfd; 42 | int backlog; 43 | } listen; 44 | struct { 45 | int sockfd; 46 | } accept; 47 | struct { 48 | int sockfd; 49 | int flags; 50 | char buf[]; 51 | } send; 52 | struct { 53 | int sockfd; 54 | int len; 55 | int flags; 56 | } recv; 57 | }; 58 | }; 59 | 60 | struct nsipc_pong { 61 | union { 62 | struct { 63 | uint32_t addr; 64 | uint16_t port; 65 | } accept; 66 | }; 67 | }; 68 | -------------------------------------------------------------------------------- /hv6/user/ps.c: -------------------------------------------------------------------------------- 1 | #include "user.h" 2 | 3 | static const char *proc_state_names[] = { 4 | [PROC_UNUSED] = "UNUSED ", [PROC_EMBRYO] = "EMBRYO ", [PROC_RUNNABLE] = "RUNNABLE", 5 | [PROC_RUNNING] = "RUNNING ", [PROC_SLEEPING] = "SLEEPING", [PROC_ZOMBIE] = "ZOMBIE ", 6 | }; 7 | 8 | static void spaces(uint64_t x, size_t n) 9 | { 10 | size_t i; 11 | 12 | if (x == 0) { 13 | i = 1; 14 | } else { 15 | for (i = 0; x; x /= 10) 16 | ++i; 17 | } 18 | 19 | for (; i < n; ++i) 20 | printf(1, " "); 21 | } 22 | 23 | static void ps(void) 24 | { 25 | pid_t pid; 26 | 27 | printf(1, " PID PPID STATE NAME\n"); 28 | 29 | for (pid = 0; pid < NPROC; ++pid) { 30 | pid_t ppid = uprocs[pid].ppid; 31 | int state = uprocs[pid].state; 32 | 33 | if (state == PROC_UNUSED) 34 | continue; 35 | 36 | /* pid */ 37 | spaces(pid, 5); 38 | printf(1, "%ld ", pid); 39 | 40 | /* ppid */ 41 | spaces(ppid, 5); 42 | printf(1, "%ld ", ppid); 43 | 44 | /* state */ 45 | assert(state < countof(proc_state_names), "state must be valid"); 46 | printf(1, "%s", proc_state_names[state]); 47 | 48 | /* name */ 49 | printf(1, " %s\n", (char *)&uprocs[pid].name); 50 | } 51 | } 52 | 53 | int main(int argc, char *argv[]) 54 | { 55 | ps(); 56 | exit(); 57 | } 58 | -------------------------------------------------------------------------------- /hv6/user/pstree.c: -------------------------------------------------------------------------------- 1 | #include "user.h" 2 | 3 | static void fill(char *indent, size_t from, size_t to, char c) 4 | { 5 | memset(indent + from, c, to - from); 6 | } 7 | 8 | static size_t fill_children(pid_t ppid, pid_t *children) 9 | { 10 | pid_t pid; 11 | size_t i = 0; 12 | 13 | memset(children, 0, sizeof(pid_t) * NPROC); 14 | for (pid = 0; pid < NPROC; ++pid) { 15 | if (pid != ppid && uprocs[pid].ppid == ppid) 16 | children[i++] = pid; 17 | } 18 | return i; 19 | } 20 | 21 | static void pstree(char *indent, pid_t pid) 22 | { 23 | int level = strlen(indent); 24 | pid_t children[NPROC] = {0}; 25 | size_t i, idt, num_children; 26 | 27 | num_children = fill_children(pid, children); 28 | for (i = 0; i < num_children; i++) { 29 | char *name = (char *)&uprocs[children[i]].name; 30 | bool first = (i == 0); 31 | bool last = (i + 1 == num_children); 32 | 33 | if (!first) 34 | printf(1, "\n%s", indent); 35 | 36 | if (!last) 37 | memcpy(indent + strlen(indent), "│", 3); 38 | 39 | if (first && last) 40 | printf(1, "─"); 41 | if (first && !last) 42 | printf(1, "─┬─"); 43 | if (!first && last) 44 | printf(1, "└─"); 45 | if (!first && !last) 46 | printf(1, "├─"); 47 | 48 | idt = !first && last ? 3 : 2; 49 | 50 | printf(1, "%s", name); 51 | 52 | fill(indent, strlen(indent), strlen(indent) + strlen(name) + idt, ' '); 53 | pstree(indent, children[i]); 54 | fill(indent, level, strlen(indent), '\0'); 55 | } 56 | } 57 | 58 | int main(int argc, char *argv[]) 59 | { 60 | /* probably enough */ 61 | char indent[1024] = {0}; 62 | char *name = (char *)&uprocs[1].name; 63 | 64 | printf(1, "%s", name); 65 | memset(indent, ' ', strlen(name) + 1); 66 | pstree(indent, 1); 67 | printf(1, "\n"); 68 | exit(); 69 | } 70 | -------------------------------------------------------------------------------- /hv6/user/readline.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | char *readline(const char *prompt); 4 | void add_history(const char *); 5 | void reset_history(void); 6 | int bind_key(int key, int (*function)(int key, int cur, char **buf)); 7 | -------------------------------------------------------------------------------- /hv6/user/readylist.c: -------------------------------------------------------------------------------- 1 | #include "user.h" 2 | 3 | static int is_ready(pid_t pid) 4 | { 5 | return uprocs[pid].state == PROC_RUNNING || uprocs[pid].state == PROC_RUNNABLE; 6 | } 7 | 8 | static void print(pid_t pid, int color) 9 | { 10 | dprintf(1, "\x1b[38;5;%dm┌────┴─────────────────┐\x1b[0m\n", color); 11 | dprintf(1, "\x1b[38;5;%dm│%5ld %-16s│\x1b[0m\n", color, pid, (char *)uprocs[pid].name); 12 | dprintf(1, "\x1b[38;5;%dm└────┬─────────────────┘\x1b[0m\n", color); 13 | } 14 | 15 | int main(int argc, char *argv[]) 16 | { 17 | static bool ready[NPROC]; 18 | pid_t pid, current = getpid(), next; 19 | size_t count; 20 | 21 | pid = current; 22 | count = 0; 23 | dprintf(1, "\n"); 24 | do { 25 | assert(is_ready(pid), "must be ready"); 26 | next = uprocs[pid].ready.next; 27 | assert(uprocs[next].ready.prev == pid, "must be well-formed"); 28 | print(pid, (pid == current) ? 42 : 255); 29 | ready[pid] = true; 30 | count++; 31 | pid = next; 32 | } while (pid != current); 33 | dprintf(1, "\n"); 34 | dprintf(1, "Found %zu ready processes in readylist\n", count); 35 | 36 | for (pid = 0, count = 0; pid < NPROC; ++pid) { 37 | if (is_ready(pid) && !ready[pid]) 38 | count++; 39 | } 40 | dprintf(1, "Found %zu ready processes not in readylist\n", count); 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /hv6/user/rm.c: -------------------------------------------------------------------------------- 1 | #include "user.h" 2 | 3 | int main(int argc, char *argv[]) 4 | { 5 | int i; 6 | 7 | if (argc < 2){ 8 | printf(2, "Usage: rm files...\n"); 9 | exit(); 10 | } 11 | 12 | for (i = 1; i < argc; i++) { 13 | if (unlink(argv[i]) < 0) { 14 | printf(2, "rm: %s failed to delete\n", argv[i]); 15 | break; 16 | } 17 | } 18 | 19 | exit(); 20 | } 21 | -------------------------------------------------------------------------------- /hv6/user/socket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | struct hostent { 6 | char *h_name; /* official name of host */ 7 | char **h_aliases; /* alias list */ 8 | int h_addrtype; /* host address type */ 9 | int h_length; /* length of address */ 10 | char **h_addr_list; /* list of addresses from name server */ 11 | #define h_addr h_addr_list[0] /* address, for backward compatibility */ 12 | }; 13 | 14 | struct in_addr { 15 | uint32_t s_addr; 16 | }; 17 | 18 | struct sockaddr { 19 | uint8_t sa_len; 20 | uint8_t sa_family; 21 | char sa_data[14]; 22 | }; 23 | 24 | struct sockaddr_in { 25 | uint8_t sin_len; 26 | uint8_t sin_family; 27 | uint16_t sin_port; 28 | struct in_addr sin_addr; 29 | char sin_zero[8]; 30 | }; 31 | 32 | char *inet_ntoa(struct in_addr in); 33 | char *inet_ntoa_r(struct in_addr in, char *buf, socklen_t size); 34 | 35 | struct hostent *gethostbyname(const char *name); 36 | 37 | int socket(int domain, int type, int protocol); 38 | int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen); 39 | int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 40 | int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 41 | int listen(int sockfd, int backlog); 42 | int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 43 | ssize_t send(int sockfd, const void *buf, size_t len, int flags); 44 | ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, 45 | socklen_t addrlen); 46 | ssize_t recv(int sockfd, void *buf, size_t len, int flags); 47 | ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, 48 | socklen_t *addrlen); 49 | 50 | #ifdef htons 51 | #undef htons 52 | #endif 53 | #define htons __builtin_bswap16 54 | 55 | #ifdef ntohs 56 | #undef ntohs 57 | #endif 58 | #define ntohs __builtin_bswap16 59 | 60 | #ifdef htonl 61 | #undef htonl 62 | #endif 63 | #define htonl __builtin_bswap32 64 | 65 | #ifdef ntohl 66 | #undef ntohl 67 | #endif 68 | #define ntohl __builtin_bswap32 69 | 70 | #ifndef INADDR_ANY 71 | #define INADDR_ANY 0 72 | #endif 73 | -------------------------------------------------------------------------------- /hv6/user/timer.c: -------------------------------------------------------------------------------- 1 | #include "ns.h" 2 | 3 | static uint8_t ping_buf[PAGE_SIZE] __aligned(PAGE_SIZE); 4 | static struct fsipc_ping *ping = (void *)ping_buf; 5 | 6 | int main(int argc, char **argv) 7 | { 8 | pid_t pid; 9 | 10 | assert(argc >= 2, "usage: timer pid"); 11 | 12 | pid = atoi(argv[1]); 13 | 14 | while (1) { 15 | sys_send(pid, NSIPC_TIMER, virt_to_pn(ping), 0, -1); 16 | /* TODO: sleep */ 17 | yield(); 18 | } 19 | 20 | exit(); 21 | } 22 | -------------------------------------------------------------------------------- /hv6/user/vmstat.c: -------------------------------------------------------------------------------- 1 | #include "user.h" 2 | 3 | static const char *typenames[] = { 4 | [PAGE_TYPE_FREE] = "FREE ", [PAGE_TYPE_RESERVED] = "RESERVED ", 5 | [PAGE_TYPE_PROC_DATA] = "PROC/DATA", [PAGE_TYPE_FRAME] = "FRAME ", 6 | [PAGE_TYPE_X86_PML4] = "PML4 ", [PAGE_TYPE_X86_PDPT] = "PDPT ", 7 | [PAGE_TYPE_X86_PD] = "PD ", [PAGE_TYPE_X86_PT] = "PT ", 8 | [PAGE_TYPE_IOMMU_PDPT] = "IO/PDPT ", [PAGE_TYPE_IOMMU_PD] = "IO/PD ", 9 | [PAGE_TYPE_IOMMU_PT] = "IO/PT ", [PAGE_TYPE_IOMMU_FRAME] = "IO/FRAME ", 10 | [PAGE_TYPE_IOMMU_PML4] = "IO/PML4 ", 11 | }; 12 | 13 | static void fill(uint64_t x, size_t n, uint8_t c) 14 | { 15 | size_t i; 16 | 17 | if (x == 0) { 18 | i = 1; 19 | } else { 20 | for (i = 0; x; x /= 10) 21 | ++i; 22 | } 23 | 24 | for (; i < n; ++i) 25 | printf(1, "%c", c); 26 | } 27 | 28 | static void vmstat(void) 29 | { 30 | pn_t i, n = NPAGE, start = 0; 31 | pid_t pid; 32 | int type; 33 | 34 | pid = upages[0].pid; 35 | type = upages[0].type; 36 | 37 | for (i = 1; i < n; ++i) { 38 | if (type == upages[i].type && pid == upages[i].pid && i != n - 1) 39 | continue; 40 | if (start == i - 1) { 41 | fill(0, 7, ' '); 42 | } else { 43 | fill(start, 5, '0'); 44 | printf(1, "%lu-", start); 45 | } 46 | fill((i == n - 1) ? i : i - 1, 5, '0'); 47 | printf(1, "%lu ", (i == n - 1) ? i : i - 1); 48 | assert(type <= countof(typenames), "must be valid type"); 49 | printf(1, " %s", typenames[type]); 50 | printf(1, " "); 51 | if (pid) { 52 | fill(pid, 2, '0'); 53 | printf(1, "%ld %.16s", pid, (char *)&uprocs[pid].name); 54 | } 55 | printf(1, "\n"); 56 | pid = upages[i].pid; 57 | type = upages[i].type; 58 | start = i; 59 | } 60 | } 61 | 62 | int main(int argc, char *argv[]) 63 | { 64 | vmstat(); 65 | exit(); 66 | } 67 | -------------------------------------------------------------------------------- /hv6/user/wc.c: -------------------------------------------------------------------------------- 1 | #include "stat.h" 2 | #include "types.h" 3 | #include "user.h" 4 | 5 | char buf[512]; 6 | 7 | void wc(int fd, char *name) 8 | { 9 | int i, n; 10 | int l, w, c, inword; 11 | 12 | l = w = c = 0; 13 | inword = 0; 14 | while ((n = read(fd, buf, sizeof(buf))) > 0) { 15 | for (i = 0; i < n; i++) { 16 | c++; 17 | if (buf[i] == '\n') 18 | l++; 19 | if (strchr(" \r\t\n\v", buf[i])) 20 | inword = 0; 21 | else if (!inword) { 22 | w++; 23 | inword = 1; 24 | } 25 | } 26 | } 27 | if (n < 0) { 28 | printf(1, "wc: read error\n"); 29 | exit(); 30 | } 31 | printf(1, "%d %d %d %s\n", l, w, c, name); 32 | } 33 | 34 | int main(int argc, char *argv[]) 35 | { 36 | int fd, i; 37 | 38 | if (argc <= 1) { 39 | wc(0, ""); 40 | exit(); 41 | } 42 | 43 | for (i = 1; i < argc; i++) { 44 | if ((fd = open(argv[i], 0)) < 0) { 45 | printf(1, "wc: cannot open %s\n", argv[i]); 46 | exit(); 47 | } 48 | wc(fd, argv[i]); 49 | close(fd); 50 | } 51 | exit(); 52 | } 53 | -------------------------------------------------------------------------------- /hv6/user/wttr.c: -------------------------------------------------------------------------------- 1 | #include "user.h" 2 | 3 | int main(int argc, char **argv) 4 | { 5 | execl("httpget", "httpget", "wttr.in/?0", NULL); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /hv6/vm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "types.h" 5 | 6 | extern uint64_t pages[NPAGE][PAGE_SIZE / sizeof(uint64_t)]; 7 | extern struct page_desc page_desc_table[NPAGE]; 8 | 9 | void alloc_page(pid_t pid, enum page_type type, pn_t pn); 10 | void free_page(pn_t pn); 11 | int map_page(pid_t pid, pn_t from_pn, size_t index, pn_t pfn, pte_t perm, 12 | enum page_type from_type); 13 | 14 | int sys_alloc_pdpt(pid_t pid, pn_t from, size_t index, pn_t to, pte_t perm); 15 | int sys_alloc_pd(pid_t pid, pn_t from, size_t index, pn_t to, pte_t perm); 16 | int sys_alloc_pt(pid_t pid, pn_t from, size_t index, pn_t to, pte_t perm); 17 | int sys_alloc_frame(pid_t pid, pn_t from, size_t index, pn_t to, pte_t perm); 18 | int sys_copy_frame(pn_t from, pid_t pid, pn_t to); 19 | int sys_protect_frame(pn_t pt, size_t index, pn_t frame, pte_t perm); 20 | 21 | int sys_free_pdpt(pn_t from, size_t index, pn_t to); 22 | int sys_free_pd(pn_t from, size_t index, pn_t to); 23 | int sys_free_pt(pn_t from, size_t index, pn_t to); 24 | int sys_free_frame(pn_t from, size_t index, pn_t to); 25 | int sys_reclaim_page(pn_t pn); 26 | 27 | int sys_map_page_desc(pid_t pid, pn_t from, size_t index, size_t n, pte_t perm); 28 | int sys_map_pml4(pid_t pid, size_t index, pte_t perm); 29 | int sys_map_proc(pid_t pid, pn_t from, size_t index, size_t n, pte_t perm); 30 | int sys_map_dev(pid_t pid, pn_t from, size_t index, size_t n, pte_t perm); 31 | int sys_map_file(pid_t pid, pn_t from, size_t index, size_t n, pte_t perm); 32 | int sys_map_port(pn_t from, size_t index, size_t n, pte_t perm); 33 | 34 | static inline struct page_desc *get_page_desc(pn_t pn) 35 | { 36 | assert(is_pn_valid(pn), "page number must be valid"); 37 | return &page_desc_table[pn]; 38 | } 39 | 40 | static inline bool is_page_type(pn_t pn, enum page_type type) 41 | { 42 | return is_pn_valid(pn) && get_page_desc(pn)->type == type; 43 | } 44 | 45 | static inline bool is_page_pid(pn_t pn, pid_t pid) 46 | { 47 | return is_pn_valid(pn) && get_page_desc(pn)->pid == pid; 48 | } 49 | 50 | static inline void *get_page(pn_t pn) 51 | { 52 | assert(is_pn_valid(pn), "pn must be valid"); 53 | return pages + pn; 54 | } 55 | 56 | static inline pn_t pn_to_pfn(pn_t pn) 57 | { 58 | pn_t pfn0 = (uintptr_t)pages / PAGE_SIZE; 59 | 60 | assert(is_pn_valid(pn), "pn must be valid"); 61 | return pfn0 + pn; 62 | } 63 | 64 | static inline pn_t pfn_to_pn(pn_t pfn) 65 | { 66 | pn_t pfn0 = (uintptr_t)pages / PAGE_SIZE; 67 | 68 | assert(pfn >= pfn0 && pfn < pfn0 + NPAGE, "pfn must be valid"); 69 | return pfn - pfn0; 70 | } 71 | -------------------------------------------------------------------------------- /include/uapi/assym.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define ASSYM_BIAS 0x10000 /* avoid zero-length arrays */ 4 | #define ASSYM_ABS(value) ((value) < 0 ? -((value) + 1) + 1ULL : (value)) 5 | 6 | #define ASSYM(name, value) \ 7 | char name##sign[((value) < 0 ? 1 : 0) + ASSYM_BIAS]; \ 8 | char name##w0[(ASSYM_ABS(value) & 0xFFFFU) + ASSYM_BIAS]; \ 9 | char name##w1[((ASSYM_ABS(value) & 0xFFFF0000UL) >> 16) + ASSYM_BIAS]; \ 10 | char name##w2[((ASSYM_ABS(value) & 0xFFFF00000000ULL) >> 32) + ASSYM_BIAS]; \ 11 | char name##w3[((ASSYM_ABS(value) & 0xFFFF000000000000ULL) >> 48) + ASSYM_BIAS] 12 | -------------------------------------------------------------------------------- /include/uapi/bitset.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define _BITSET_BITS (sizeof(unsigned long) * 8) 6 | 7 | #define __howmany(x, y) (((x) + ((y) - 1)) / (y)) 8 | 9 | #define __bitset_words(_s) (__howmany(_s, _BITSET_BITS)) 10 | 11 | #define __bitset_mask(n) (1UL << ((n) % _BITSET_BITS)) 12 | 13 | #define __bitset_word(n) ((n) / _BITSET_BITS) 14 | 15 | #define BITSET_DEFINE(t, _s) unsigned long t[__bitset_words(_s)] 16 | 17 | static inline void bit_set(size_t n, unsigned long *bits) 18 | { 19 | bits[__bitset_word(n)] |= __bitset_mask(n); 20 | } 21 | 22 | static inline void bit_clear(size_t n, unsigned long *bits) 23 | { 24 | bits[__bitset_word(n)] &= ~__bitset_mask(n); 25 | } 26 | 27 | static inline int bit_isset(size_t n, unsigned long *bits) 28 | { 29 | return !!(bits[__bitset_word(n)] & __bitset_mask(n)); 30 | } 31 | -------------------------------------------------------------------------------- /include/uapi/console.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | struct console_device { 6 | void *arg; 7 | int (*getc)(void *); 8 | void (*write)(void *, const char *, size_t); 9 | 10 | SLIST_ENTRY(console_device) link; 11 | }; 12 | 13 | int console_getc(void); 14 | void console_write(const char *s, size_t n); 15 | void console_register(struct console_device *dev); 16 | 17 | void uart8250_init(void); 18 | void porte9_init(void); 19 | void kbd_init(void); 20 | void cga_init(void *); 21 | void cga_write(void *arg, const char *s, size_t n); 22 | void membuf_init(void); 23 | int membuf_get(void *); 24 | -------------------------------------------------------------------------------- /include/uapi/container.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef uint32_t cptr_t; 4 | 5 | enum { 6 | NUM_CONTAINER_CAPABILITY_SLOTS = 64, 7 | }; 8 | 9 | enum cap_type { 10 | /* Capability slot is empty and carries no data. */ 11 | CAP_TYPE_EMPTY = 0, 12 | /* Capability to another container */ 13 | CAP_TYPE_CONTAINER, 14 | CAP_TYPE_ENV, 15 | CAP_TYPE_FRAME_1K, 16 | CAP_TYPE_FRAME_4K, 17 | CAP_TYPE_FRAME_1M, 18 | CAP_TYPE_FRAME_2M, 19 | CAP_TYPE_FRAME_4M, 20 | CAP_TYPE_FRAME_1G, 21 | CAP_TYPE_PAGEMAP_L0, /* Page Mapping Level 0 */ 22 | CAP_TYPE_PAGEMAP_L1, /* Page Mapping Level 1 */ 23 | CAP_TYPE_PAGEMAP_L2, /* Page Mapping Level 2 */ 24 | CAP_TYPE_PAGEMAP_L3, /* Page Mapping Level 3 */ 25 | }; 26 | -------------------------------------------------------------------------------- /include/uapi/image.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | /* little endian, "EXOV" */ 6 | #define IMAGE_MAGIC 0x564f5845 7 | #define IMAGE_TEXT_OFFSET_DEFAULT 0x00400000 8 | 9 | #ifndef __ASSEMBLER__ 10 | 11 | /* header for init */ 12 | struct image { 13 | uint64_t code; 14 | uint64_t text_offset; 15 | uint64_t image_size; 16 | uint64_t res[4]; 17 | uint32_t magic; 18 | uint32_t res5; 19 | uint8_t payload[]; 20 | } __packed; 21 | 22 | #endif /* !__ASSEMBLER__ */ 23 | -------------------------------------------------------------------------------- /include/uapi/machine/io.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define IRQ_TIMER 0 6 | #define IRQ_KBD 1 7 | #define IRQ_COM2 3 8 | #define IRQ_COM1 4 9 | #define IRQ_ERROR 19 10 | #define IRQ_SPURIOUS 31 11 | 12 | #define PORT_COM2 0x2f8 13 | #define PORT_COM1 0x3f8 14 | 15 | #define PORT_KBD_DATA 0x60 16 | #define PORT_KBD_STATUS 0x64 17 | 18 | #define PORT_CRT 0x3d4 19 | 20 | #define PORT_PCI_CONF_ADDRESS 0xcf8 21 | #define PORT_PCI_CONF_DATA 0xcfc 22 | 23 | #define CGA_START UINT64_C(0xb8000) 24 | 25 | #define VRAM_START UINT64_C(0xa0000) 26 | #define VRAM_END UINT64_C(0xbffff) 27 | 28 | /* 29 | * 0xc0000000 might be good enough: ECAM often starts at 0xf000xxxx, 30 | * but it's 0xa0000000 on sysv (0xb0000000 on QEMU), therefore the value. 31 | */ 32 | #define PCI_START UINT64_C(0xa0000000) 33 | #define PCI_END UINT64_C(0x100000000) 34 | -------------------------------------------------------------------------------- /include/uapi/machine/trap_genassym.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "trap.h" 3 | 4 | ASSYM(TRAP_REGS_R15, offsetof(struct trap_regs, r15)); 5 | ASSYM(TRAP_REGS_R14, offsetof(struct trap_regs, r14)); 6 | ASSYM(TRAP_REGS_R13, offsetof(struct trap_regs, r13)); 7 | ASSYM(TRAP_REGS_R12, offsetof(struct trap_regs, r12)); 8 | ASSYM(TRAP_REGS_RBP, offsetof(struct trap_regs, rbp)); 9 | ASSYM(TRAP_REGS_RBX, offsetof(struct trap_regs, rbx)); 10 | ASSYM(TRAP_REGS_RAX, offsetof(struct trap_regs, rax)); 11 | ASSYM(TRAP_REGS_R11, offsetof(struct trap_regs, r11)); 12 | ASSYM(TRAP_REGS_R10, offsetof(struct trap_regs, r10)); 13 | ASSYM(TRAP_REGS_R9, offsetof(struct trap_regs, r9)); 14 | ASSYM(TRAP_REGS_R8, offsetof(struct trap_regs, r8)); 15 | ASSYM(TRAP_REGS_RCX, offsetof(struct trap_regs, rcx)); 16 | ASSYM(TRAP_REGS_RDX, offsetof(struct trap_regs, rdx)); 17 | ASSYM(TRAP_REGS_RSI, offsetof(struct trap_regs, rsi)); 18 | ASSYM(TRAP_REGS_RDI, offsetof(struct trap_regs, rdi)); 19 | ASSYM(TRAP_REGS_SIZE, sizeof(struct trap_regs)); 20 | -------------------------------------------------------------------------------- /include/uapi/pci.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define PCI_ANY_ID (~0U) 6 | 7 | #define PCI_DRIVER_ID(vendor, product) \ 8 | { vendor, product, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID } 9 | 10 | #define PCI_DRIVER_CLASS(class, subclass, interface) \ 11 | { PCI_ANY_ID, PCI_ANY_ID, class, subclass, interface } 12 | 13 | struct pci_func { 14 | uint16_t devid; 15 | 16 | uint16_t vendor; 17 | uint16_t product; 18 | 19 | uint8_t class; 20 | uint8_t subclass; 21 | uint8_t interface; 22 | uint8_t revision; 23 | 24 | uint64_t reg_base[6]; 25 | uint64_t reg_size[6]; 26 | }; 27 | 28 | /* PCI driver table */ 29 | struct pci_driver { 30 | uint32_t vendor, product; 31 | uint32_t class, subclass, interface; 32 | 33 | SLIST_ENTRY(pci_driver) link; 34 | }; 35 | 36 | /* must be called before pci_init() */ 37 | void pci_register_driver(struct pci_driver *); 38 | 39 | void pci_init(void); 40 | 41 | uint32_t pci_conf_read(uint16_t devid, uint32_t off); 42 | void pci_conf_write(uint16_t devid, uint32_t off, uint32_t v); 43 | 44 | static inline uint16_t pci_devid(int bus, int dev, int func) 45 | { 46 | return (bus << 8) | (dev << 3) | func; 47 | } 48 | 49 | static inline uint8_t pci_bus_num(uint16_t devid) 50 | { 51 | return devid >> 8; 52 | } 53 | 54 | static inline uint8_t pci_dev_num(uint16_t devid) 55 | { 56 | return (devid >> 3) & 0x1f; 57 | } 58 | 59 | static inline uint8_t pci_func_num(uint16_t devid) 60 | { 61 | return devid & 0x07; 62 | } 63 | 64 | /* PCIe configuration base address */ 65 | extern physaddr_t pci_config_base; 66 | 67 | static inline physaddr_t pci_config_addr(uint16_t devid) 68 | { 69 | return pci_config_base + devid * SZ_4K; 70 | } 71 | 72 | /* OS callback */ 73 | extern void (*pci_register_func)(struct pci_func *); 74 | -------------------------------------------------------------------------------- /include/uapi/pcidb.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define PCI_VENDOR_ATHEROS 0x1969 4 | # define PCI_PRODUCT_ATHEROS_E2500 0xE0B1 5 | 6 | #define PCI_VENDOR_AMD 0x1022 7 | 8 | #define PCI_VENDOR_INTEL 0x8086 9 | # define PCI_PRODUCT_E1000_82540EM 0x100E 10 | # define PCI_PRODUCT_E1000_82574L 0x10D3 11 | # define PCI_PRODUCT_E1000_PCH_LPT_I217_LM 0x153A 12 | -------------------------------------------------------------------------------- /include/uapi/psf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define PSF2_MAGIC0 0x72 6 | #define PSF2_MAGIC1 0xb5 7 | #define PSF2_MAGIC2 0x4a 8 | #define PSF2_MAGIC3 0x86 9 | 10 | /* bits used in flags */ 11 | #define PSF2_HAS_UNICODE_TABLE 0x01 12 | 13 | /* max version recognized so far */ 14 | #define PSF2_MAXVERSION 0 15 | 16 | /* UTF8 separators */ 17 | #define PSF2_SEPARATOR 0xFF 18 | #define PSF2_STARTSEQ 0xFE 19 | 20 | struct psf2_header { 21 | unsigned char magic[4]; 22 | unsigned int version; 23 | unsigned int headersize; /* offset of bitmaps in file */ 24 | unsigned int flags; 25 | unsigned int length; /* number of glyphs */ 26 | unsigned int charsize; /* number of bytes for each character */ 27 | unsigned int height, width; /* max dimensions of glyphs */ 28 | /* charsize = height * ((width + 7) / 8) */ 29 | } __packed; 30 | -------------------------------------------------------------------------------- /include/uapi/syscall.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define NR_syscalls 128 4 | -------------------------------------------------------------------------------- /include/uapi/sysctl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum { 4 | SYSCTL_ECAM_ADDRESS = 1, 5 | SYSCTL_IOMMU_VENDOR, 6 | SYSCTL_TSC_KHZ, 7 | }; 8 | -------------------------------------------------------------------------------- /irpy/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | irpy 3 | *.pyc 4 | .idea/ 5 | cmake-build-debug/ 6 | CMakeFiles/ 7 | CMakeCache.txt 8 | cmake_install.cmake 9 | Makefile 10 | o.test 11 | -------------------------------------------------------------------------------- /irpy/compiler/Emitter.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "Emitter.hh" 18 | 19 | #include 20 | 21 | namespace irpy { 22 | 23 | void Emitter::line(const std::string &ref) const 24 | { 25 | for (auto i = 0; i < indent_level_; ++i) 26 | stream_ << " "; 27 | stream_ << ref << std::endl; 28 | } 29 | 30 | void Emitter::line(void) const 31 | { 32 | stream_ << std::endl; 33 | } 34 | 35 | } // namespace irpy 36 | -------------------------------------------------------------------------------- /irpy/compiler/Emitter.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | namespace irpy { 22 | 23 | class Emitter 24 | { 25 | protected: 26 | std::ostream &stream_; 27 | 28 | int indent_level_; 29 | 30 | public: 31 | Emitter(std::ostream &stream) : stream_(stream), indent_level_(0) 32 | { 33 | } 34 | Emitter(const Emitter &) = delete; 35 | Emitter &operator=(const Emitter &) = delete; 36 | 37 | void line(const std::string &) const; 38 | void line(void) const; 39 | }; 40 | 41 | } // namespace irpy 42 | -------------------------------------------------------------------------------- /irpy/compiler/PyEmitter.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "PyEmitter.hh" 18 | 19 | #include 20 | 21 | namespace irpy { 22 | 23 | void PyEmitter::genBlock(const std::string &blk, const std::function &body) 24 | { 25 | this->line(blk + ":"); 26 | ++indent_level_; 27 | body(); 28 | --indent_level_; 29 | } 30 | 31 | void PyEmitter::genDef(const std::string &name, const std::vector &args, 32 | const std::function &func) 33 | { 34 | std::ostringstream def; 35 | def << "def " << name << "("; 36 | for (auto &a : args) 37 | def << a << ","; 38 | def << ")"; 39 | this->genBlock(def.str(), func); 40 | this->line(); 41 | } 42 | 43 | void PyEmitter::emitWarning(const std::string &filename) const 44 | { 45 | this->line("#"); 46 | this->line("# WARNING: This file has been automatically generated from " + filename); 47 | this->line("#"); 48 | this->line(); 49 | } 50 | 51 | void PyEmitter::genException(const std::string &message) const 52 | { 53 | this->line("raise Exception('" + message + ")"); 54 | this->line(); 55 | } 56 | 57 | } // namespace irpy 58 | -------------------------------------------------------------------------------- /irpy/compiler/PyEmitter.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "Emitter.hh" 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | namespace irpy { 29 | 30 | class PyEmitter : public Emitter 31 | { 32 | 33 | public: 34 | PyEmitter(std::ostream &stream) : Emitter(stream) 35 | { 36 | } 37 | 38 | void genBlock(const std::string &blk, const std::function &body); 39 | 40 | void genDef(const std::string &name, const std::vector &args, 41 | const std::function &func); 42 | 43 | void genException(const std::string &message) const; 44 | 45 | void emitWarning(const std::string &filename) const; 46 | 47 | }; 48 | 49 | } // namespace irpy 50 | -------------------------------------------------------------------------------- /irpy/compiler/PyLLVMEmitter.hh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "PyEmitter.hh" 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | 37 | namespace irpy { 38 | 39 | class PyLLVMEmitter : public PyEmitter 40 | { 41 | public: 42 | PyLLVMEmitter(std::ostream &stream, llvm::Module *module) 43 | : PyEmitter(stream), 44 | module_(module) 45 | { 46 | } 47 | 48 | void emitModule(void); 49 | void emitMetadata(void); 50 | void emitBasicBlock(llvm::BasicBlock &bb); 51 | void emitStructType(const llvm::StructType &type); 52 | void emitFunction(llvm::Function &func); 53 | void emitGlobalVariable(const llvm::GlobalVariable &type); 54 | 55 | private: 56 | 57 | llvm::Module *module_; 58 | }; 59 | 60 | } // namespace irpy 61 | -------------------------------------------------------------------------------- /irpy/compiler/irpy.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include "PyLLVMEmitter.hh" 17 | #include 18 | 19 | #if defined(PROFILER) 20 | #include 21 | #endif 22 | 23 | inline static constexpr double cycles_to_ms(std::clock_t t) { 24 | return t / static_cast(CLOCKS_PER_SEC / 1000.0); 25 | } 26 | 27 | int main(int argc, char **argv) 28 | { 29 | 30 | llvm::LLVMContext ctx; 31 | llvm::SMDiagnostic err; 32 | const std::string filename = (argc < 2) ? "-" : std::string{argv[1]}; 33 | 34 | std::clock_t start = std::clock(); 35 | 36 | auto module = llvm::parseIRFile(filename, err, ctx); 37 | if (!module) { 38 | err.print("irpy", llvm::errs()); 39 | return 3; 40 | } 41 | 42 | std::clock_t parsedone = std::clock(); 43 | std::cerr << "Parsing took " << cycles_to_ms(parsedone - start) << " ms." << std::endl; 44 | 45 | irpy::PyLLVMEmitter emitter{std::cout, module.get()}; 46 | 47 | #if defined(PROFILER) 48 | ProfilerStart("irpy.prof"); 49 | #endif 50 | 51 | emitter.emitWarning(filename); 52 | emitter.emitModule(); 53 | 54 | #if defined(PROFILER) 55 | ProfilerStop(); 56 | #endif 57 | 58 | std::clock_t emitdone = std::clock(); 59 | std::cerr << "Emitting took " << cycles_to_ms(emitdone - parsedone) << " ms." << std::endl; 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /irpy/libirpy/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Hyperkernel Authors 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | from ctx import newctx, initctx 18 | 19 | __all__ = ['newctx', 'initctx'] 20 | -------------------------------------------------------------------------------- /irpy/libirpy/ex.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Hyperkernel Authors 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | class UnreachableException(Exception): 18 | pass 19 | -------------------------------------------------------------------------------- /irpy/libirpy/server.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Hyperkernel Authors 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | import sys 18 | import util 19 | import z3 20 | 21 | from solver_utils import write_cmd, read_cmd 22 | 23 | 24 | class Server(object): 25 | def __init__(self): 26 | self._s = z3.Solver() 27 | 28 | def _write(self, command): 29 | return write_cmd(sys.stdout, command) 30 | 31 | def _read(self): 32 | return read_cmd(sys.stdin) 33 | 34 | def run(self): 35 | while True: 36 | self.handle_cmd() 37 | 38 | def handle_cmd(self): 39 | cmd = self._read() 40 | if not cmd: 41 | sys.exit(0) 42 | try: 43 | res = {'return': getattr(self, cmd['name'])(*cmd['args'], **cmd['kwargs'])} 44 | except Exception, e: 45 | res = {'exc': repr(e)} 46 | self._write(res) 47 | 48 | def add(self, term): 49 | self._s.add(z3.parse_smt2_string(term)) 50 | 51 | def set(self, **kwargs): 52 | self._s.set(**{str(k): v for k, v in kwargs.items()}) 53 | 54 | def check(self): 55 | return str(self._s.check()) 56 | 57 | def push(self): 58 | return str(self._s.push()) 59 | 60 | def pop(self): 61 | return str(self._s.pop()) 62 | 63 | def model(self): 64 | return str(self._s.model()) 65 | 66 | def model_evaluate(self, term): 67 | model = self._s.model() 68 | 69 | for t in model.decls(): 70 | if str(t) == term: 71 | term = t() 72 | break 73 | return str(self._s.model().evaluate(term)) 74 | 75 | 76 | if __name__ == '__main__': 77 | Server().run() 78 | -------------------------------------------------------------------------------- /irpy/libirpy/solver_utils.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Hyperkernel Authors 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | import math 18 | import json 19 | 20 | LEN_LEN = 8 21 | 22 | 23 | def write_cmd(stream, command): 24 | payload = json.dumps(command) 25 | assert math.log( 26 | len(payload), 10) < LEN_LEN, "payload length = {} too large".format(len(payload)) 27 | payload = str(len(payload)).rjust(LEN_LEN, '0') + payload 28 | stream.write(payload) 29 | stream.flush() 30 | 31 | 32 | def read(stream, count): 33 | v = stream.read(count) 34 | return v 35 | 36 | 37 | def read_cmd(stream): 38 | cmdlen = read(stream, LEN_LEN) 39 | if not cmdlen: 40 | return None 41 | data = read(stream, int(cmdlen)) 42 | try: 43 | return json.loads(data) 44 | except Exception, e: 45 | print "Found exception", e, data 46 | raise e 47 | -------------------------------------------------------------------------------- /irpy/libirpy/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uw-unsat/hyperkernel/50d6bada5de63c56376bdc4dba6159788847cc95/irpy/libirpy/tests/__init__.py -------------------------------------------------------------------------------- /irpy/libirpy/tests/test_types.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Hyperkernel Authors 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | import unittest 18 | 19 | import itypes as it 20 | 21 | 22 | class TestReference(unittest.TestCase): 23 | def test_type_parsing(self): 24 | ctx = {} 25 | ctx['types'] = {} 26 | 27 | it.declare_struct_type(ctx, 'struct.trap_regs', 'i64', 'i64', 'i64', 'i64', 'i64', 28 | 'i64', 'i64', 'i64', 'i64', 'i64', 'i64', 'i64', 'i64', 'i64', 'i64', '[8 x i8]',) 29 | it.declare_struct_type(ctx, 'struct.proc', 'i32', 'i64', 'i64', 30 | '[16 x i64]', 'i64', '%struct.trap_regs = type { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, [8 x i8] }', 'i64', '[8 x i8]',) 31 | 32 | self.assertEquals(it.parse_type(ctx, 'i64***'), 33 | it.PointerType(it.PointerType(it.PointerType(it.IntType(64))))) 34 | it.parse_type(ctx, 'i64***') 35 | it.parse_type(ctx, '[0 x i8]') 36 | it.parse_type(ctx, '[0 x i8]*') 37 | it.parse_type(ctx, '[3 x [4 x i32]]') 38 | it.parse_type(ctx, '[3 x [4 x i32]]') 39 | it.parse_type(ctx, '[3 x [4 x i32]]') 40 | it.parse_type(ctx, '%mytype = type { %struct.trap_regs*, i32 }') 41 | -------------------------------------------------------------------------------- /irpy/test/add.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | uint32_t test(uint32_t x, uint32_t y) 22 | { 23 | return x + y; 24 | } 25 | 26 | int main(int argc, char **argv) 27 | { 28 | uint32_t res = test(atoi(argv[1]), atoi(argv[2])); 29 | printf("%u\n", res); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /irpy/test/add_overflow.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | /* Beware signed overflow :) */ 22 | int test(int x, int y) 23 | { 24 | return x + y; 25 | } 26 | 27 | int main(int argc, char **argv) 28 | { 29 | int res = test(atoi(argv[1]), atoi(argv[2])); 30 | printf("%u\n", res); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /irpy/test/add_overflow_check.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | int __attribute__((noinline)) add(int x, int y) { return x + y; } 22 | 23 | /* Beware signed overflow :) */ 24 | int test(int x, int y) 25 | { 26 | if (x < -5000 || x > 5000 || y < -5000 || y > 5000) 27 | return 0; 28 | else 29 | return add(x, y); 30 | } 31 | 32 | int main(int argc, char **argv) 33 | { 34 | int res = test(atoi(argv[1]), atoi(argv[2])); 35 | printf("%u\n", res); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /irpy/test/alloca.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | void foo(uint32_t *x, uint32_t y) 22 | { 23 | *x += y; 24 | } 25 | 26 | uint32_t test(uint32_t x) 27 | { 28 | uint32_t y = 0; 29 | foo(&y, x); 30 | if (y > x) { 31 | y++; 32 | } else { 33 | y--; 34 | } 35 | return y; 36 | } 37 | 38 | int main(int argc, char **argv) 39 | { 40 | uint32_t res = test(atoi(argv[1])); 41 | printf("%u\n", res); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /irpy/test/alloca_alias.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | void foo(uint32_t *x, uint32_t *y, uint32_t z) 22 | { 23 | if (z > 1 << 31) { 24 | *x += 1; 25 | } else { 26 | *y += 1; 27 | } 28 | } 29 | 30 | uint32_t test(uint32_t x) 31 | { 32 | uint32_t y = 0; 33 | foo(&y, &y, x); 34 | return y; 35 | } 36 | 37 | int main(int argc, char **argv) 38 | { 39 | uint32_t res = test(atoi(argv[1])); 40 | printf("%u\n", res); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /irpy/test/array_arith.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | uint32_t arr[] = {1, 2, 3, 4}; 22 | 23 | uint32_t test(uint32_t x) 24 | { 25 | uint32_t idx = x % 4; 26 | uint32_t *bla = (uint32_t *)&arr; 27 | return *(bla + idx); 28 | } 29 | 30 | int main(int argc, char **argv) 31 | { 32 | uint32_t res = test(atoi(argv[1])); 33 | printf("%u\n", res); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /irpy/test/array_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | uint32_t arr[4]; 22 | 23 | uint32_t test(uint32_t x) 24 | { 25 | 26 | uint32_t idx = x % 4; 27 | 28 | arr[idx] = 9; 29 | arr[(idx + 1) % 4] = arr[idx]; 30 | return arr[(idx + 1) % 4]; 31 | } 32 | 33 | int main(int argc, char **argv) 34 | { 35 | uint32_t res = test(atoi(argv[1])); 36 | printf("%u\n", res); 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /irpy/test/array_test2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | uint32_t global[10]; 22 | 23 | void global_init() 24 | { 25 | for (int i = 0; i < 10; ++i) { 26 | global[i] = i; 27 | } 28 | } 29 | 30 | uint32_t test(uint32_t x) 31 | { 32 | global_init(); 33 | return global[x % 10]; 34 | } 35 | 36 | int main(int argc, char **argv) 37 | { 38 | uint32_t res = test(atoi(argv[1])); 39 | printf("%u\n", res); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /irpy/test/big_shift.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | int test(int x, int y) 22 | { 23 | return x << y; 24 | } 25 | 26 | int main(int argc, char **argv) 27 | { 28 | int res = test(atoi(argv[1]), atoi(argv[2])); 29 | printf("%u\n", res); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /irpy/test/bool_zext.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | uint32_t test(uint32_t x, uint32_t y) 22 | { 23 | uint32_t z = (x > y); 24 | if (x > 1 << 31) { 25 | return (z + 1) * y; 26 | } 27 | return z; 28 | } 29 | 30 | int main(int argc, char **argv) 31 | { 32 | uint32_t res = test(atoi(argv[1]), atoi(argv[2])); 33 | printf("%u\n", res); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /irpy/test/call_return.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | uint64_t fib(uint64_t a, uint64_t b, uint64_t steps) 22 | { 23 | uint64_t tmp; 24 | while (steps) { 25 | tmp = a; 26 | a = b; 27 | b = a + tmp; 28 | steps--; 29 | } 30 | return b; 31 | } 32 | 33 | uint64_t test(uint64_t a, uint64_t b) 34 | { 35 | return fib(a, b, 10); 36 | } 37 | 38 | int main(int argc, char **argv) 39 | { 40 | uint64_t res = test(strtoull(argv[1], NULL, 10), strtoull(argv[2], NULL, 10)); 41 | printf("%zu\n", res); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /irpy/test/cond.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | uint32_t test(uint32_t x, uint32_t y) 22 | { 23 | if (y > 10) { 24 | x++; 25 | } else { 26 | x--; 27 | } 28 | return x; 29 | } 30 | 31 | int main(int argc, char **argv) 32 | { 33 | uint32_t res = test(atoi(argv[1]), atoi(argv[2])); 34 | printf("%u\n", res); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /irpy/test/cond2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | void inc(uint32_t *x) 22 | { 23 | *x += 1; 24 | } 25 | 26 | uint32_t test(uint32_t x, uint32_t y) 27 | { 28 | if (y > 1 << 31) { 29 | inc(&x); 30 | x++; 31 | } else { 32 | for (int i = 0; i < 5; ++i) { 33 | inc(&x); 34 | } 35 | inc(&y); 36 | x--; 37 | } 38 | x = x + 1; 39 | inc(&x); 40 | return x - y; 41 | } 42 | 43 | int main(int argc, char **argv) 44 | { 45 | uint32_t res = test(atoi(argv[1]), atoi(argv[2])); 46 | printf("%u\n", res); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /irpy/test/cond_global.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | uint32_t global = 0; 22 | 23 | void test2(uint32_t x, uint32_t y) 24 | { 25 | if (y > (1 << 31)) 26 | global = x; 27 | else 28 | global = y; 29 | } 30 | 31 | uint32_t test(uint32_t x, uint32_t y) 32 | { 33 | test2(x, y); 34 | return global; 35 | } 36 | 37 | int main(int argc, char **argv) 38 | { 39 | uint32_t res = test(atoi(argv[1]), atoi(argv[2])); 40 | printf("%u\n", res); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /irpy/test/loop2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | int test(uint64_t x, uint64_t y) 22 | { 23 | for (int i = 0; i < 5; i++) { 24 | y *= x; 25 | if (y > 1337) 26 | break; 27 | } 28 | return y; 29 | } 30 | 31 | int main(int argc, char **argv) 32 | { 33 | int res = test(strtoull(argv[1], NULL, 10), strtoull(argv[2], NULL, 10)); 34 | printf("%u\n", res); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /irpy/test/loop3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | int test(uint64_t y) 22 | { 23 | for (int i = 0; i < 10; i++) { 24 | if (i % 2) { 25 | y = y * 2 + 1; 26 | } else { 27 | y = y - 12; 28 | } 29 | } 30 | return y; 31 | } 32 | 33 | int main(int argc, char **argv) 34 | { 35 | int res = test(strtoull(argv[1], NULL, 10)); 36 | printf("%u\n", res); 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /irpy/test/loop4.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | int test(uint64_t i) 22 | { 23 | uint64_t y = 0; 24 | if (i < 10) { 25 | for (; i < 11; i++) { 26 | if (i % 2) { 27 | y = y * 2 + 1; 28 | } else { 29 | y = y - 12; 30 | } 31 | } 32 | } 33 | return y; 34 | } 35 | 36 | int main(int argc, char **argv) 37 | { 38 | int res = test(strtoull(argv[1], NULL, 10)); 39 | printf("%u\n", res); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /irpy/test/lsh.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | uint32_t test(uint32_t x, uint32_t y) 22 | { 23 | if (y < 32) 24 | return x << y; 25 | return 0; 26 | } 27 | 28 | int main(int argc, char **argv) 29 | { 30 | uint32_t res = test(atoi(argv[1]), atoi(argv[2])); 31 | printf("%u\n", res); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /irpy/test/mul_overflow.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | /* Beware signed overflow :) */ 22 | int test(int x, int y) 23 | { 24 | return x * y; 25 | } 26 | 27 | int main(int argc, char **argv) 28 | { 29 | int res = test(atoi(argv[1]), atoi(argv[2])); 30 | printf("%u\n", res); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /irpy/test/path.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | int test(uint64_t x, uint64_t y) 22 | { 23 | uint64_t z = 123; 24 | if (y < 10 && x < y) { 25 | for (; x < y; x++) { 26 | z += x * y + z; 27 | } 28 | } 29 | 30 | return z; 31 | } 32 | 33 | int main(int argc, char **argv) 34 | { 35 | int res = test(strtoull(argv[1], NULL, 10), strtoull(argv[2], NULL, 10)); 36 | printf("%u\n", res); 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /irpy/test/poison_cond.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | uint32_t test(uint32_t x, uint32_t y) 22 | { 23 | if (y << x) 24 | return x * y; 25 | else 26 | return x + 1; 27 | } 28 | 29 | int main(int argc, char **argv) 30 | { 31 | uint32_t res = test(atoi(argv[1]), atoi(argv[2])); 32 | printf("%u\n", res); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /irpy/test/ptrptr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | void bla(uint32_t x, uint32_t **a, uint32_t *b, uint32_t *c) 22 | { 23 | if (x > 1 << 31) 24 | *a = b; 25 | else 26 | *a = c; 27 | } 28 | 29 | uint32_t test(uint32_t x, uint32_t y, uint32_t z) 30 | { 31 | uint32_t *a = NULL; 32 | uint32_t *b = &y; 33 | uint32_t *c = &z; 34 | bla(x, &a, b, c); 35 | return *a; 36 | } 37 | 38 | int main(int argc, char **argv) 39 | { 40 | uint32_t res = test(atoi(argv[1]), atoi(argv[2]), atoi(argv[3])); 41 | printf("%u\n", res); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /irpy/test/rsh.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | uint32_t test(uint32_t x, uint32_t y) 22 | { 23 | if (y < 32) 24 | return x >> y; 25 | return 0; 26 | } 27 | 28 | int main(int argc, char **argv) 29 | { 30 | uint32_t res = test(atoi(argv[1]), atoi(argv[2])); 31 | printf("%u\n", res); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /irpy/test/sdiv.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | int32_t test(int32_t x, int32_t y) 22 | { 23 | if (y != 0) 24 | return x / y; 25 | return 0; 26 | } 27 | 28 | int main(int argc, char **argv) 29 | { 30 | uint32_t res = test(atoi(argv[1]), atoi(argv[2])); 31 | printf("%u\n", res); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /irpy/test/sext.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | int64_t test(int8_t y) 22 | { 23 | return y; 24 | } 25 | 26 | int main(int argc, char **argv) 27 | { 28 | int64_t res = test(strtoull(argv[1], NULL, 10)); 29 | printf("%zu\n", res); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /irpy/test/srem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | int32_t test(int32_t x, int32_t y) 22 | { 23 | if (y != 0) 24 | return x % y; 25 | return 0; 26 | } 27 | 28 | int main(int argc, char **argv) 29 | { 30 | uint32_t res = test(atoi(argv[1]), atoi(argv[2])); 31 | printf("%u\n", res); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /irpy/test/struct_.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | struct vec3 { 22 | uint64_t x; 23 | uint64_t y; 24 | uint64_t z; 25 | }; 26 | 27 | struct vec3 p = {0}; 28 | 29 | uint64_t test(uint64_t x) 30 | { 31 | 32 | p.x = x; 33 | p.y = p.x + p.x; 34 | p.z = p.y - x; 35 | return p.z; 36 | } 37 | 38 | int main(int argc, char **argv) 39 | { 40 | uint64_t res = test(strtoull(argv[1], NULL, 10)); 41 | printf("%zu\n", res); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /irpy/test/struct_cond.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | struct point { 22 | uint64_t x; 23 | uint64_t y; 24 | }; 25 | 26 | struct point arr[5]; 27 | 28 | _Bool is_valid(uint64_t x) 29 | { 30 | return (x < 5); 31 | } 32 | 33 | uint8_t test(uint64_t x, uint64_t y) 34 | { 35 | if (!is_valid(x)) 36 | return -1; 37 | struct point *p = &arr[x]; 38 | if (p->x < 1 << 31) 39 | return p->y; 40 | p->y = 54; 41 | return p->y; 42 | } 43 | 44 | int main(int argc, char **argv) 45 | { 46 | uint64_t res = test(strtoull(argv[1], NULL, 10), strtoull(argv[2], NULL, 10)); 47 | printf("%zu\n", res); 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /irpy/test/struct_t.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | struct point { 22 | uint64_t x; 23 | uint64_t y; 24 | }; 25 | 26 | uint64_t sqrtlen(struct point *pt) 27 | { 28 | return pt->x * pt->x + pt->y * pt->y; 29 | } 30 | 31 | uint8_t test(uint64_t x, uint64_t y) 32 | { 33 | struct point pt; 34 | pt.x = x; 35 | pt.y = y; 36 | return sqrtlen(&pt); 37 | } 38 | 39 | int main(int argc, char **argv) 40 | { 41 | uint64_t res = test(strtoull(argv[1], NULL, 10), strtoull(argv[2], NULL, 10)); 42 | printf("%zu\n", res); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /irpy/test/switch.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | int test(uint32_t x) 22 | { 23 | int32_t y; 24 | 25 | switch (x) { 26 | case 1: 27 | case 2: 28 | y = 10; 29 | break; 30 | case 10: 31 | y = 703; 32 | break; 33 | default: 34 | y = -1; 35 | break; 36 | } 37 | 38 | if (y > 5) 39 | return y + x; 40 | return y - x; 41 | } 42 | 43 | int main(int argc, char **argv) 44 | { 45 | int res = test(strtoull(argv[1], NULL, 10)); 46 | printf("%u\n", res); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /irpy/test/switch_table.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | int test(uint32_t x) 22 | { 23 | int32_t y; 24 | 25 | switch (x) { 26 | case 1: 27 | case 2: 28 | y = 10; 29 | break; 30 | case 3: 31 | y = 11; 32 | break; 33 | case 4: 34 | y = 12; 35 | break; 36 | case 5: 37 | y = 13; 38 | break; 39 | case 6: 40 | y = 14; 41 | break; 42 | case 7: 43 | y = 15; 44 | break; 45 | case 10: 46 | y = 703; 47 | break; 48 | default: 49 | y = -1; 50 | break; 51 | } 52 | 53 | if (y > 5) 54 | return y + x; 55 | return y - x; 56 | } 57 | 58 | int main(int argc, char **argv) 59 | { 60 | int res = test(strtoull(argv[1], NULL, 10)); 61 | printf("%u\n", res); 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /irpy/test/trunc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | uint8_t test(uint64_t y) 22 | { 23 | return y; 24 | } 25 | 26 | int main(int argc, char **argv) 27 | { 28 | int res = test(strtoull(argv[1], NULL, 10)); 29 | printf("%u\n", res); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /irpy/test/udiv.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | uint32_t test(uint32_t x, uint32_t y) 22 | { 23 | if (y != 0) 24 | return x / y; 25 | return 0; 26 | } 27 | 28 | int main(int argc, char **argv) 29 | { 30 | uint32_t res = test(atoi(argv[1]), atoi(argv[2])); 31 | printf("%u\n", res); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /irpy/test/urem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | uint32_t test(uint32_t x, uint32_t y) 22 | { 23 | if (y != 0) 24 | return x % y; 25 | return 0; 26 | } 27 | 28 | int main(int argc, char **argv) 29 | { 30 | uint32_t res = test(atoi(argv[1]), atoi(argv[2])); 31 | printf("%u\n", res); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /irpy/test/zero_div.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | uint32_t test(uint32_t x, uint32_t y) 22 | { 23 | return x / y; 24 | } 25 | 26 | int main(int argc, char **argv) 27 | { 28 | uint32_t res = test(atoi(argv[1]), atoi(argv[2])); 29 | printf("%u\n", res); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /irpy/test/zext.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Hyperkernel Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | uint64_t test(uint8_t y) 22 | { 23 | return y; 24 | } 25 | 26 | int main(int argc, char **argv) 27 | { 28 | uint64_t res = test(strtoull(argv[1], NULL, 10)); 29 | printf("%zu\n", res); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /kernel/Makefrag: -------------------------------------------------------------------------------- 1 | $(O)/kernel/initbin.o: $(O)/user/init.bin 2 | 3 | $(O)/kernel/initbin.o: CFLAGS += -I $(O)/user 4 | 5 | $(O)/kernel/svm_entry.o: $(O)/kernel/svm_assym.h 6 | 7 | $(O)/kernel/locore.o \ 8 | $(O)/kernel/svm_entry.o \ 9 | $(O)/kernel/vmx_entry.o \ 10 | $(O)/user/entry.o \ 11 | $(O)/user/trap_entry.o: $(O)/include/uapi/machine/trap_assym.h 12 | 13 | .SECONDARY: $(O)/kernel/svm_genassym.o $(O)/include/uapi/machine/trap_genassym.o 14 | 15 | # workaround for gdb's "reply too long" 16 | gdb: 17 | $(GDB) \ 18 | -ex "set arch i386:x86-64:intel" \ 19 | -ex "target remote :1234" \ 20 | -ex "symbol $(KERNEL_ELF)" \ 21 | -ex "b main" \ 22 | -ex "c" \ 23 | -ex "disconnect" \ 24 | -ex "set arch i386:x86-64" \ 25 | -ex "target remote :1234" 26 | -------------------------------------------------------------------------------- /kernel/amd_iommu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define IVRS_DEV_TABLE_BASE_OFFSET 0x00 6 | #define IVRS_CMD_BUF_OFFSET 0x08 7 | #define IVRS_CONTROL_OFFSET 0x18 8 | 9 | /* IOMMU Control Register */ 10 | #define IVRS_CONTROL_IOMMU_EN BIT64(0) /* IOMMU enable */ 11 | #define IVRS_CONTROL_DEV_TBL_SEG_EN BITMASK64(36, 34) /* Device Table Segmentation enable */ 12 | 13 | struct dev_table_entry { 14 | uint64_t dev0; 15 | uint64_t dev1; 16 | uint64_t dev2; 17 | uint64_t dev3; 18 | } __packed; 19 | 20 | /* [63:0] */ 21 | #define IVRS_DEV0_V BIT64(0) 22 | #define IVRS_DEV0_TV BIT64(1) 23 | 24 | /* [191:128] */ 25 | #define IVRS_DEV2_IV BIT64(0) 26 | #define IVRS_DEV2_INTCTL_SHIFT (188 - 128) 27 | #define IVRS_DEV2_INTCTL_ABORT UINT64_C(0) 28 | #define IVRS_DEV2_INTCTL_FORWARD (UINT64_C(1) << IVRS_DEV2_INTCTL_SHIFT) 29 | #define IVRS_DEV2_INTCTL_REMAP (UINT64_C(2) << IVRS_DEV2_INTCTL_SHIFT) 30 | #define IVRS_DEV2_INTTABLEN_SHIFT 1 31 | 32 | typedef uint64_t ivrs_pte_t; 33 | 34 | #define IVRS_PTE_IW BIT64(62) /* Write permission */ 35 | #define IVRS_PTE_IR BIT64(61) /* Read permission */ 36 | #define IVRS_PTE_PERM_SHIFT 61 37 | #define IVRS_PTE_ADDR_MASK BITS64(51, 12) /* Address mask */ 38 | #define IVRS_PTE_ADDR_SHIFT 12 39 | #define IVRS_PTE_MODE_MASK BITS64(11, 9) 40 | #define IVRS_PTE_MODE_SHIFT 9 41 | #define IVRS_PTE_P BIT64(0) /* Present */ 42 | 43 | struct cmd_entry { 44 | uint64_t op1 : 60; 45 | uint64_t opcode : 3; 46 | uint64_t op2; 47 | } __packed; 48 | 49 | static_assert(sizeof(struct cmd_entry) == 16, "sizeof cmd_entry"); 50 | -------------------------------------------------------------------------------- /kernel/config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define ENABLED(feature) (feature != 0) 4 | #define DISABLED(feature) (feature == 0) 5 | 6 | #define CONFIG_X86_64 1 7 | #define CONFIG_X86 1 8 | #define CONFIG_FPU 1 9 | 10 | #define CONFIG_PREEMPT_TIMER 100 /* milliseconds */ 11 | 12 | #define CONFIG_PREEMPT 0 13 | 14 | #define CONFIG_VPID 0 15 | 16 | /* Enable one of the following */ 17 | #define CONFIG_MEMFS 1 18 | #define CONFIG_NVME 0 19 | 20 | #if (CONFIG_MEMFS == CONFIG_NVME) 21 | #error "Enable exactly one of MEMFS and NVME" 22 | #endif 23 | 24 | #define CONFIG_CGA 1 25 | -------------------------------------------------------------------------------- /kernel/cpuid.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "cpuid.h" 3 | 4 | static uint32_t features[CPUID_LEAF_MAX]; 5 | 6 | void cpuid_init(void) 7 | { 8 | uint32_t regs[4], highest; 9 | 10 | cpuid(0, regs); 11 | highest = regs[0]; 12 | 13 | if (highest >= 1) { 14 | cpuid(1, regs); 15 | features[CPUID_1_EDX] = regs[3]; 16 | features[CPUID_1_ECX] = regs[2]; 17 | } 18 | 19 | if (highest >= 7) { 20 | cpuid2(7, 0, regs); 21 | features[CPUID_7_0_EBX] = regs[1]; 22 | features[CPUID_7_0_ECX] = regs[2]; 23 | features[CPUID_7_0_EDX] = regs[3]; 24 | } 25 | 26 | cpuid(0x80000000, regs); 27 | highest = regs[0]; 28 | 29 | if (highest >= 0x80000001) { 30 | cpuid(0x80000001, regs); 31 | features[CPUID_80000001_EDX] = regs[3]; 32 | features[CPUID_80000001_ECX] = regs[2]; 33 | } 34 | 35 | if (highest >= 0x8000000a) { 36 | cpuid(0x8000000a, regs); 37 | features[CPUID_8000000A_EDX] = regs[3]; 38 | } 39 | } 40 | 41 | bool cpuid_has(int bit) 42 | { 43 | return !!(features[bit / 32U] & (1U << (bit % 32U))); 44 | } 45 | -------------------------------------------------------------------------------- /kernel/fpu.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void fpu_init(void) 7 | { 8 | #if ENABLED(CONFIG_FPU) 9 | register_t cr0, cr4; 10 | 11 | /* check xsave */ 12 | if (!cpuid_has(CPUID_FEATURE_XSAVE)) 13 | panic("no xsave support"); 14 | 15 | cr0 = rcr0(); 16 | cr0 &= ~CR0_EM; 17 | cr0 |= CR0_MP; 18 | 19 | cr4 = rcr4(); 20 | cr4 |= CR4_OSFXSR | CR4_OSXMMEXCPT | CR4_OSXSAVE; 21 | 22 | lcr0(cr0); 23 | lcr4(cr4); 24 | 25 | /* TODO: avx */ 26 | xsetbv(XCR0, XFEATURE_ENABLED_X87 | XFEATURE_ENABLED_SSE); 27 | #endif 28 | } 29 | 30 | void fpu_user_init(void *data) 31 | { 32 | #if ENABLED(CONFIG_FPU) 33 | struct xsave_area *xsave_area = data; 34 | 35 | /* default values */ 36 | xsave_area->fxsave_area.fcw = 0x37f; 37 | xsave_area->fxsave_area.ftw = 0xffff; 38 | xsave_area->fxsave_area.mxcsr = 0x1f80; 39 | #endif 40 | } 41 | -------------------------------------------------------------------------------- /kernel/hvm.c: -------------------------------------------------------------------------------- 1 | #include "cpuid.h" 2 | #include "hvm.h" 3 | 4 | void svm_init(void); 5 | void vmx_init(void); 6 | 7 | void (*hvm_user_init)(void *hvm, register_t rip); 8 | void (*hvm_switch)(void *hvm, void *stack, register_t cr3, timer_t timer, int launched); 9 | void (*hvm_flush)(void *hvm); 10 | void (*hvm_copy)(void *dst, void *src, pid_t pid); 11 | void (*hvm_set_timer)(void *hvm, timer_t timer); 12 | void (*hvm_set_io_bitmap)(void *hvm, void *addr); 13 | void (*hvm_set_pid)(void *hvm, pid_t pid); 14 | void (*hvm_invalidate_tlb)(pid_t pid); 15 | 16 | void (*hvm_preempt)(void); 17 | void (*hvm_fault)(void); 18 | int (*hvm_extintr)(uint8_t irq); 19 | 20 | void hvm_init(void) 21 | { 22 | if (cpuid_has(CPUID_FEATURE_SVM)) 23 | return svm_init(); 24 | 25 | if (cpuid_has(CPUID_FEATURE_VMX)) 26 | return vmx_init(); 27 | 28 | panic("hvm: no svm/vmx"); 29 | } 30 | -------------------------------------------------------------------------------- /kernel/hvm_support.S: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef __ASSEMBLER__ 4 | #error "Must be included from assembly code" 5 | #endif 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | /* %rax holds the syscall number; use %r10-r11 as scratch registers */ 12 | .macro INVOKE_SYSCALL 13 | /* validate the syscall number */ 14 | cmpq $NR_syscalls, %rax 15 | jb 1f 16 | movq $-ENOSYS, %rax 17 | jmp 2f 18 | 1: 19 | movq $syscalls, %r10 20 | leaq (%r10, %rax, 8), %rax 21 | /* invoke the syscall */ 22 | callq *(%rax) 23 | 2: 24 | .endm 25 | -------------------------------------------------------------------------------- /kernel/include/bootmem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define BOOTMEM_MAP_MAX_SIZE 128 6 | 7 | struct region { 8 | physaddr_t lower, upper; /* [lower, upper) */ 9 | }; 10 | 11 | struct bootmem_map { 12 | size_t size; 13 | struct region regions[BOOTMEM_MAP_MAX_SIZE]; 14 | }; 15 | 16 | extern struct bootmem_map bootmem_map; 17 | 18 | void bootmem_add(physaddr_t addr, size_t size); 19 | void bootmem_remove(physaddr_t addr, size_t size); 20 | bool bootmem_usable(physaddr_t addr, size_t size); 21 | void *bootmem_alloc(size_t alignment, size_t size); 22 | void bootmem_seal(void); 23 | -------------------------------------------------------------------------------- /kernel/include/ctype.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define isspace(c) ((c) == ' ' || ((c) >= '\t' && (c) <= '\r')) 6 | #define isascii(c) (((c) & ~0x7f) == 0) 7 | #define isupper(c) ((c) >= 'A' && (c) <= 'Z') 8 | #define islower(c) ((c) >= 'a' && (c) <= 'z') 9 | #define isalpha(c) (isupper(c) || islower(c)) 10 | #define isdigit(c) ((c) >= '0' && (c) <= '9') 11 | #define isxdigit(c) (isdigit(c) || ((c) >= 'A' && (c) <= 'F') || ((c) >= 'a' && (c) <= 'f')) 12 | #define isprint(c) ((c) >= ' ' && (c) <= '~') 13 | 14 | #define toupper(c) ((c)-0x20 * (((c) >= 'a') && ((c) <= 'z'))) 15 | #define tolower(c) ((c) + 0x20 * (((c) >= 'A') && ((c) <= 'Z'))) 16 | -------------------------------------------------------------------------------- /kernel/include/hvm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | struct trap_regs; 6 | 7 | void hvm_init(void); 8 | extern void (*hvm_user_init)(void *hvm, register_t rip); 9 | extern void (*hvm_switch)(void *hvm, void *stack, register_t cr3, timer_t timer, int launched); 10 | extern void (*hvm_flush)(void *hvm); 11 | extern void (*hvm_copy)(void *dst, void *src, pid_t pid); 12 | extern void (*hvm_set_timer)(void *hvm, timer_t timer); 13 | extern void (*hvm_set_io_bitmap)(void *hvm, void *addr); 14 | extern void (*hvm_set_pid)(void *hvm, pid_t pid); 15 | extern void (*hvm_invalidate_tlb)(pid_t pid); 16 | 17 | /* callback into OS */ 18 | extern void (*hvm_preempt)(void); 19 | extern void (*hvm_fault)(void); 20 | extern int (*hvm_extintr)(uint8_t irq); 21 | -------------------------------------------------------------------------------- /kernel/include/init.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void tsc_init(void); 4 | void trap_init(void); 5 | void cpuid_init(void); 6 | void acpi_init(void); 7 | void mtrr_init(void); 8 | void pmap_init(void); 9 | void xapic_init(void); 10 | void pic_init(void); 11 | void ioapic_init(void); 12 | void fpu_init(void); 13 | void fpu_user_init(void *); 14 | void iommu_init(void); 15 | -------------------------------------------------------------------------------- /kernel/include/iommu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | extern uint16_t iommu_vendor; 6 | extern void (*iommu_reset_dev_root)(uint16_t id); 7 | extern void (*iommu_set_dev_root)(uint16_t id, physaddr_t addr); 8 | extern uint64_t (*iommu_entry)(uint64_t addr, uint64_t perm, size_t level); 9 | extern void (*iommu_set_intremap)(uint16_t index, uint16_t id, uint8_t irq); 10 | extern void (*iommu_reset_intremap)(uint16_t index); 11 | extern void (*iommu_flush)(void); 12 | extern void (*iommu_early_set_dev_region)(physaddr_t start, physaddr_t end); 13 | -------------------------------------------------------------------------------- /kernel/include/machine/env.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | struct env { 6 | /* Root container of this environment */ 7 | struct container *container; 8 | /* Current program counter */ 9 | uint64_t pc; 10 | void *pgdir; 11 | struct trap_regs regs; 12 | }; 13 | -------------------------------------------------------------------------------- /kernel/include/machine/memlayout.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #define TEXT_OFFSET SZ_2M 7 | 8 | /* kernel stack */ 9 | #define STACK_SIZE (2 * PAGE_SIZE) 10 | 11 | #define GDT_ENTRY_CS 1 12 | #define GDT_ENTRY_DS 2 13 | /* TSS selector takes up two slots */ 14 | #define GDT_ENTRY_TSS 3 15 | 16 | #define GDT_CS (GDT_ENTRY_CS << 3) 17 | #define GDT_DS (GDT_ENTRY_DS << 3) 18 | #define GDT_TSS (GDT_ENTRY_TSS << 3) 19 | -------------------------------------------------------------------------------- /kernel/include/pagemap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | int pagemap_insert(struct capability pagemap, struct capability item, uintptr_t addr, 6 | unsigned flags); 7 | -------------------------------------------------------------------------------- /kernel/include/stdio.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | void putchar(int c); 6 | void puts(const char *s); 7 | 8 | int kvprintf(const char *fmt, void (*func)(int, void *), void *arg, va_list ap) __printf(1, 0); 9 | int printf(const char *fmt, ...) __printf(1, 2); 10 | int vprintf(const char *fmt, va_list ap) __printf(1, 0); 11 | int snprintf(char *str, size_t size, const char *fmt, ...) __printf(3, 4); 12 | int vsnprintf(char *str, size_t size, const char *fmt, va_list ap) __printf(3, 0); 13 | 14 | int getchar(void); 15 | -------------------------------------------------------------------------------- /kernel/include/stdlib.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | unsigned long strtoul(const char *nptr, char **endptr, int base); 4 | -------------------------------------------------------------------------------- /kernel/include/string.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | void *memchr(const void *s, int c, size_t n); 6 | int memcmp(const void *s1, const void *s2, size_t n); 7 | void *memmove(void *dst, const void *src, size_t n); 8 | void *memcpy(void *restrict dst, const void *restrict src, size_t n); 9 | void *memset(void *s, int c, size_t n); 10 | void bzero(void *s, size_t n); 11 | 12 | size_t strlen(const char *s); 13 | size_t strnlen(const char *s, size_t maxlen); 14 | char *strchr(const char *s, int c); 15 | int strcmp(const char *s1, const char *s2); 16 | int strncmp(const char *s1, const char *s2, size_t n); 17 | char *strcpy(char *restrict to, const char *restrict from); 18 | char *strncpy(char *restrict dst, const char *restrict src, size_t n); 19 | char *strcat(char *restrict s, const char *restrict append); 20 | char *strsep(char **stringp, const char *delim); 21 | -------------------------------------------------------------------------------- /kernel/include/symtable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifndef __ASSEMBLER__ 6 | 7 | extern char _start[], _etext[], _edata[], _end[]; 8 | 9 | #endif /* !__ASSEMBLER__ */ 10 | -------------------------------------------------------------------------------- /kernel/include/time.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define NSEC_PER_SEC UINT64_C(1000000000) 6 | #define FSEC_PER_SEC UINT64_C(1000000000000000) 7 | #define FSEC_PER_NSEC (FSEC_PER_SEC / NSEC_PER_SEC) 8 | 9 | typedef uint64_t seconds_t; 10 | typedef uint64_t nanoseconds_t; 11 | typedef uint64_t milliseconds_t; 12 | typedef uint64_t cycle_t; 13 | 14 | nanoseconds_t cycles_to_ns(cycle_t cycle); 15 | cycle_t ns_to_cycles(nanoseconds_t ns); 16 | cycle_t ms_to_cycles(milliseconds_t ms); 17 | 18 | nanoseconds_t uptime(void); 19 | void nanodelay(nanoseconds_t delay); 20 | -------------------------------------------------------------------------------- /kernel/ioapic.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define IOREGSEL (0x00 / 4) 5 | #define IOWIN (0x10 / 4) 6 | 7 | #define IOAPICID 0x00 /* Register index: ID */ 8 | #define IOAPICVER 0x01 /* Register index: version */ 9 | #define IOREDTBL 0x10 /* Redirection table base */ 10 | 11 | #define INT_DISABLED 0x00010000 /* Interrupt disabled */ 12 | #define INT_LEVEL 0x00008000 /* Level-triggered (vs edge-) */ 13 | #define INT_ACTIVELOW 0x00002000 /* Active low (vs high) */ 14 | #define INT_LOGICAL 0x00000800 /* Destination is CPU id (vs APIC ID) */ 15 | 16 | static uint32_t *ioapic = (void *)0xfec00000; 17 | 18 | static uint32_t ioapic_read(int reg) 19 | { 20 | mmio_write32(ioapic + IOREGSEL, reg); 21 | return mmio_read32(ioapic + IOWIN); 22 | } 23 | 24 | static void ioapic_write(int reg, uint32_t data) 25 | { 26 | mmio_write32(ioapic + IOREGSEL, reg); 27 | mmio_write32(ioapic + IOWIN, data); 28 | } 29 | 30 | void ioapic_init(void) 31 | { 32 | int i, reg_ver, ver, pins; 33 | 34 | reg_ver = ioapic_read(IOAPICVER); 35 | ver = reg_ver & 0xff; 36 | pins = ((reg_ver >> 16) & 0xff) + 1; 37 | pr_info("ioapic: 0x%016" PRIxPTR " v%02x [global_irq %02d-%02d]\n", 38 | (uintptr_t)ioapic, ver, 0, pins - 1); 39 | 40 | /* mark all interrupts edge-triggered, active high, disabled, and not routed to any CPUs */ 41 | for (i = 0; i < pins; ++i) { 42 | ioapic_write(IOREDTBL + 2 * i, INT_DISABLED | (TRAP_IRQ0 + i)); 43 | ioapic_write(IOREDTBL + 2 * i + 1, 0); 44 | } 45 | } 46 | 47 | void ioapic_enable(int irq, uint32_t apicid) 48 | { 49 | /* 50 | * Mark interrupt edge-triggered, active high, 51 | * enabled, and routed to the given cpunum, 52 | * which happens to be that cpu's APIC ID. 53 | */ 54 | ioapic_write(IOREDTBL + 2 * irq, TRAP_IRQ0 + irq); 55 | ioapic_write(IOREDTBL + 2 * irq + 1, apicid << 24); 56 | pr_info("ioapic: enable irq %d\n", irq); 57 | } 58 | -------------------------------------------------------------------------------- /kernel/iommu.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | uint16_t iommu_vendor; 5 | void (*iommu_reset_dev_root)(uint16_t id); 6 | void (*iommu_set_dev_root)(uint16_t id, physaddr_t addr); 7 | uint64_t (*iommu_entry)(uint64_t addr, uint64_t perm, size_t level); 8 | void (*iommu_set_intremap)(uint16_t index, uint16_t devid, uint8_t vector); 9 | void (*iommu_reset_intremap)(uint16_t index); 10 | void (*iommu_flush)(void); 11 | void (*iommu_early_set_dev_region)(physaddr_t start, physaddr_t end); 12 | 13 | void intel_iommu_init(void); 14 | void amd_iommu_init(void); 15 | 16 | static void stub_iommu_reset_dev_root(uint16_t id) 17 | { 18 | } 19 | static void stub_iommu_set_dev_root(uint16_t id, physaddr_t addr) 20 | { 21 | } 22 | extern uint64_t stub_iommu_entry(uint64_t addr, uint64_t perm, uint64_t level) 23 | { 24 | return 0; 25 | } 26 | static void stub_iommu_set_intremap(uint16_t index, uint16_t id, uint8_t irq) 27 | { 28 | } 29 | static void stub_iommu_reset_intremap(uint16_t index) 30 | { 31 | } 32 | static void stub_iommu_flush(void) 33 | { 34 | } 35 | static void stub_iommu_early_set_dev_region(physaddr_t start, physaddr_t end) 36 | { 37 | } 38 | 39 | void iommu_init(void) 40 | { 41 | acpi_status status; 42 | struct acpi_table_header *header; 43 | 44 | status = acpi_get_table(ACPI_SIG_DMAR, 0, &header); 45 | if (ACPI_SUCCESS(status)) 46 | return intel_iommu_init(); 47 | 48 | status = acpi_get_table(ACPI_SIG_IVRS, 0, &header); 49 | if (ACPI_SUCCESS(status)) 50 | return amd_iommu_init(); 51 | 52 | pr_warn("iommu: DMAR/IVRS not found\n"); 53 | iommu_reset_dev_root = stub_iommu_reset_dev_root; 54 | iommu_set_dev_root = stub_iommu_set_dev_root; 55 | iommu_entry = stub_iommu_entry; 56 | iommu_set_intremap = stub_iommu_set_intremap; 57 | iommu_reset_intremap = stub_iommu_reset_intremap; 58 | iommu_flush = stub_iommu_flush; 59 | iommu_early_set_dev_region = stub_iommu_early_set_dev_region; 60 | } 61 | -------------------------------------------------------------------------------- /kernel/kernel.lds.S: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | OUTPUT_ARCH(i386:x86-64) 4 | 5 | SECTIONS 6 | { 7 | . = TEXT_OFFSET; 8 | _start = .; 9 | 10 | .text : { 11 | *(.head.text) 12 | *(.text .text.*) 13 | _etext = .; 14 | } 15 | 16 | .rodata : { 17 | *(.rodata .rodata.*) 18 | } 19 | 20 | .data : { 21 | *(.data .data.*) 22 | _edata = .; 23 | } 24 | 25 | .bss : { 26 | *(.bss .bss.*) 27 | } 28 | 29 | . = ALIGN(SZ_2M); 30 | _end = .; 31 | } 32 | -------------------------------------------------------------------------------- /kernel/mtrr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static char *names[] = { 5 | [MTRR_UNCACHEABLE] = "uncacheable", [MTRR_WRITE_COMBINING] = "write-combining", 6 | [MTRR_WRITE_THROUGH] = "write-through", [MTRR_WRITE_PROTECTED] = "write-protected", 7 | [MTRR_WRITE_BACK] = "write-back", 8 | }; 9 | 10 | void mtrr_init(void) 11 | { 12 | uint64_t cap; 13 | size_t vcnt, i; 14 | 15 | if (!cpuid_has(CPUID_FEATURE_MTRR)) 16 | return; 17 | cap = rdmsr(MSR_IA32_MTRRCAP); 18 | vcnt = bit_get_field(cap, MTRRCAP_VCNT); 19 | pr_info("mtrr: %zu variable ranges\n", vcnt); 20 | 21 | for (i = 0; i < vcnt; ++i) { 22 | uint64_t base, mask, addr, size, type; 23 | char *name = "?"; 24 | 25 | base = rdmsr(MSR_IA32_MTRR_PHYSBASE(i)); 26 | mask = rdmsr(MSR_IA32_MTRR_PHYSMASK(i)); 27 | if (!(mask & MTRR_PHYSMASK_VALID)) 28 | continue; 29 | addr = base & MTRR_PHYSBASE_PHYSBASE; 30 | size = ((~((mask)&MTRR_PHYSMASK_PHYSMASK) & BITMASK64(39, 0)) + 1); 31 | type = base & MTRR_PHYSBASE_TYPE; 32 | if (type < countof(names) && names[type]) 33 | name = names[type]; 34 | pr_info("mtrr: 0x%016" PRIx64 "-0x%016" PRIx64 ": %s\n", addr, addr + size - 1, name); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /kernel/svm_entry.S: -------------------------------------------------------------------------------- 1 | #include 2 | #include "hvm_support.S" 3 | #include "svm.h" 4 | #include "svm_assym.h" 5 | 6 | .global svm_loop 7 | svm_loop: 8 | LOAD_FPU_REGS 9 | LOAD_EXTRA_REGS 10 | LOAD_RAX_REG 11 | 12 | svm_fast_path: 13 | LOAD_C_REGS_EXCEPT_RAX 14 | /* 15 | * Clear GIF and turn on IF for guest (v_intr_masking), 16 | * to allow vmexits by external interrupts. 17 | */ 18 | vmload %rax 19 | sti 20 | vmrun %rax 21 | cli 22 | vmsave %rax 23 | /* NMI may happen here */ 24 | /* guest %rsp saved in vmcb; kernel stack pointer unchanged */ 25 | SAVE_C_REGS 26 | /* r10-11 are temporary registers */ 27 | movq VMCB_EXITCODE(%rax), %r10 28 | cmpq $VMCB_EXIT_VMMCALL, %r10 29 | je handle_syscall 30 | cmpq $VMCB_EXIT_INTR, %r10 31 | je handle_intr 32 | /* slow path */ 33 | SAVE_EXTRA_REGS 34 | SAVE_FPU_REGS 35 | movq %rax, %rdi 36 | movq %rsp, %rsi 37 | call svm_dispatch 38 | jmp svm_loop 39 | 40 | handle_syscall: 41 | /* bump %rip to skip vmmcall */ 42 | addq $3, VMCB_RIP(%rax) 43 | /* load the syscall number */ 44 | movq VMCB_RAX(%rax), %rax 45 | /* invoke the syscall */ 46 | INVOKE_SYSCALL 47 | /* copy the return value */ 48 | movq %rax, %r10 49 | /* restore the vmcb */ 50 | LOAD_RAX_REG 51 | /* save the return value into vmcb */ 52 | movq %r10, VMCB_RAX(%rax) 53 | jmp svm_fast_path 54 | 55 | handle_intr: 56 | /* don't change %rip */ 57 | 58 | stgi 59 | /* 60 | * find out the vector by triggering the interrupt; 61 | * need one nop to pass the interrupt shadow 62 | */ 63 | sti 64 | /* vector using the kernel IDT */ 65 | nop 66 | cli 67 | clgi 68 | /* restore the vmcb */ 69 | LOAD_RAX_REG 70 | /* don't change %rip */ 71 | jmp svm_fast_path 72 | -------------------------------------------------------------------------------- /kernel/svm_genassym.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "svm.h" 3 | 4 | ASSYM(VMCB_EXITCODE, offsetof(struct vmcb, ctrl.exitcode)); 5 | ASSYM(VMCB_RAX, offsetof(struct vmcb, state.rax)); 6 | ASSYM(VMCB_RIP, offsetof(struct vmcb, state.rip)); 7 | -------------------------------------------------------------------------------- /kernel/tsc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define IO_TIMER1 0x040 /* 8253 Timer #1 */ 5 | #define TIMER_FREQ 1193182 6 | #define TIMER_CNTR (IO_TIMER1 + 0) /* timer counter port */ 7 | #define TIMER_MODE (IO_TIMER1 + 3) /* timer mode port */ 8 | #define TIMER_SEL0 0x00 /* select counter 0 */ 9 | #define TIMER_TCOUNT 0x00 /* mode 0, terminal count */ 10 | #define TIMER_16BIT 0x30 /* r/w counter 16 bits, LSB first */ 11 | #define TIMER_STAT 0xe0 /* read status mode */ 12 | #define TIMER_STAT0 (TIMER_STAT | 0x2) /* status mode counter 0 */ 13 | 14 | static uint64_t tsc_mhz; 15 | 16 | void tsc_init(void) 17 | { 18 | uint64_t xticks, start, end; 19 | 20 | /* PIT countdown from 2^16 - 1 */ 21 | xticks = 0xffff; 22 | outb(TIMER_MODE, TIMER_SEL0 | TIMER_TCOUNT | TIMER_16BIT); 23 | outb(IO_TIMER1, xticks % 256); 24 | outb(IO_TIMER1, xticks / 256); 25 | 26 | /* wait until OUT bit of status byte is set */ 27 | start = rdtsc(); 28 | do { 29 | outb(TIMER_MODE, TIMER_STAT0); 30 | if (rdtsc() - start > BIT64(32)) { 31 | pr_info("tsc: PIT stuck, assuming 2GHz\n"); 32 | tsc_mhz = 2 * 1000; 33 | return; 34 | } 35 | } while (!(inb(TIMER_CNTR) & 0x80)); 36 | end = rdtsc(); 37 | 38 | tsc_mhz = ((end - start) * 10) / ((xticks * 10000000) / TIMER_FREQ); 39 | pr_info("tsc: %" PRIu64 " MHz\n", tsc_mhz); 40 | } 41 | 42 | /* convert cyles to nanoseconds: 43 | * ns = cycles / (freq / NSEC_PER_SECOND) 44 | * ns = cycles * (NSEC_PER_SECOND / freq) 45 | * ns = cycles * (10^3 / freq_mhz) 46 | */ 47 | nanoseconds_t cycles_to_ns(cycle_t cycle) 48 | { 49 | if (!tsc_mhz) 50 | return 0; 51 | return cycle * 1000 / tsc_mhz; 52 | } 53 | 54 | cycle_t ns_to_cycles(nanoseconds_t ns) 55 | { 56 | return ns * tsc_mhz / 1000; 57 | } 58 | 59 | cycle_t ms_to_cycles(milliseconds_t ms) 60 | { 61 | return ms * tsc_mhz * 1000; 62 | } 63 | 64 | nanoseconds_t uptime(void) 65 | { 66 | return cycles_to_ns(rdtsc()); 67 | } 68 | 69 | void nanodelay(nanoseconds_t delay) 70 | { 71 | uint64_t tsc_delay, start; 72 | 73 | tsc_delay = (tsc_mhz * delay) / 1000; 74 | start = rdtsc(); 75 | while (rdtsc() - start < tsc_delay) 76 | pause(); 77 | } 78 | -------------------------------------------------------------------------------- /kernel/vmx_entry.S: -------------------------------------------------------------------------------- 1 | #include "hvm_support.S" 2 | #include "vmx.h" 3 | 4 | .global vmx_entry 5 | vmx_entry: 6 | SAVE_C_REGS_EXCEPT_RAX 7 | /* use r10-11 as temporary registers */ 8 | 9 | movq $VMCS_EXIT_REASON, %r11 10 | vmread %r11, %r10 11 | 12 | cmpq $EXIT_REASON_VMCALL, %r10 13 | je handle_syscall 14 | 15 | cmpq $EXIT_REASON_CPUID, %r10 16 | je handle_cpuid 17 | 18 | cmpq $EXIT_REASON_EXT_INTR, %r10 19 | je handle_ext_intr 20 | 21 | /* slow path */ 22 | SAVE_RAX_REG 23 | SAVE_EXTRA_REGS 24 | SAVE_FPU_REGS 25 | movq %rsp, %rdi 26 | /* vmx_dispatch will call vmclear so vmlaunch is okay later */ 27 | callq vmx_dispatch 28 | jmp vmx_resume 29 | 30 | .global vmx_launch 31 | vmx_launch: 32 | LOAD_FPU_REGS 33 | LOAD_EXTRA_REGS 34 | LOAD_C_REGS 35 | vmlaunch 36 | 37 | .global vmx_resume 38 | vmx_resume: 39 | LOAD_FPU_REGS 40 | LOAD_EXTRA_REGS 41 | LOAD_C_REGS 42 | vmresume 43 | 44 | handle_syscall: 45 | /* bump rip to skip vmcall */ 46 | movq $VMCS_GUEST_RIP, %r11 47 | vmread %r11, %r10 48 | addq $3, %r10 49 | vmwrite %r10, %r11 50 | /* invoke the syscall */ 51 | INVOKE_SYSCALL 52 | /* %rax holds the return value */ 53 | LOAD_C_REGS_EXCEPT_RAX 54 | vmresume 55 | 56 | /* cpuid causes vmexit unconditionally */ 57 | handle_cpuid: 58 | /* bump %rip to skip cpuid */ 59 | movq $VMCS_GUEST_RIP, %r11 60 | vmread %r11, %r10 61 | addq $2, %r10 62 | vmwrite %r10, %r11 63 | /* 64 | * input: %rax, %rcx 65 | * output: %eax, %ebx, %ecx, %edx 66 | */ 67 | cpuid 68 | LOAD_C_REGS_EXCEPT_RAX_RCX_RDX 69 | vmresume 70 | 71 | handle_ext_intr: 72 | /* don't change %rip */ 73 | SAVE_RAX_REG 74 | callq vmx_extintr 75 | LOAD_C_REGS 76 | vmresume 77 | -------------------------------------------------------------------------------- /lib/console.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define CONSBUFSIZ 512 4 | 5 | static struct { 6 | uint8_t buf[CONSBUFSIZ]; 7 | size_t rpos; 8 | size_t wpos; 9 | } queue; 10 | 11 | static SLIST_HEAD(console_list, console_device) devs; 12 | 13 | static void console_intr(int (*proc)(void *), void *arg) 14 | { 15 | int c; 16 | 17 | while ((c = (*proc)(arg)) >= 0) { 18 | if (c == 0) 19 | continue; 20 | queue.buf[queue.wpos++] = c; 21 | if (queue.wpos == CONSBUFSIZ) 22 | queue.wpos = 0; 23 | } 24 | } 25 | 26 | int console_getc(void) 27 | { 28 | struct console_device *dev; 29 | 30 | SLIST_FOREACH(dev, &devs, link) 31 | { 32 | if (dev->getc) 33 | console_intr(dev->getc, dev->arg); 34 | } 35 | 36 | if (queue.rpos != queue.wpos) { 37 | int c = queue.buf[queue.rpos++]; 38 | 39 | if (queue.rpos == CONSBUFSIZ) 40 | queue.rpos = 0; 41 | return c; 42 | } 43 | 44 | return 0; 45 | } 46 | 47 | void console_write(const char *s, size_t n) 48 | { 49 | struct console_device *dev; 50 | 51 | SLIST_FOREACH(dev, &devs, link) 52 | { 53 | if (dev->write) 54 | dev->write(dev->arg, s, n); 55 | } 56 | } 57 | 58 | void console_register(struct console_device *dev) 59 | { 60 | SLIST_INSERT_HEAD(&devs, dev, link); 61 | } 62 | -------------------------------------------------------------------------------- /lib/panic.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void panic(const char *fmt, ...) 4 | { 5 | va_list ap; 6 | 7 | va_start(ap, fmt); 8 | if (fmt) { 9 | pr_crit("kernel panic: "); 10 | vsyslog(LOG_CRIT, fmt, ap); 11 | pr_crit("\n"); 12 | } 13 | va_end(ap); 14 | 15 | /* QEMU's -isa-debug-exit */ 16 | outb(0x501, 0); 17 | /* Bochs shutdown port */ 18 | outsb(0x8900, "Shutdown", 8); 19 | 20 | while (1) 21 | halt(); 22 | } 23 | -------------------------------------------------------------------------------- /lib/stdlib.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | unsigned long strtoul(const char *nptr, char **endptr, int base) 4 | { 5 | const char *s = nptr; 6 | unsigned long acc; 7 | unsigned char c; 8 | unsigned long cutoff; 9 | int neg = 0, any, cutlim; 10 | 11 | /* 12 | * See strtol for comments as to the logic used. 13 | */ 14 | do { 15 | c = *s++; 16 | } while (isspace(c)); 17 | if (c == '-') { 18 | neg = 1; 19 | c = *s++; 20 | } else if (c == '+') 21 | c = *s++; 22 | if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { 23 | c = s[1]; 24 | s += 2; 25 | base = 16; 26 | } 27 | if (base == 0) 28 | base = c == '0' ? 8 : 10; 29 | cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; 30 | cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; 31 | for (acc = 0, any = 0;; c = *s++) { 32 | if (!isascii(c)) 33 | break; 34 | if (isdigit(c)) 35 | c -= '0'; 36 | else if (isalpha(c)) 37 | c -= isupper(c) ? 'A' - 10 : 'a' - 10; 38 | else 39 | break; 40 | if (c >= base) 41 | break; 42 | if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) 43 | any = -1; 44 | else { 45 | any = 1; 46 | acc *= base; 47 | acc += c; 48 | } 49 | } 50 | if (any < 0) 51 | acc = ULONG_MAX; 52 | else if (neg) 53 | acc = -acc; 54 | if (endptr != NULL) 55 | *endptr = (char *)(any ? s - 1 : nptr); 56 | return acc; 57 | } 58 | -------------------------------------------------------------------------------- /lib/syslog.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | static int logpriority = LOG_DEBUG; 8 | static int lognewline = 1; 9 | 10 | /* kernel log ring buffer */ 11 | static char klog_buf[KLOG_NR_LINES][KLOG_LINE_SIZE]; 12 | static size_t klog_line; 13 | 14 | static void putch(int c, void *arg) 15 | { 16 | int *newline = arg, len; 17 | static char line_buf[KLOG_LINE_SIZE]; 18 | static size_t line_size; 19 | 20 | if (*newline) { 21 | nanoseconds_t up = uptime(); 22 | uint64_t s = up / 1000000000; 23 | uint64_t ms = (up / 1000) % 1000000; 24 | 25 | *newline = 0; 26 | /* [seconds.microseconds] */ 27 | bzero(line_buf, KLOG_LINE_SIZE); 28 | len = snprintf(line_buf, KLOG_LINE_SIZE, "[%5" PRIu64 ".%06" PRIu64 "] ", s, ms); 29 | console_write(line_buf, len); 30 | line_size = len; 31 | } 32 | 33 | putchar(c); 34 | 35 | assert(line_size < KLOG_LINE_SIZE, "line too long"); 36 | line_buf[line_size] = (uint8_t)c; 37 | ++line_size; 38 | 39 | if (c == '\n') { 40 | *newline = 1; 41 | memcpy(klog_buf[klog_line % KLOG_NR_LINES], line_buf, KLOG_LINE_SIZE); 42 | ++klog_line; 43 | } 44 | } 45 | 46 | void syslog(int priority, const char *fmt, ...) 47 | { 48 | va_list ap; 49 | 50 | va_start(ap, fmt); 51 | vsyslog(priority, fmt, ap); 52 | va_end(ap); 53 | } 54 | 55 | void vsyslog(int priority, const char *fmt, va_list ap) 56 | { 57 | if (priority > logpriority) 58 | return; 59 | kvprintf(fmt, putch, &lognewline, ap); 60 | } 61 | 62 | int syslog_read(void *dest, size_t n, size_t off) 63 | { 64 | size_t i, start, len; 65 | const char *line_buf; 66 | 67 | /* log has wrapped around: start from klog_line rather than 0 */ 68 | if (klog_line >= KLOG_NR_LINES) 69 | start = klog_line; 70 | else 71 | start = 0; 72 | 73 | for (i = 0; i < KLOG_NR_LINES; ++i) { 74 | line_buf = klog_buf[(start + i) % KLOG_NR_LINES]; 75 | len = strnlen(line_buf, KLOG_LINE_SIZE); 76 | if (off < len) { 77 | memcpy(dest, line_buf + off, len - off); 78 | return len - off; 79 | } 80 | off -= len; 81 | } 82 | 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /scripts/check-hv6-invariants.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | import os 3 | import sys 4 | import subprocess 5 | import time 6 | 7 | q = subprocess.Popen('make hv6-qemu', stdout=subprocess.PIPE, shell=True) 8 | 9 | time.sleep(10) 10 | 11 | q.terminate() 12 | 13 | os.popen('killall qemu-system-x86_64') 14 | 15 | buf = q.stdout.read(2 ** 20) 16 | 17 | print buf 18 | 19 | if 'checking invariants done' in buf: 20 | sys.exit(0) 21 | else: 22 | sys.exit(1) 23 | -------------------------------------------------------------------------------- /scripts/configure_bochs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # 4 | # Copyright 2017 Hyperkernel Authors 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | read -p 'Install Prefix> ' BOCHS_PREFIX 20 | ./configure --enable-disasm --enable-x86-64 --enable-all-optimizations --enable-gdb-stub --enable-fpu --enable-cdrom --enable-plugins --enable-pci --enable-alignment-check --enable-debugger-gui --enable-iodebug --enable-logging --enable-cpu-level=6 --with-term --with-sdl2 --with-nogui --enable-svm --enable-avx --enable-evex --enable-vmx=2 --disable-show-ips --prefix="${BOCHS_PREFIX}" 21 | 22 | -------------------------------------------------------------------------------- /scripts/configure_qemu.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # 4 | # Copyright 2017 Hyperkernel Authors 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | read -p 'Install Prefix> ' QEMU_PREFIX 20 | ./configure --target-list="x86_64-softmmu" --prefix="${QEMU_PREFIX}" --disable-cocoa --enable-sdl 21 | -------------------------------------------------------------------------------- /scripts/genassym.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # $FreeBSD$ 3 | 4 | usage() 5 | { 6 | echo "usage: genassym [-o outfile] objfile" 7 | exit 1 8 | } 9 | 10 | 11 | work() 12 | { 13 | ${NM:='nm'} ${NMFLAGS} "$1" | ${AWK:='awk'} ' 14 | / C .*sign$/ { 15 | sign = substr($1, length($1) - 3, 4) 16 | sub("^0*", "", sign) 17 | if (sign != "") 18 | sign = "-" 19 | } 20 | / C .*w0$/ { 21 | w0 = substr($1, length($1) - 3, 4) 22 | } 23 | / C .*w1$/ { 24 | w1 = substr($1, length($1) - 3, 4) 25 | } 26 | / C .*w2$/ { 27 | w2 = substr($1, length($1) - 3, 4) 28 | } 29 | / C .*w3$/ { 30 | w3 = substr($1, length($1) - 3, 4) 31 | w = w3 w2 w1 w0 32 | sub("^0*", "", w) 33 | if (w == "") 34 | w = "0" 35 | sub("w3$", "", $3) 36 | # This still has minor problems representing INT_MIN, etc. 37 | # E.g., 38 | # with 32-bit 2''s complement ints, this prints -0x80000000, 39 | # which has the wrong type (unsigned int). 40 | printf("#define\t%s\t%s0x%s\n", $3, sign, w) 41 | } ' 42 | } 43 | 44 | 45 | # 46 | #MAIN PROGGRAM 47 | # 48 | use_outfile="no" 49 | while getopts "o:" option 50 | do 51 | case "$option" in 52 | o) outfile="$OPTARG" 53 | use_outfile="yes";; 54 | *) usage;; 55 | esac 56 | done 57 | shift $(($OPTIND - 1)) 58 | case $# in 59 | 1) ;; 60 | *) usage;; 61 | esac 62 | 63 | if [ "$use_outfile" = "yes" ] 64 | then 65 | work $1 3>"$outfile" >&3 3>&- 66 | else 67 | work $1 68 | fi 69 | 70 | -------------------------------------------------------------------------------- /scripts/gensymtable.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import fileinput 4 | 5 | count = 0 6 | print('#include ') 7 | print('') 8 | print('const struct symbol ksymtable[] = {') 9 | for line in fileinput.input(): 10 | e = line.strip().split() 11 | if len(e) == 2: 12 | # weak symbols 13 | addr = 0 14 | typ, name = e 15 | else: 16 | assert len(e) == 3 17 | addr, typ, name = e 18 | count += 1 19 | print('\t{{ 0x{}, \'{}\', "{}" }},'.format(addr, typ, name)) 20 | print('};') 21 | print('') 22 | print('const uint64_t ksymtable_count = {};'.format(count)) 23 | -------------------------------------------------------------------------------- /scripts/ldcheck.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # Expects input in the format yielded by 3 | # nm --numeric-sort --print-size 4 | 5 | import sys 6 | 7 | def main(): 8 | addr = 1024 * 1024 9 | for line in sys.stdin: 10 | line = line.strip().split() 11 | if len(line) != 4: 12 | continue 13 | start = int(line[0], 16) 14 | end = start + int(line[1], 16) 15 | print("%016x-%016x: %s" % (start, end - 1, line[-1])) 16 | # check no overlap 17 | assert addr <= start 18 | addr = end 19 | 20 | if __name__ == "__main__": 21 | main() 22 | -------------------------------------------------------------------------------- /scripts/no_undef.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | perl -p -i \ 3 | -e 's/nsw/ /g; s/nuw/ /g; s/exact/ /g; s/inbounds/ /g' \ 4 | "${1}" 5 | -------------------------------------------------------------------------------- /scripts/pytest: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | # -*- coding: utf-8 -*- 4 | import re 5 | import sys 6 | 7 | from xdist.scheduler.load import LoadScheduling 8 | 9 | def check_schedule(self, node, duration=0): 10 | if node.shutting_down: 11 | return 12 | 13 | if self.pending: 14 | self._send_tests(node, 1) 15 | self.log("num items waiting for node:", len(self.pending)) 16 | 17 | 18 | LoadScheduling.check_schedule = check_schedule 19 | from pytest import main 20 | 21 | if __name__ == '__main__': 22 | sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) 23 | sys.exit(main()) 24 | -------------------------------------------------------------------------------- /scripts/stackcheck_config.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2017 Hyperkernel Authors 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | check = [ 18 | # system calls 19 | lambda s: s.startswith('sys_'), 20 | ] 21 | 22 | maxusage = 1024 23 | -------------------------------------------------------------------------------- /user/lwip/FILES: -------------------------------------------------------------------------------- 1 | api/ - The code for the high-level wrapper API. Not needed if 2 | you use the lowel-level call-back/raw API. 3 | 4 | apps/ - Higher layer applications that are specifically programmed 5 | with the lwIP low-level raw API. 6 | 7 | core/ - The core of the TPC/IP stack; protocol implementations, 8 | memory and buffer management, and the low-level raw API. 9 | 10 | include/ - lwIP include files. 11 | 12 | netif/ - Generic network interface device drivers are kept here. 13 | 14 | For more information on the various subdirectories, check the FILES 15 | file in each directory. 16 | -------------------------------------------------------------------------------- /user/lwip/apps/httpd/fs/404.html: -------------------------------------------------------------------------------- 1 | 2 | lwIP - A Lightweight TCP/IP Stack 3 | 4 | 5 | 6 | 19 |
7 | SICS logo 9 | 10 |

lwIP - A Lightweight TCP/IP Stack

11 |

404 - Page not found

12 |

13 | Sorry, the page you are requesting was not found on this 14 | server. 15 |

16 |
17 |   18 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /user/lwip/apps/httpd/fs/img/sics.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uw-unsat/hyperkernel/50d6bada5de63c56376bdc4dba6159788847cc95/user/lwip/apps/httpd/fs/img/sics.gif -------------------------------------------------------------------------------- /user/lwip/apps/httpd/fs/index.html: -------------------------------------------------------------------------------- 1 | 2 | lwIP - A Lightweight TCP/IP Stack 3 | 4 | 5 | 6 | 44 |
7 | SICS logo 9 | 10 |

lwIP - A Lightweight TCP/IP Stack

11 |

12 | The web page you are watching was served by a simple web 13 | server running on top of the lightweight TCP/IP stack lwIP. 15 |

16 |

17 | lwIP is an open source implementation of the TCP/IP 18 | protocol suite that was originally written by Adam Dunkels 20 | of the Swedish Institute of Computer Science but now is 21 | being actively developed by a team of developers 22 | distributed world-wide. Since it's release, lwIP has 23 | spurred a lot of interest and has been ported to several 24 | platforms and operating systems. lwIP can be used either 25 | with or without an underlying OS. 26 |

27 |

28 | The focus of the lwIP TCP/IP implementation is to reduce 29 | the RAM usage while still having a full scale TCP. This 30 | makes lwIP suitable for use in embedded systems with tens 31 | of kilobytes of free RAM and room for around 40 kilobytes 32 | of code ROM. 33 |

34 |

35 | More information about lwIP can be found at the lwIP 36 | homepage at http://savannah.nongnu.org/projects/lwip/ 38 | or at the lwIP wiki at http://lwip.wikia.com/. 40 |

41 |
42 |   43 |
45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /user/lwip/apps/httpd/fsdata.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2001-2003 Swedish Institute of Computer Science. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 3. The name of the author may not be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 21 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 24 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 25 | * OF SUCH DAMAGE. 26 | * 27 | * This file is part of the lwIP TCP/IP stack. 28 | * 29 | * Author: Adam Dunkels 30 | * 31 | */ 32 | #ifndef LWIP_FSDATA_H 33 | #define LWIP_FSDATA_H 34 | 35 | #include "lwip/apps/httpd_opts.h" 36 | #include "lwip/apps/fs.h" 37 | 38 | struct fsdata_file { 39 | const struct fsdata_file *next; 40 | const unsigned char *name; 41 | const unsigned char *data; 42 | int len; 43 | u8_t flags; 44 | #if HTTPD_PRECALCULATED_CHECKSUM 45 | u16_t chksum_count; 46 | const struct fsdata_chksum *chksum; 47 | #endif /* HTTPD_PRECALCULATED_CHECKSUM */ 48 | }; 49 | 50 | #endif /* LWIP_FSDATA_H */ 51 | -------------------------------------------------------------------------------- /user/lwip/apps/httpd/makefsdata/readme.txt: -------------------------------------------------------------------------------- 1 | This directory contains a script ('makefsdata') to create C code suitable for 2 | httpd for given html pages (or other files) in a directory. 3 | 4 | There is also a plain C console application doing the same and extended a bit. 5 | 6 | Usage: htmlgen [targetdir] [-s] [-i]s 7 | targetdir: relative or absolute path to files to convert 8 | switch -s: toggle processing of subdirectories (default is on) 9 | switch -e: exclude HTTP header from file (header is created at runtime, default is on) 10 | switch -11: include HTTP 1.1 header (1.0 is default) 11 | 12 | if targetdir not specified, makefsdata will attempt to 13 | process files in subdirectory 'fs'. 14 | -------------------------------------------------------------------------------- /user/lwip/core/ipv6/dhcp6.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * 4 | * DHCPv6. 5 | */ 6 | 7 | /* 8 | * Copyright (c) 2010 Inico Technologies Ltd. 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 3. The name of the author may not be used to endorse or promote products 20 | * derived from this software without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 23 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 25 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 26 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 27 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 30 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 31 | * OF SUCH DAMAGE. 32 | * 33 | * This file is part of the lwIP TCP/IP stack. 34 | * 35 | * Author: Ivan Delamer 36 | * 37 | * 38 | * Please coordinate changes and requests with Ivan Delamer 39 | * 40 | */ 41 | 42 | #include "lwip/opt.h" 43 | 44 | #if LWIP_IPV6 && LWIP_IPV6_DHCP6 /* don't build if not configured for use in lwipopts.h */ 45 | 46 | #include "lwip/ip6_addr.h" 47 | #include "lwip/def.h" 48 | 49 | 50 | #endif /* LWIP_IPV6 && LWIP_IPV6_DHCP6 */ 51 | -------------------------------------------------------------------------------- /user/lwip/core/ipv6/inet6.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * 4 | * INET v6 addresses. 5 | */ 6 | 7 | /* 8 | * Copyright (c) 2010 Inico Technologies Ltd. 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 3. The name of the author may not be used to endorse or promote products 20 | * derived from this software without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 23 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 25 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 26 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 27 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 30 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 31 | * OF SUCH DAMAGE. 32 | * 33 | * This file is part of the lwIP TCP/IP stack. 34 | * 35 | * Author: Ivan Delamer 36 | * 37 | * 38 | * Please coordinate changes and requests with Ivan Delamer 39 | * 40 | */ 41 | 42 | #include "lwip/opt.h" 43 | 44 | #if LWIP_IPV6 && LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ 45 | 46 | #include "lwip/def.h" 47 | #include "lwip/inet.h" 48 | 49 | /** This variable is initialized by the system to contain the wildcard IPv6 address. 50 | */ 51 | const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; 52 | 53 | #endif /* LWIP_IPV6 */ 54 | -------------------------------------------------------------------------------- /user/lwip/include/lwip/apps/FILES: -------------------------------------------------------------------------------- 1 | This directory contains application headers. 2 | Every application shall provide one api file APP.h and optionally one options file APP_opts.h 3 | -------------------------------------------------------------------------------- /user/lwip/include/lwip/apps/netbiosns.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * NETBIOS name service responder 4 | */ 5 | 6 | /* 7 | * Redistribution and use in source and binary forms, with or without modification, 8 | * are permitted provided that the following conditions are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, 13 | * this list of conditions and the following disclaimer in the documentation 14 | * and/or other materials provided with the distribution. 15 | * 3. The name of the author may not be used to endorse or promote products 16 | * derived from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | * 29 | * This file is part of the lwIP TCP/IP stack. 30 | * 31 | */ 32 | #ifndef LWIP_HDR_APPS_NETBIOS_H 33 | #define LWIP_HDR_APPS_NETBIOS_H 34 | 35 | #include "lwip/apps/netbiosns_opts.h" 36 | 37 | void netbiosns_init(void); 38 | #ifndef NETBIOS_LWIP_NAME 39 | void netbiosns_set_name(const char* hostname); 40 | #endif 41 | void netbiosns_stop(void); 42 | 43 | #endif /* LWIP_HDR_APPS_NETBIOS_H */ 44 | -------------------------------------------------------------------------------- /user/lwip/include/lwip/apps/netbiosns_opts.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * NETBIOS name service responder options 4 | */ 5 | 6 | /* 7 | * Redistribution and use in source and binary forms, with or without modification, 8 | * are permitted provided that the following conditions are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, 13 | * this list of conditions and the following disclaimer in the documentation 14 | * and/or other materials provided with the distribution. 15 | * 3. The name of the author may not be used to endorse or promote products 16 | * derived from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | * 29 | * This file is part of the lwIP TCP/IP stack. 30 | * 31 | */ 32 | #ifndef LWIP_HDR_APPS_NETBIOS_OPTS_H 33 | #define LWIP_HDR_APPS_NETBIOS_OPTS_H 34 | 35 | #include "lwip/opt.h" 36 | 37 | /** 38 | * @defgroup netbiosns_opts Options 39 | * @ingroup netbiosns 40 | * @{ 41 | */ 42 | 43 | /** NetBIOS name of lwip device 44 | * This must be uppercase until NETBIOS_STRCMP() is defined to a string 45 | * comparision function that is case insensitive. 46 | * If you want to use the netif's hostname, use this (with LWIP_NETIF_HOSTNAME): 47 | * (ip_current_netif() != NULL ? ip_current_netif()->hostname != NULL ? ip_current_netif()->hostname : "" : "") 48 | * 49 | * If this is not defined, netbiosns_set_name() can be called at runtime to change the name. 50 | */ 51 | #ifdef __DOXYGEN__ 52 | #define NETBIOS_LWIP_NAME "NETBIOSLWIPDEV" 53 | #endif 54 | 55 | /** 56 | * @} 57 | */ 58 | 59 | #endif /* LWIP_HDR_APPS_NETBIOS_OPTS_H */ 60 | -------------------------------------------------------------------------------- /user/lwip/include/lwip/dhcp6.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * 4 | * IPv6 address autoconfiguration as per RFC 4862. 5 | */ 6 | 7 | /* 8 | * Copyright (c) 2010 Inico Technologies Ltd. 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 3. The name of the author may not be used to endorse or promote products 20 | * derived from this software without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 23 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 25 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 26 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 27 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 30 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 31 | * OF SUCH DAMAGE. 32 | * 33 | * This file is part of the lwIP TCP/IP stack. 34 | * 35 | * Author: Ivan Delamer 36 | * 37 | * IPv6 address autoconfiguration as per RFC 4862. 38 | * 39 | * Please coordinate changes and requests with Ivan Delamer 40 | * 41 | */ 42 | 43 | #ifndef LWIP_HDR_IP6_DHCP6_H 44 | #define LWIP_HDR_IP6_DHCP6_H 45 | 46 | #include "lwip/opt.h" 47 | 48 | #if LWIP_IPV6_DHCP6 /* don't build if not configured for use in lwipopts.h */ 49 | 50 | 51 | struct dhcp6 52 | { 53 | /*@todo: implement DHCP6*/ 54 | }; 55 | 56 | #endif /* LWIP_IPV6_DHCP6 */ 57 | 58 | #endif /* LWIP_HDR_IP6_DHCP6_H */ 59 | -------------------------------------------------------------------------------- /user/lwip/include/lwip/ethip6.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * 4 | * Ethernet output for IPv6. Uses ND tables for link-layer addressing. 5 | */ 6 | 7 | /* 8 | * Copyright (c) 2010 Inico Technologies Ltd. 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 3. The name of the author may not be used to endorse or promote products 20 | * derived from this software without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 23 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 25 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 26 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 27 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 30 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 31 | * OF SUCH DAMAGE. 32 | * 33 | * This file is part of the lwIP TCP/IP stack. 34 | * 35 | * Author: Ivan Delamer 36 | * 37 | * 38 | * Please coordinate changes and requests with Ivan Delamer 39 | * 40 | */ 41 | 42 | #ifndef LWIP_HDR_ETHIP6_H 43 | #define LWIP_HDR_ETHIP6_H 44 | 45 | #include "lwip/opt.h" 46 | 47 | #if LWIP_IPV6 && LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */ 48 | 49 | #include "lwip/pbuf.h" 50 | #include "lwip/ip6.h" 51 | #include "lwip/ip6_addr.h" 52 | #include "lwip/netif.h" 53 | 54 | 55 | #ifdef __cplusplus 56 | extern "C" { 57 | #endif 58 | 59 | 60 | err_t ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | 66 | #endif /* LWIP_IPV6 && LWIP_ETHERNET */ 67 | 68 | #endif /* LWIP_HDR_ETHIP6_H */ 69 | -------------------------------------------------------------------------------- /user/lwip/include/lwip/prot/ip.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * IP protocol definitions 4 | */ 5 | 6 | /* 7 | * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 8 | * All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without modification, 11 | * are permitted provided that the following conditions are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 3. The name of the author may not be used to endorse or promote products 19 | * derived from this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 22 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 24 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 26 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 29 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 30 | * OF SUCH DAMAGE. 31 | * 32 | * This file is part of the lwIP TCP/IP stack. 33 | * 34 | * Author: Adam Dunkels 35 | * 36 | */ 37 | #ifndef LWIP_HDR_PROT_IP_H 38 | #define LWIP_HDR_PROT_IP_H 39 | 40 | #include "lwip/arch.h" 41 | 42 | #define IP_PROTO_ICMP 1 43 | #define IP_PROTO_IGMP 2 44 | #define IP_PROTO_UDP 17 45 | #define IP_PROTO_UDPLITE 136 46 | #define IP_PROTO_TCP 6 47 | 48 | /** This operates on a void* by loading the first byte */ 49 | #define IP_HDR_GET_VERSION(ptr) ((*(u8_t*)(ptr)) >> 4) 50 | 51 | #endif /* LWIP_HDR_PROT_IP_H */ 52 | -------------------------------------------------------------------------------- /user/lwip/include/netif/etharp.h: -------------------------------------------------------------------------------- 1 | /* ARP has been moved to core/ipv4, provide this #include for compatibility only */ 2 | #include "lwip/etharp.h" 3 | #include "netif/ethernet.h" 4 | -------------------------------------------------------------------------------- /user/lwip/include/netif/ppp/chap-md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | * chap-md5.h - New CHAP/MD5 implementation. 3 | * 4 | * Copyright (c) 2003 Paul Mackerras. All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * 2. The name(s) of the authors of this software must not be used to 14 | * endorse or promote products derived from this software without 15 | * prior written permission. 16 | * 17 | * 3. Redistributions of any form whatsoever must retain the following 18 | * acknowledgment: 19 | * "This product includes software developed by Paul Mackerras 20 | * ". 21 | * 22 | * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO 23 | * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 24 | * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 25 | * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 26 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 27 | * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 28 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 29 | */ 30 | 31 | #include "netif/ppp/ppp_opts.h" 32 | #if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ 33 | 34 | extern const struct chap_digest_type md5_digest; 35 | 36 | #endif /* PPP_SUPPORT && CHAP_SUPPORT */ 37 | -------------------------------------------------------------------------------- /user/lwip/include/netif/ppp/chap_ms.h: -------------------------------------------------------------------------------- 1 | /* 2 | * chap_ms.h - Challenge Handshake Authentication Protocol definitions. 3 | * 4 | * Copyright (c) 1995 Eric Rosenquist. All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in 15 | * the documentation and/or other materials provided with the 16 | * distribution. 17 | * 18 | * 3. The name(s) of the authors of this software must not be used to 19 | * endorse or promote products derived from this software without 20 | * prior written permission. 21 | * 22 | * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO 23 | * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 24 | * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 25 | * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 26 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 27 | * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 28 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 29 | * 30 | * $Id: chap_ms.h,v 1.13 2004/11/15 22:13:26 paulus Exp $ 31 | */ 32 | 33 | #include "netif/ppp/ppp_opts.h" 34 | #if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ 35 | 36 | #ifndef CHAPMS_INCLUDE 37 | #define CHAPMS_INCLUDE 38 | 39 | extern const struct chap_digest_type chapms_digest; 40 | extern const struct chap_digest_type chapms2_digest; 41 | 42 | #endif /* CHAPMS_INCLUDE */ 43 | 44 | #endif /* PPP_SUPPORT && MSCHAP_SUPPORT */ 45 | -------------------------------------------------------------------------------- /user/lwip/include/netif/ppp/ecp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ecp.h - Definitions for PPP Encryption Control Protocol. 3 | * 4 | * Copyright (c) 2002 Google, Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in 16 | * the documentation and/or other materials provided with the 17 | * distribution. 18 | * 19 | * 3. The name(s) of the authors of this software must not be used to 20 | * endorse or promote products derived from this software without 21 | * prior written permission. 22 | * 23 | * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO 24 | * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 25 | * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 26 | * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 27 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 28 | * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 29 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 30 | * 31 | * $Id: ecp.h,v 1.2 2003/01/10 07:12:36 fcusack Exp $ 32 | */ 33 | 34 | #include "netif/ppp/ppp_opts.h" 35 | #if PPP_SUPPORT && ECP_SUPPORT /* don't build if not configured for use in lwipopts.h */ 36 | 37 | typedef struct ecp_options { 38 | bool required; /* Is ECP required? */ 39 | unsigned enctype; /* Encryption type */ 40 | } ecp_options; 41 | 42 | extern fsm ecp_fsm[]; 43 | extern ecp_options ecp_wantoptions[]; 44 | extern ecp_options ecp_gotoptions[]; 45 | extern ecp_options ecp_allowoptions[]; 46 | extern ecp_options ecp_hisoptions[]; 47 | 48 | extern const struct protent ecp_protent; 49 | 50 | #endif /* PPP_SUPPORT && ECP_SUPPORT */ 51 | -------------------------------------------------------------------------------- /user/lwip/include/posix/errno.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * This file is a posix wrapper for lwip/errno.h. 4 | */ 5 | 6 | /* 7 | * Redistribution and use in source and binary forms, with or without modification, 8 | * are permitted provided that the following conditions are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, 13 | * this list of conditions and the following disclaimer in the documentation 14 | * and/or other materials provided with the distribution. 15 | * 3. The name of the author may not be used to endorse or promote products 16 | * derived from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | * 29 | * This file is part of the lwIP TCP/IP stack. 30 | * 31 | */ 32 | 33 | #include "lwip/errno.h" 34 | -------------------------------------------------------------------------------- /user/lwip/include/posix/netdb.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * This file is a posix wrapper for lwip/netdb.h. 4 | */ 5 | 6 | /* 7 | * Redistribution and use in source and binary forms, with or without modification, 8 | * are permitted provided that the following conditions are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, 13 | * this list of conditions and the following disclaimer in the documentation 14 | * and/or other materials provided with the distribution. 15 | * 3. The name of the author may not be used to endorse or promote products 16 | * derived from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | * 29 | * This file is part of the lwIP TCP/IP stack. 30 | * 31 | */ 32 | 33 | #include "lwip/netdb.h" 34 | -------------------------------------------------------------------------------- /user/lwip/include/posix/sys/socket.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * This file is a posix wrapper for lwip/sockets.h. 4 | */ 5 | 6 | /* 7 | * Redistribution and use in source and binary forms, with or without modification, 8 | * are permitted provided that the following conditions are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, 13 | * this list of conditions and the following disclaimer in the documentation 14 | * and/or other materials provided with the distribution. 15 | * 3. The name of the author may not be used to endorse or promote products 16 | * derived from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 21 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 23 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 | * OF SUCH DAMAGE. 28 | * 29 | * This file is part of the lwIP TCP/IP stack. 30 | * 31 | */ 32 | 33 | #include "lwip/sockets.h" 34 | -------------------------------------------------------------------------------- /user/lwip/netif/FILES: -------------------------------------------------------------------------------- 1 | This directory contains generic network interface device drivers that 2 | do not contain any hardware or architecture specific code. The files 3 | are: 4 | 5 | ethernet.c 6 | Shared code for Ethernet based interfaces. 7 | 8 | ethernetif.c 9 | An example of how an Ethernet device driver could look. This 10 | file can be used as a "skeleton" for developing new Ethernet 11 | network device drivers. It uses the etharp.c ARP code. 12 | 13 | lowpan6.c 14 | A 6LoWPAN implementation as a netif. 15 | 16 | slipif.c 17 | A generic implementation of the SLIP (Serial Line IP) 18 | protocol. It requires a sio (serial I/O) module to work. 19 | 20 | ppp/ Point-to-Point Protocol stack 21 | The lwIP PPP support is based from pppd (http://ppp.samba.org) with 22 | huge changes to match code size and memory requirements for embedded 23 | devices. Please read /doc/ppp.txt and ppp/PPPD_FOLLOWUP for a detailed 24 | explanation. 25 | -------------------------------------------------------------------------------- /user/lwip/netif/ppp/eui64.c: -------------------------------------------------------------------------------- 1 | /* 2 | * eui64.c - EUI64 routines for IPv6CP. 3 | * 4 | * Copyright (c) 1999 Tommi Komulainen. All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in 15 | * the documentation and/or other materials provided with the 16 | * distribution. 17 | * 18 | * 3. The name(s) of the authors of this software must not be used to 19 | * endorse or promote products derived from this software without 20 | * prior written permission. 21 | * 22 | * 4. Redistributions of any form whatsoever must retain the following 23 | * acknowledgment: 24 | * "This product includes software developed by Tommi Komulainen 25 | * ". 26 | * 27 | * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO 28 | * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 29 | * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 30 | * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 31 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 32 | * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 33 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 34 | * 35 | * $Id: eui64.c,v 1.6 2002/12/04 23:03:32 paulus Exp $ 36 | */ 37 | 38 | #include "netif/ppp/ppp_opts.h" 39 | #if PPP_SUPPORT && PPP_IPV6_SUPPORT /* don't build if not configured for use in lwipopts.h */ 40 | 41 | #include "netif/ppp/ppp_impl.h" 42 | #include "netif/ppp/eui64.h" 43 | 44 | /* 45 | * eui64_ntoa - Make an ascii representation of an interface identifier 46 | */ 47 | char *eui64_ntoa(eui64_t e) { 48 | static char buf[20]; 49 | 50 | sprintf(buf, "%02x%02x:%02x%02x:%02x%02x:%02x%02x", 51 | e.e8[0], e.e8[1], e.e8[2], e.e8[3], 52 | e.e8[4], e.e8[5], e.e8[6], e.e8[7]); 53 | return buf; 54 | } 55 | 56 | #endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ 57 | -------------------------------------------------------------------------------- /user/lwip/netif/ppp/polarssl/README: -------------------------------------------------------------------------------- 1 | About PolarSSL files into lwIP PPP support 2 | ------------------------------------------ 3 | 4 | This folder contains some files fetched from the latest BSD release of 5 | the PolarSSL project (PolarSSL 0.10.1-bsd) for ciphers and encryption 6 | methods we need for lwIP PPP support. 7 | 8 | The PolarSSL files were cleaned to contain only the necessary struct 9 | fields and functions needed for lwIP. 10 | 11 | The PolarSSL API was not changed at all, so if you are already using 12 | PolarSSL you can choose to skip the compilation of the included PolarSSL 13 | library into lwIP. 14 | 15 | If you are not using the embedded copy you must include external 16 | libraries into your arch/cc.h port file. 17 | 18 | Beware of the stack requirements which can be a lot larger if you are not 19 | using our cleaned PolarSSL library. 20 | 21 | 22 | PolarSSL project website: http://polarssl.org/ 23 | -------------------------------------------------------------------------------- /user/trap.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define GDT_ENTRY_CS 1 7 | #define GDT_ENTRY_DS 2 8 | #define GDT_ENTRY_TSS 3 9 | #define GDT_CS (GDT_ENTRY_CS << 3) 10 | #define GDT_DS (GDT_ENTRY_DS << 3) 11 | #define GDT_TSS (GDT_ENTRY_TSS << 3) 12 | 13 | static struct tss tss = { 14 | .rsp0 = 0, /* no stack switch */ 15 | }; 16 | 17 | static uint64_t gdt[] = { 18 | 0, KERNEL_CS_DESC, KERNEL_DS_DESC, 0, 0, /* TSS */ 19 | }; 20 | 21 | static struct pseudo_desc gdt_desc = { 22 | sizeof(gdt) - 1, (uint64_t)gdt, 23 | }; 24 | 25 | static struct gate_desc idt[256] = {{0}}; 26 | 27 | static struct pseudo_desc idt_desc = { 28 | sizeof(idt) - 1, (uint64_t)idt, 29 | }; 30 | 31 | void trap_init(void) 32 | { 33 | uint64_t tss_addr = (uint64_t)&tss; 34 | size_t i; 35 | extern void *trap_vectors[]; 36 | 37 | gdt[GDT_ENTRY_TSS] = 38 | SEG_TSSA | SEG_P | SEG_A | SEG_BASELO(tss_addr) | SEG_LIMIT(sizeof(tss) - 1); 39 | gdt[GDT_ENTRY_TSS + 1] = SEG_BASEHI(tss_addr); 40 | 41 | for (i = 0; i < countof(idt); ++i) 42 | set_gate_desc(&idt[i], 0, GDT_CS, trap_vectors[i], KERNEL_PL); 43 | lgdt(&gdt_desc); 44 | 45 | asm volatile("mov $16, %%ax\n" 46 | "mov %%ax, %%ds\n" 47 | "mov %%ax, %%es\n" 48 | "mov %%ax, %%ss\n" 49 | "mov $8, %%rax\n" 50 | "pushq %%rax\n" 51 | "pushq $1f\n" 52 | "lretq\n" 53 | "1:\n" 54 | "nop" 55 | : 56 | : 57 | : "rax"); 58 | 59 | ltr(GDT_TSS); 60 | lidt(&idt_desc); 61 | } 62 | --------------------------------------------------------------------------------