diff -Nur sys.orig/conf/files sys.lilyvm/conf/files --- sys.orig/conf/files Fri Jan 14 12:07:39 2005 +++ sys.lilyvm/conf/files Sun May 22 12:34:24 2005 @@ -1593,3 +1593,4 @@ dev/drm/radeon_state.c optional radeondrm dev/drm/tdfx_drv.c optional tdfxdrm +net/if_vmn.c optional vmn diff -Nur sys.orig/dev/md/md.c sys.lilyvm/dev/md/md.c --- sys.orig/dev/md/md.c Tue Aug 20 02:43:34 2002 +++ sys.lilyvm/dev/md/md.c Sun May 22 12:34:24 2005 @@ -53,6 +53,7 @@ static int mdrootready; static void mdcreate_malloc(void); +static void mdstrategy_vmdisk(struct buf *bp); #define CDEV_MAJOR 95 #define BDEV_MAJOR 22 @@ -76,7 +77,7 @@ /* maj */ CDEV_MAJOR, /* dump */ nodump, /* psize */ nopsize, - /* flags */ D_DISK | D_CANFREE | D_MEMDISK, + /* flags */ D_DISK | D_CANFREE, /* bmaj */ BDEV_MAJOR }; @@ -89,7 +90,7 @@ struct disk disk; dev_t dev; int busy; - enum {MD_MALLOC, MD_PRELOAD} type; + enum {MD_MALLOC, MD_PRELOAD, MD_VMDISK} type; unsigned nsect; /* MD_MALLOC related fields */ @@ -103,6 +104,14 @@ static int mdunits; +#define lilyvm_call_int (*(int(**)(int,...))0xbfafefac) +#define lilyvm_call_longlong (*(long long(**)(int,...))0xbfafef9c) +#define lilyvm_call lilyvm_call_int +#define LILYVM_CALL_VMDISK_NUM_DISKS 3 +#define LILYVM_CALL_VMDISK_GETSIZE 4 +#define LILYVM_CALL_VMDISK_PREAD 5 +#define LILYVM_CALL_VMDISK_PWRITE 6 + static int mdopen(dev_t dev, int flag, int fmt, struct proc *p) { @@ -152,6 +161,8 @@ sc = bp->b_dev->si_drv1; if (sc->type == MD_MALLOC) { mdstrategy_malloc(bp); + } else if (sc->type == MD_VMDISK) { + mdstrategy_vmdisk(bp); } else { mdstrategy_preload(bp); } @@ -339,6 +350,62 @@ return; } +static void +mdstrategy_vmdisk(struct buf *bp) +{ + int s; + struct md_s *sc; + devstat_trans_flags dop; + u_int64_t offset; + + if (md_debug > 1) + printf("mdstrategy_vmdisk(%p) %s %lx, %d, %ld, %p)\n", + bp, devtoname(bp->b_dev), bp->b_flags, bp->b_blkno, + bp->b_bcount / DEV_BSIZE, bp->b_data); + + sc = bp->b_dev->si_drv1; + + s = splbio(); + + bufqdisksort(&sc->buf_queue, bp); + + if (sc->busy) { + splx(s); + return; + } + + sc->busy++; + + while (1) { + bp = bufq_first(&sc->buf_queue); + if (bp) + bufq_remove(&sc->buf_queue, bp); + splx(s); + if (!bp) + break; + + devstat_start_transaction(&sc->stats); + + if (bp->b_flags & B_FREEBUF) { + dop = DEVSTAT_NO_DATA; + } else if (bp->b_flags & B_READ) { + dop = DEVSTAT_READ; + offset = (u_int64_t) bp->b_pblkno << DEV_BSHIFT; + lilyvm_call (LILYVM_CALL_VMDISK_PREAD, sc->unit, bp->b_data, bp->b_bcount, offset); + } else { + dop = DEVSTAT_WRITE; + offset = (u_int64_t) bp->b_pblkno << DEV_BSHIFT; + lilyvm_call (LILYVM_CALL_VMDISK_PWRITE, sc->unit, bp->b_data, bp->b_bcount, offset); + } + bp->b_resid = 0; + devstat_end_transaction_buf(&sc->stats, bp); + biodone(bp); + s = splbio(); + } + sc->busy = 0; + return; +} + static struct md_s * mdcreate(void) { @@ -358,6 +425,19 @@ } static void +mdcreate_vmdisk(void) +{ + struct md_s *sc; + + sc = mdcreate(); + sc->type = MD_VMDISK; + sc->nsect = lilyvm_call_longlong (LILYVM_CALL_VMDISK_GETSIZE, sc->unit) / DEV_BSIZE; + + if (sc->unit == 0) + mdrootready = 1; +} + +static void mdcreate_preload(u_char *image, unsigned length) { struct md_s *sc; @@ -395,7 +475,11 @@ caddr_t c; u_char *ptr, *name, *type; unsigned len; + int i; + for (i = lilyvm_call (LILYVM_CALL_VMDISK_NUM_DISKS); i; i--) { + mdcreate_vmdisk (); + } #ifdef MD_ROOT_SIZE mdcreate_preload(mfs_root, MD_ROOT_SIZE*1024); #endif diff -Nur sys.orig/i386/conf/a sys.lilyvm/i386/conf/a --- sys.orig/i386/conf/a Thu Jan 1 09:00:00 1970 +++ sys.lilyvm/i386/conf/a Sun May 22 12:34:24 2005 @@ -0,0 +1,272 @@ +## +## GENERIC -- Generic kernel configuration file for FreeBSD/i386 +## +## For more information on this file, please read the handbook section on +## Kernel Configuration Files: +## +## http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +## +## The handbook is also available locally in /usr/share/doc/handbook +## if you've installed the doc distribution, otherwise always see the +## FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +## latest information. +## +## An exhaustive list of options and more detailed explanations of the +## device lines is also present in the ./LINT configuration file. If you are +## in doubt as to the purpose or necessity of a line, check first in LINT. +## +## $FreeBSD: src/sys/i386/conf/GENERIC,v 1.246.2.59 2004/04/07 20:29:01 vkashyap Exp $ +# +machine i386 +cpu I386_CPU +cpu I486_CPU +cpu I586_CPU +cpu I686_CPU +ident a +maxusers 0 +# +##makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols +# +options MATH_EMULATE #Support for x87 emulation +options INET #InterNETworking +options INET6 #IPv6 communications protocols +options FFS #Berkeley Fast Filesystem +options FFS_ROOT #FFS usable as root device [keep this!] +options SOFTUPDATES #Enable FFS soft updates support +options UFS_DIRHASH #Improve performance on big directories +options MFS #Memory Filesystem +options MD_ROOT #MD is a potential root device +options NFS #Network Filesystem +options NFS_ROOT #NFS usable as root device, NFS required +options MSDOSFS #MSDOS Filesystem +options CD9660 #ISO 9660 Filesystem +options CD9660_ROOT #CD-ROM usable as root, CD9660 required +options PROCFS #Process filesystem +options COMPAT_43 #Compatible with BSD 4.3 [KEEP THIS!] +options SCSI_DELAY=15000 #Delay (in ms) before probing SCSI +options UCONSOLE #Allow users to grab the console +options USERCONFIG #boot -c editor +options VISUAL_USERCONFIG #visual boot -c editor +options KTRACE #ktrace(1) support +options SYSVSHM #SYSV-style shared memory +options SYSVMSG #SYSV-style message queues +options SYSVSEM #SYSV-style semaphores +options P1003_1B #Posix P1003_1B real-time extensions +options _KPOSIX_PRIORITY_SCHEDULING +options ICMP_BANDLIM #Rate limit bad replies +options KBD_INSTALL_CDEV # install a CDEV entry in /dev +options AHC_REG_PRETTY_PRINT # Print register bitfields in debug + # output. Adds ~128k to driver. +options AHD_REG_PRETTY_PRINT # Print register bitfields in debug + # output. Adds ~215k to driver. +# +## To make an SMP kernel, the next two are needed +##options SMP # Symmetric MultiProcessor Kernel +##options APIC_IO # Symmetric (APIC) I/O +# +device isa +#device eisa +#device pci +# +## Floppy drives +#device fdc0 at isa? port IO_FD1 irq 6 drq 2 +#device fd0 at fdc0 drive 0 +#device fd1 at fdc0 drive 1 +## +## If you have a Toshiba Libretto with its Y-E Data PCMCIA floppy, +## don't use the above line for fdc0 but the following one: +##device fdc0 +# +## ATA and ATAPI devices +#device ata0 at isa? port IO_WD1 irq 14 +#device ata1 at isa? port IO_WD2 irq 15 +#device ata +#device atadisk # ATA disk drives +#device atapicd # ATAPI CDROM drives +#device atapifd # ATAPI floppy drives +#device atapist # ATAPI tape drives +#options ATA_STATIC_ID #Static device numbering +# +## SCSI Controllers +#device ahb # EISA AHA1742 family +#device ahc # AHA2940 and onboard AIC7xxx devices +#device ahd # AHA39320/29320 and onboard AIC79xx devices +#device amd # AMD 53C974 (Tekram DC-390(T)) +#device isp # Qlogic family +#device mpt # LSI-Logic MPT/Fusion +#device ncr # NCR/Symbios Logic +#device sym # NCR/Symbios Logic (newer chipsets) +#options SYM_SETUP_LP_PROBE_MAP=0x40 +# # Allow ncr to attach legacy NCR devices when +# # both sym and ncr are configured +# +#device adv0 at isa? +#device adw +#device bt0 at isa? +#device aha0 at isa? +#device aic0 at isa? +# +#device ncv # NCR 53C500 +#device nsp # Workbit Ninja SCSI-3 +#device stg # TMC 18C30/18C50 +# +## SCSI peripherals +#device scbus # SCSI bus (required) +#device da # Direct Access (disks) +#device sa # Sequential Access (tape etc) +#device cd # CD +#device pass # Passthrough device (direct SCSI access) +# +## RAID controllers interfaced to the SCSI subsystem +#device asr # DPT SmartRAID V, VI and Adaptec SCSI RAID +#device dpt # DPT Smartcache - See LINT for options! +#device iir # Intel Integrated RAID +#device mly # Mylex AcceleRAID/eXtremeRAID +#device ciss # Compaq SmartRAID 5* series +#device twa # 3ware 9000 series PATA/SATA RAID +# +## RAID controllers +#device aac # Adaptec FSA RAID, Dell PERC2/PERC3 +##device aacp # SCSI passthrough for aac (requires CAM) +#device ida # Compaq Smart RAID +#device amr # AMI MegaRAID +#device mlx # Mylex DAC960 family +#device pst # Promise Supertrak SX6000 +#device twe # 3ware Escalade +# +## atkbdc0 controls both the keyboard and the PS/2 mouse +#device atkbdc0 at isa? port IO_KBD +#device atkbd0 at atkbdc? irq 1 flags 0x1 +#device psm0 at atkbdc? irq 12 +# +#device vga0 at isa? +# +## splash screen/screen saver +#pseudo-device splash +# +## syscons is the default console driver, resembling an SCO console +#device sc0 at isa? flags 0x100 +# +## Enable this and PCVT_FREEBSD for pcvt vt220 compatible console driver +##device vt0 at isa? +##options XSERVER # support for X server on a vt console +##options FAT_CURSOR # start with block cursor +## If you have a ThinkPAD, uncomment this along with the rest of the PCVT lines +##options PCVT_SCANSET=2 # IBM keyboards are non-std +# +#device agp # support several AGP chipsets +# +## Floating point support - do not disable. +device npx0 at nexus? port IO_NPX irq 13 +# +## Power management support (see LINT for more options) +#device apm0 at nexus? disable flags 0x20 # Advanced Power Management +# +## PCCARD (PCMCIA) support +#device card +#device pcic0 at isa? irq 0 port 0x3e0 iomem 0xd0000 +#device pcic1 at isa? irq 0 port 0x3e2 iomem 0xd4000 disable +# +## Serial (COM) ports +device sio0 at isa? port IO_COM1 flags 0x40030 irq 4 +device sio1 at isa? port IO_COM2 flags 0x40000 irq 3 +device sio2 at isa? disable port IO_COM3 flags 0x40000 irq 5 +device sio3 at isa? disable port IO_COM4 flags 0x40000 irq 9 +# +## Parallel port +#device ppc0 at isa? irq 7 +#device ppbus # Parallel port bus (required) +#device lpt # Printer +#device plip # TCP/IP over parallel +#device ppi # Parallel port interface device +##device vpo # Requires scbus and da +# +# +## PCI Ethernet NICs. +#device de # DEC/Intel DC21x4x (``Tulip'') +#device em # Intel PRO/1000 adapter Gigabit Ethernet Card (``Wiseman'') +#device txp # 3Com 3cR990 (``Typhoon'') +#device vx # 3Com 3c590, 3c595 (``Vortex'') +# +## PCI Ethernet NICs that use the common MII bus controller code. +## NOTE: Be sure to keep the 'device miibus' line in order to use these NICs! +#device miibus # MII bus support +#device dc # DEC/Intel 21143 and various workalikes +#device fxp # Intel EtherExpress PRO/100B (82557, 82558) +#device pcn # AMD Am79C97x PCI 10/100 NICs +#device rl # RealTek 8129/8139 +#device sf # Adaptec AIC-6915 (``Starfire'') +#device sis # Silicon Integrated Systems SiS 900/SiS 7016 +#device ste # Sundance ST201 (D-Link DFE-550TX) +#device tl # Texas Instruments ThunderLAN +#device tx # SMC EtherPower II (83c170 ``EPIC'') +#device vr # VIA Rhine, Rhine II +#device wb # Winbond W89C840F +#device xl # 3Com 3c90x (``Boomerang'', ``Cyclone'') +#device bge # Broadcom BCM570x (``Tigon III'') +# +## ISA Ethernet NICs. +## 'device ed' requires 'device miibus' +#device ed0 at isa? disable port 0x280 irq 10 iomem 0xd8000 +#device ex +#device ep +#device fe0 at isa? disable port 0x300 +## Xircom Ethernet +#device xe +## PRISM I IEEE 802.11b wireless NIC. +#device awi +## WaveLAN/IEEE 802.11 wireless NICs. Note: the WaveLAN/IEEE really +## exists only as a PCMCIA device, so there is no ISA attachment needed +## and resources will always be dynamically assigned by the pccard code. +#device wi +## Aironet 4500/4800 802.11 wireless NICs. Note: the declaration below will +## work for PCMCIA and PCI cards, as well as ISA cards set to ISA PnP +## mode (the factory default). If you set the switches on your ISA +## card for a manually chosen I/O address and IRQ, you must specify +## those parameters here. +#device an +## The probe order of these is presently determined by i386/isa/isa_compat.c. +#device ie0 at isa? disable port 0x300 irq 10 iomem 0xd0000 +##device le0 at isa? disable port 0x300 irq 5 iomem 0xd0000 +#device lnc0 at isa? disable port 0x280 irq 10 drq 0 +#device cs0 at isa? disable port 0x300 +#device sn0 at isa? disable port 0x300 irq 10 +# +## Pseudo devices - the number indicates how many units to allocate. +pseudo-device loop # Network loopback +pseudo-device ether # Ethernet support +#pseudo-device sl 1 # Kernel SLIP +#pseudo-device ppp 1 # Kernel PPP +#pseudo-device tun # Packet tunnel. +pseudo-device pty # Pseudo-ttys (telnet etc) +pseudo-device md # Memory "disks" +#pseudo-device gif # IPv6 and IPv4 tunneling +#pseudo-device faith 1 # IPv6-to-IPv4 relaying (translation) +# +## The `bpf' pseudo-device enables the Berkeley Packet Filter. +## Be aware of the administrative consequences of enabling this! +#pseudo-device bpf #Berkeley packet filter +# +## USB support +#device uhci # UHCI PCI->USB interface +#device ohci # OHCI PCI->USB interface +#device usb # USB Bus (required) +#device ugen # Generic +#device uhid # "Human Interface Devices" +#device ukbd # Keyboard +#device ulpt # Printer +#device umass # Disks/Mass storage - Requires scbus and da +#device ums # Mouse +#device uscanner # Scanners +#device urio # Diamond Rio MP3 Player +## USB Ethernet, requires mii +#device aue # ADMtek USB ethernet +#device cue # CATC USB ethernet +#device kue # Kawasaki LSI USB ethernet +# +## FireWire support +#device firewire # FireWire bus code +#device sbp # SCSI over FireWire (Requires scbus and da) +#device fwe # Ethernet over FireWire (non-standard!) +options MAXMEM="(64*1024)" +pseudo-device vmn diff -Nur sys.orig/i386/i386/locore.s sys.lilyvm/i386/i386/locore.s --- sys.orig/i386/i386/locore.s Fri Oct 17 15:54:00 2003 +++ sys.lilyvm/i386/i386/locore.s Sun May 22 12:34:34 2005 @@ -393,7 +393,7 @@ 9: movl $SYS_sigreturn,%eax pushl %eax /* junk to fake return addr. */ - int $0x80 /* enter kernel with args */ + .byte 0xcd,0x80 # int $0x80 /* enter kernel with args */ 0: jmp 0b ALIGN_TEXT @@ -408,7 +408,7 @@ movl $0x01d516,SC_TRAPNO(%eax) /* magic: 0ldSiG */ movl $SYS_sigreturn,%eax pushl %eax /* junk to fake return addr. */ - int $0x80 /* enter kernel with args */ + .byte 0xcd,0x80 # int $0x80 /* enter kernel with args */ 0: jmp 0b ALIGN_TEXT diff -Nur sys.orig/i386/i386/machdep.c sys.lilyvm/i386/i386/machdep.c --- sys.orig/i386/i386/machdep.c Thu Oct 23 05:15:10 2003 +++ sys.lilyvm/i386/i386/machdep.c Sun May 22 12:34:24 2005 @@ -1460,8 +1460,12 @@ /* * Perform "base memory" related probes & setup */ +#if 0 vm86_intcall(0x12, &vmf); basemem = vmf.vmf_ax; +#else + basemem = 640; +#endif if (basemem > 640) { printf("Preposterous BIOS basemem of %uK, truncating to 640K\n", basemem); @@ -1516,6 +1520,7 @@ #define SMAPSIZ sizeof(*smap) #define SMAP_SIG 0x534D4150 /* 'SMAP' */ +goto skipint15; vmc.npages = 0; smap = (void *)vm86_addpage(&vmc, 1, KERNBASE + (1 << PAGE_SHIFT)); vm86_getptr(&vmc, (vm_offset_t)smap, &vmf.vmf_es, &vmf.vmf_di); @@ -1619,6 +1624,7 @@ vm86_intcall(0x15, &vmf); extmem = vmf.vmf_ax; #else +skipint15:; /* * Prefer the RTC value for extended memory. */ diff -Nur sys.orig/i386/include/pmap.h sys.lilyvm/i386/include/pmap.h --- sys.orig/i386/include/pmap.h Sun Aug 10 01:21:19 2003 +++ sys.lilyvm/i386/include/pmap.h Sun May 22 12:34:24 2005 @@ -88,7 +88,7 @@ * This **MUST** be a multiple of 4 (eg: 252, 256, 260, etc). */ #ifndef KVA_PAGES -#define KVA_PAGES (1 << (30 - PDRSHIFT)) +#define KVA_PAGES 128 /*(1 << (30 - PDRSHIFT))*/ #endif /* @@ -123,7 +123,7 @@ #define MPPTDI (NPDEPTD-1) /* per cpu ptd entry */ #define KPTDI (MPPTDI-NKPDE) /* start of kernel virtual pde's */ #else -#define KPTDI (NPDEPTD-NKPDE) /* start of kernel virtual pde's */ +#define KPTDI (NPDEPTD-NKPDE-256) /* start of kernel virtual pde's */ #endif /* SMP */ #define PTDPTDI (KPTDI-NPGPTD) /* ptd entry that points to ptd! */ diff -Nur sys.orig/i386/linux/linux_locore.s sys.lilyvm/i386/linux/linux_locore.s --- sys.orig/i386/linux/linux_locore.s Tue Nov 6 04:08:23 2001 +++ sys.lilyvm/i386/linux/linux_locore.s Sun May 22 12:34:34 2005 @@ -12,7 +12,7 @@ movl %esp, %ebx /* pass sigframe */ push %eax /* fake ret addr */ movl $LINUX_SYS_linux_sigreturn,%eax /* linux_sigreturn() */ - int $0x80 /* enter kernel with args */ + .byte 0xcd,0x80 # int $0x80 /* enter kernel with args */ 0: jmp 0b ALIGN_TEXT /* XXXXX */ @@ -22,7 +22,7 @@ movl LINUX_SC_GS(%ebx),%gs push %eax /* fake ret addr */ movl $LINUX_SYS_linux_rt_sigreturn,%eax /* linux_rt_sigreturn() */ - int $0x80 /* enter kernel with args */ + .byte 0xcd,0x80 # int $0x80 /* enter kernel with args */ 0: jmp 0b ALIGN_TEXT /* XXXXX */ diff -Nur sys.orig/i386/svr4/svr4_locore.s sys.lilyvm/i386/svr4/svr4_locore.s --- sys.orig/i386/svr4/svr4_locore.s Fri Jul 7 09:38:51 2000 +++ sys.lilyvm/i386/svr4/svr4_locore.s Sun May 22 12:34:34 2005 @@ -18,7 +18,7 @@ 1: pushl %eax # pointer to ucontext pushl $1 # set context movl $_svr4_sys_context,%eax - int $0x80 # enter kernel with args on stack + .byte 0xcd,0x80 # int $0x80 # enter kernel with args on stack 0: jmp 0b ALIGN_TEXT diff -Nur sys.orig/net/if_vmn.c sys.lilyvm/net/if_vmn.c --- sys.orig/net/if_vmn.c Thu Jan 1 09:00:00 1970 +++ sys.lilyvm/net/if_vmn.c Sun May 22 12:34:24 2005 @@ -0,0 +1,390 @@ +/* Copyright (C) 2004 Hideki EIRAKU */ + +/* + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)if_loop.c 8.1 (Berkeley) 6/10/93 + * $FreeBSD: src/sys/net/if_loop.c,v 1.47.2.9 2004/02/08 08:40:24 silby Exp $ + */ + +/* + * Loopback interface driver for protocol testing and timing. + */ +#include "loop.h" + +#include "opt_atalk.h" +#include "opt_inet.h" +#include "opt_inet6.h" +#include "opt_ipx.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef INET +#include +#include +#endif + +#ifdef IPX +#include +#include +#endif + +#ifdef INET6 +#ifndef INET +#include +#endif +#include +#include +#endif + +#ifdef NS +#include +#include +#endif + +#ifdef NETATALK +#include +#include +#endif NETATALK + +#include +#include "../../i386/isa/intr_machdep.h" + +int vmnioctl __P((struct ifnet *, u_long, caddr_t)); +static void vmnrtrequest __P((int, struct rtentry *, struct rt_addrinfo *)); + +static void vmnattach __P((void *)); +PSEUDO_SET(vmnattach, if_vmn); + +int vmnoutput __P((struct ifnet *ifp, + struct mbuf *m, struct sockaddr *dst, struct rtentry *rt)); + +static void vmninputintr (void); +static void vmninput(void *dummy); + +#define lilyvm_call_int (*(int(**)(int,...))0xbfafefac) +#define lilyvm_call_longlong (*(long long(**)(int,...))0xbfafef9c) +#define lilyvm_call lilyvm_call_int +#define LILYVM_CALL_VMN_WRITE 1 +#define LILYVM_CALL_VMN_READ 2 +#define VMNMTU 1500 + +static struct ifnet vmnif[1]; +static u_int vmn_imask = HWI_MASK | SWI_MASK; +static struct callout input_callout; + +/* ARGSUSED */ +static void +vmnattach(dummy) + void *dummy; +{ + register struct ifnet *ifp; + register int i = 0; + + for (ifp = vmnif; i < 1; ifp++) { + ifp->if_name = "vmn"; + ifp->if_unit = i++; + ifp->if_mtu = VMNMTU; + ifp->if_flags = IFF_MULTICAST; + ifp->if_ioctl = vmnioctl; + ifp->if_output = vmnoutput; + ifp->if_type = IFT_OTHER; + ifp->if_snd.ifq_maxlen = ifqmaxlen; + if_attach(ifp); + bpfattach(ifp, DLT_NULL, sizeof(u_int)); + } + callout_init (&input_callout); +#if VMN_POLLING + callout_reset (&input_callout, 1, vmninput, NULL); +#else + inthand_add ("vmn", 1, (inthand2_t *)vmninputintr, NULL, &vmn_imask, INTR_EXCL); +#endif +} + +static void +vmninputintr (void) +{ + vmninput (NULL); +} + +int +vmnoutput(ifp, m, dst, rt) + struct ifnet *ifp; + register struct mbuf *m; + struct sockaddr *dst; + register struct rtentry *rt; +{ + + if ((m->m_flags & M_PKTHDR) == 0) + panic("vmnoutput no HDR"); + + if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) { + m_freem(m); + return (rt->rt_flags & RTF_BLACKHOLE ? 0 : + rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH); + } + + ifp->if_opackets++; + ifp->if_obytes += m->m_pkthdr.len; +#if 1 /* XXX */ + switch (dst->sa_family) { + case AF_INET: + case AF_INET6: + case AF_IPX: + case AF_NS: + case AF_APPLETALK: + break; + default: + printf("vmnoutput: af=%d unexpected\n", dst->sa_family); + m_freem(m); + return (EAFNOSUPPORT); + } +#endif + { + u_int8_t buf[VMNMTU]; + m_copydata (m, 0, m->m_pkthdr.len, buf); + lilyvm_call (LILYVM_CALL_VMN_WRITE, buf, m->m_pkthdr.len); + } + m_freem(m); + return 0; +} + +static void +vmninput(void *dummy) +{ + int s, isr; + register struct ifqueue *ifq = 0; + static struct mbuf *m = NULL; + static u_int len = 0; + struct ifnet *ifp = &vmnif[0]; + int af = AF_INET; + +loop: + if (m == NULL) { + len = 0; + MGETHDR (m, M_DONTWAIT, MT_DATA); + if (m) { + MCLGET (m, M_DONTWAIT); + if ((m->m_flags & M_EXT) == 0) { + m_freem (m); + m = NULL; + } + } + } + if (m) { + if (len == 0) { + len = lilyvm_call (LILYVM_CALL_VMN_READ, mtod (m, uint8_t *), MCLBYTES); + m->m_pkthdr.len = m->m_len = len; + } + } else { + callout_reset (&input_callout, 1, vmninput, NULL); + return; + } + if (len == 0) return; + + KASSERT((m->m_flags & M_PKTHDR) != 0, ("vmninput: no HDR")); + m->m_pkthdr.rcvif = ifp; + + /* BPF write needs to be handled specially */ + if (af == AF_UNSPEC) { + KASSERT(m->m_len >= sizeof(int), ("vmninput: m_len")); + af = *(mtod(m, int *)); + m->m_len -= sizeof(int); + m->m_pkthdr.len -= sizeof(int); + m->m_data += sizeof(int); + } + + /* Let BPF see incoming packet */ + if (ifp->if_bpf) { + struct mbuf m0, *n = m; + + if (ifp->if_bpf->bif_dlt == DLT_NULL) { + /* + * We need to prepend the address family as + * a four byte field. Cons up a dummy header + * to pacify bpf. This is safe because bpf + * will only read from the mbuf (i.e., it won't + * try to free it or keep a pointer a to it). + */ + m0.m_next = m; + m0.m_len = 4; + m0.m_data = (char *)⁡ + n = &m0; + } + bpf_mtap(ifp, n); + } + + /* Deliver to upper layer protocol */ + switch (af) { +#ifdef INET + case AF_INET: + ifq = &ipintrq; + isr = NETISR_IP; + break; +#endif +#ifdef INET6 + case AF_INET6: + m->m_flags |= M_LOOP; + ifq = &ip6intrq; + isr = NETISR_IPV6; + break; +#endif +#ifdef IPX + case AF_IPX: + ifq = &ipxintrq; + isr = NETISR_IPX; + break; +#endif +#ifdef NS + case AF_NS: + ifq = &nsintrq; + isr = NETISR_NS; + break; +#endif +#ifdef NETATALK + case AF_APPLETALK: + ifq = &atintrq2; + isr = NETISR_ATALK; + break; +#endif NETATALK + default: + printf("vmninput: can't handle af=%d\n", af); + m_freem(m); + return; /* (EAFNOSUPPORT); */ + } + s = splimp(); + if (IF_QFULL(ifq)) { + IF_DROP(ifq); + splx(s); + callout_reset (&input_callout, 1, vmninput, NULL); + return; + } + IF_ENQUEUE(ifq, m); + schednetisr(isr); + ifp->if_ipackets++; + ifp->if_ibytes += m->m_pkthdr.len; + splx(s); + m = NULL; + goto loop; +} + +/* ARGSUSED */ +static void +vmnrtrequest(cmd, rt, info) + int cmd; + struct rtentry *rt; + struct rt_addrinfo *info; +{ + if (rt) { + rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; /* for ISO */ + /* + * For optimal performance, the send and receive buffers + * should be at least twice the MTU plus a little more for + * overhead. + */ + rt->rt_rmx.rmx_recvpipe = + rt->rt_rmx.rmx_sendpipe = 3 * VMNMTU; + } +} + +/* + * Process an ioctl request. + */ +/* ARGSUSED */ +int +vmnioctl(ifp, cmd, data) + register struct ifnet *ifp; + u_long cmd; + caddr_t data; +{ + register struct ifaddr *ifa; + register struct ifreq *ifr = (struct ifreq *)data; + register int error = 0; + + switch (cmd) { + + case SIOCSIFADDR: + ifp->if_flags |= IFF_UP | IFF_RUNNING; + ifa = (struct ifaddr *)data; + ifa->ifa_rtrequest = vmnrtrequest; + /* + * Everything else is done at a higher level. + */ + break; + + case SIOCADDMULTI: + case SIOCDELMULTI: + if (ifr == 0) { + error = EAFNOSUPPORT; /* XXX */ + break; + } + switch (ifr->ifr_addr.sa_family) { + +#ifdef INET + case AF_INET: + break; +#endif +#ifdef INET6 + case AF_INET6: + break; +#endif + + default: + error = EAFNOSUPPORT; + break; + } + break; + + case SIOCSIFMTU: + ifp->if_mtu = ifr->ifr_mtu>VMNMTU?VMNMTU:ifr->ifr_mtu; + break; + + case SIOCSIFFLAGS: + break; + + default: + error = EINVAL; + } + return (error); +}