├── sys ├── src │ ├── nix │ │ ├── 386 │ │ │ └── random.c │ │ ├── test │ │ │ ├── 1 │ │ │ │ ├── output │ │ │ │ ├── runtest │ │ │ │ └── kern │ │ │ ├── 6.testzio │ │ │ ├── 6.testzp │ │ │ ├── tools │ │ │ ├── Tests │ │ │ ├── runtests │ │ │ └── README │ │ ├── k10 │ │ │ ├── root │ │ │ │ ├── tcp17010 │ │ │ │ ├── mkfile │ │ │ │ ├── k8root.namespace │ │ │ │ └── k8root.proto │ │ │ ├── Linux │ │ │ ├── init9.c │ │ │ ├── boot.fs │ │ │ ├── nixtype │ │ │ ├── memory.c │ │ │ ├── iob.h │ │ │ ├── cpuidamd64.s │ │ │ ├── l64cpuid.s │ │ │ ├── map.c │ │ │ ├── l64fpu.s │ │ │ ├── etherif.h │ │ │ ├── l64syscall.s │ │ │ ├── sipi.h │ │ │ ├── k8cpu │ │ │ ├── arch.c │ │ │ ├── l64acsyscall.s │ │ │ ├── qqsort.c │ │ │ ├── msi.c │ │ │ ├── apic.h │ │ │ ├── sipi.c │ │ │ ├── k8cpufs │ │ │ ├── mkfile │ │ │ ├── crap.c │ │ │ └── cga.c │ │ ├── root │ │ │ ├── tcp564 │ │ │ ├── tcp23 │ │ │ ├── mkfile │ │ │ ├── profile │ │ │ ├── big.c │ │ │ ├── bigloop.c │ │ │ └── rcmain │ │ ├── w │ │ │ └── pxeload │ │ │ │ ├── ppxeload │ │ │ │ ├── ppxeloadacid │ │ │ │ ├── apm.c │ │ │ │ ├── ilock.c │ │ │ │ ├── multiboot.c │ │ │ │ ├── ureg.h │ │ │ │ ├── queue.c │ │ │ │ ├── fs.h │ │ │ │ ├── kfs.h │ │ │ │ ├── print.c │ │ │ │ ├── etherif.h │ │ │ │ ├── dosfs.h │ │ │ │ ├── fs.c │ │ │ │ ├── alarm.c │ │ │ │ ├── mkfile │ │ │ │ ├── l64p.s │ │ │ │ ├── mmu64.h │ │ │ │ ├── cga.c │ │ │ │ ├── ip.h │ │ │ │ ├── error.h │ │ │ │ ├── lib.h │ │ │ │ └── warp64.c │ │ ├── bench │ │ │ ├── 1 │ │ │ │ ├── output │ │ │ │ ├── kern │ │ │ │ └── runbench │ │ │ ├── Mean │ │ │ ├── Benchs │ │ │ ├── Time │ │ │ ├── tools │ │ │ ├── Locks │ │ │ └── runbenchs │ │ ├── boot │ │ │ ├── printstub.c │ │ │ ├── mkfile │ │ │ ├── getpasswd.c │ │ │ ├── sac.c │ │ │ ├── nopsession.c │ │ │ ├── paq.c │ │ │ ├── bootauth.c │ │ │ ├── embed.c │ │ │ ├── bootcache.c │ │ │ ├── boot.h │ │ │ ├── doauthenticate.c │ │ │ └── settime.c │ │ ├── mk │ │ │ ├── mkroot │ │ │ ├── mkrootall │ │ │ ├── bootmkfile │ │ │ ├── mkrr │ │ │ └── mkenum │ │ ├── port │ │ │ ├── print.c │ │ │ ├── pmc.h │ │ │ ├── mul64fract.c │ │ │ ├── initcode.c │ │ │ ├── aoe.h │ │ │ ├── edf.h │ │ │ ├── devtab.c │ │ │ ├── latin1.c │ │ │ ├── alarm.c │ │ │ ├── rebootcmd.c │ │ │ ├── rdb.c │ │ │ ├── ps.c │ │ │ ├── parse.c │ │ │ ├── rmap.c │ │ │ ├── devwd.c │ │ │ ├── error.h │ │ │ ├── devdup.c │ │ │ ├── latin1.h │ │ │ ├── netif.h │ │ │ └── sd.h │ │ ├── nix │ │ ├── words │ │ ├── ip │ │ │ ├── inferno.c │ │ │ ├── nullmedium.c │ │ │ ├── ptclbsum.c │ │ │ ├── pktmedium.c │ │ │ ├── loopbackmedium.c │ │ │ ├── chandial.c │ │ │ └── netdevmedium.c │ │ └── rc │ │ │ ├── test_vmx │ │ │ └── mknixboot │ ├── NOTICE │ ├── cmd │ │ └── rc │ │ │ ├── getflags.h │ │ │ ├── io.h │ │ │ ├── trap.c │ │ │ ├── mkfile │ │ │ ├── subr.c │ │ │ ├── pfnc.c │ │ │ ├── var.c │ │ │ ├── fns.h │ │ │ ├── tree.c │ │ │ ├── exec.h │ │ │ ├── here.c │ │ │ ├── pcmd.c │ │ │ └── syn.y │ └── libc │ │ └── 9syscall │ │ ├── sys.h │ │ └── mkfile └── include │ ├── trace.h │ └── tos.h ├── NOTICE ├── CONTRIBUTORS ├── LICENSE └── NOTES /sys/src/nix/test/1/output: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sys/src/nix/k10/root/tcp17010: -------------------------------------------------------------------------------- 1 | #!/bin/cpu -N -R 2 | -------------------------------------------------------------------------------- /sys/src/nix/root/tcp564: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | exec exportfs -r / 3 | -------------------------------------------------------------------------------- /sys/src/nix/root/tcp23: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | exec /bin/ip/telnetd -at $* 3 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Copyright © 2002 Lucent Technologies Inc. 2 | All Rights Reserved 3 | -------------------------------------------------------------------------------- /sys/src/NOTICE: -------------------------------------------------------------------------------- 1 | Copyright © 2002 Lucent Technologies Inc. 2 | All Rights Reserved 3 | -------------------------------------------------------------------------------- /sys/src/nix/test/6.testzio: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rminnich/nix-os/HEAD/sys/src/nix/test/6.testzio -------------------------------------------------------------------------------- /sys/src/nix/test/6.testzp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rminnich/nix-os/HEAD/sys/src/nix/test/6.testzp -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/ppxeload: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rminnich/nix-os/HEAD/sys/src/nix/w/pxeload/ppxeload -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/ppxeloadacid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rminnich/nix-os/HEAD/sys/src/nix/w/pxeload/ppxeloadacid -------------------------------------------------------------------------------- /sys/src/nix/k10/Linux: -------------------------------------------------------------------------------- 1 | Linux support was removed from this kernel. 2 | It may be found in /n/nixdump/2011/1114/sys/src/nix 3 | -------------------------------------------------------------------------------- /sys/src/nix/k10/init9.c: -------------------------------------------------------------------------------- 1 | extern void startboot(char*, char**); 2 | 3 | void 4 | main(char* argv0) 5 | { 6 | startboot(argv0, &argv0); 7 | } 8 | -------------------------------------------------------------------------------- /sys/src/nix/test/tools: -------------------------------------------------------------------------------- 1 | fn fail { 2 | echo $* >[1=2] 3 | exit fail 4 | } 5 | 6 | fn log { 7 | echo $* 8 | echo $* >/dev/cons 9 | } 10 | -------------------------------------------------------------------------------- /sys/src/cmd/rc/getflags.h: -------------------------------------------------------------------------------- 1 | #define NFLAG 128 2 | 3 | extern char **flag[NFLAG]; 4 | extern char *cmdname; 5 | extern char *flagset[]; 6 | 7 | int getflags(int, char*[], char*, int); 8 | -------------------------------------------------------------------------------- /sys/src/nix/bench/Mean: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | sed 's/[sur]//g' $* | 3 | awk 'BEGIN{u=0.0; s=0.0; t=0.0} 4 | {u += $1; s += $2; t += $3} 5 | END{printf("times %g %g %g\n", u/NR, s/NR, t/NR);}' 6 | -------------------------------------------------------------------------------- /sys/src/nix/k10/boot.fs: -------------------------------------------------------------------------------- 1 | #!/boot/rc -m /boot/rcmain 2 | /boot/echo Morning 3 | # boot script for file servers, including standalone ones 4 | path=(/boot /$cputype/bin /rc/bin .) 5 | exec /boot/rc -m/boot/rcmain -i 6 | -------------------------------------------------------------------------------- /sys/src/nix/k10/nixtype: -------------------------------------------------------------------------------- 1 | trap.c:261: tos->kcycles += t - up->kentry; 2 | trap.c:262: tos->pcycles = up->pcycles; 3 | trap.c:263: tos->pid = up->pid; 4 | trap.c:268: tos->core = mp->machno; 5 | trap.c:269: tos->nixtype = mp->nixtype; 6 | -------------------------------------------------------------------------------- /sys/src/nix/root/mkfile: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | static Lock fmtl; 5 | 6 | void 7 | _fmtlock(void) 8 | { 9 | lock(&fmtl); 10 | } 11 | 12 | void 13 | _fmtunlock(void) 14 | { 15 | unlock(&fmtl); 16 | } 17 | 18 | int 19 | _efgfmt(Fmt*) 20 | { 21 | return -1; 22 | } 23 | -------------------------------------------------------------------------------- /sys/src/nix/test/1/runtest: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | 3 | rfork ne 4 | 5 | # import rc functions popular among scripts, e.g. fail 6 | # 7 | . ../tools 8 | 9 | # make sure we have 32 cores running 10 | ncores=`{wc -l /dev/sysstat | sed 's,/.*,,'} 11 | ~ $ncores 32 || fail does not have 32 cores 12 | 13 | -------------------------------------------------------------------------------- /sys/src/nix/root/profile: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | 3 | switch($service){ 4 | case terminal 5 | prompt=('% ' ' ') 6 | status='' 7 | case cpu 8 | prompt=($sysname'% ' ' ') 9 | bind /mnt/term/dev/cons /dev/cons 10 | bind /mnt/term/dev/consctl /dev/consctl 11 | bind -a /mnt/term/dev /dev 12 | status='' 13 | } 14 | -------------------------------------------------------------------------------- /sys/src/nix/mk/mkroot: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | 3 | rfork e 4 | echo mkroot $* 5 | if(! ~ $#* 2){ 6 | echo usage: mkroot path name >[2=1] 7 | exit 1 8 | } 9 | n=`{basename $1} 10 | cp $1 $2.out 11 | t=`{file $2.out} 12 | if(~ $"t *executable*) 13 | strip $2.out 14 | aux/data2s $2 < $2.out > $2.root.s 15 | echo mkroot $* done 16 | -------------------------------------------------------------------------------- /sys/src/nix/k10/memory.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | 7 | void 8 | meminit(void) 9 | { 10 | extern void asmmeminit(void); 11 | 12 | asmmeminit(); 13 | } 14 | 15 | void 16 | umeminit(void) 17 | { 18 | extern void asmumeminit(void); 19 | 20 | asmumeminit(); 21 | } 22 | -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/apm.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "io.h" 7 | 8 | Apminfo apm; 9 | 10 | void 11 | apminit(void) 12 | { 13 | if(getconf("apm0") && apm.haveinfo) 14 | changeconf("apm0=ax=%x ebx=%x cx=%x dx=%x di=%x esi=%x\n", 15 | apm.ax, apm.ebx, apm.cx, apm.dx, apm.di, apm.esi); 16 | } 17 | -------------------------------------------------------------------------------- /sys/src/nix/k10/iob.h: -------------------------------------------------------------------------------- 1 | 2 | /* io bufs */ 3 | void iobufinit(void); 4 | Block* va2block(void*); 5 | void* io2alloc(uint); 6 | Block* bigalloc(void); 7 | Block* sbigalloc(void); 8 | int isbigblock(Block*); 9 | 10 | /* bal.c */ 11 | physaddr bal(usize); 12 | void bfree(physaddr, usize); 13 | void balinit(physaddr, usize); 14 | void balfreephys(physaddr, usize); 15 | void baldump(void); 16 | -------------------------------------------------------------------------------- /sys/src/nix/boot/mkfile: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | void 5 | main(int argc, char *argv[]) 6 | { 7 | ulong num = 1; 8 | uvlong size; 9 | u8int *c; 10 | 11 | if (argc > 1) 12 | num = strtoul(argv[1], 0, 0); 13 | size = num * 0x200000ULL; 14 | print("Try to malloc %ulld bytes\n", size); 15 | c = mallocz(size, 1); 16 | print("Did it\n"); 17 | while(1); 18 | } 19 | 20 | /* 6c big.c; 6l -o big big.6 */ 21 | -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/ilock.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "io.h" 7 | 8 | void 9 | ilock(Lock *lk) 10 | { 11 | if(lk->locked != 0) 12 | panic("ilock"); 13 | lk->spl = splhi(); 14 | lk->locked = 1; 15 | } 16 | 17 | void 18 | iunlock(Lock *lk) 19 | { 20 | if(lk->locked != 1) 21 | panic("iunlock"); 22 | lk->locked = 0; 23 | splx(lk->spl); 24 | } 25 | -------------------------------------------------------------------------------- /sys/src/nix/bench/Benchs: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | 3 | # change the boot sequence to run benchs. 4 | 5 | # remove output from all benchs: 6 | # rm -f [0-9]*/^(koutput output FAIL KMESG) k[0-9]*/^(koutput output FAIL KMESG) 7 | 8 | # remove output from some benchs, to rerun them: 9 | # for(t in 93 94 95) rm -f $t/^(koutput output FAIL KMESG) 10 | 11 | 12 | # arrange for them to run after rebooting 13 | cp runbenchs /cfg/$sysname/runbenchs 14 | runbenchs 15 | 16 | -------------------------------------------------------------------------------- /sys/src/nix/port/print.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | 7 | static Lock fmtl; 8 | 9 | void 10 | _fmtlock(void) 11 | { 12 | lock(&fmtl); 13 | } 14 | 15 | void 16 | _fmtunlock(void) 17 | { 18 | unlock(&fmtl); 19 | } 20 | 21 | int 22 | _efgfmt(Fmt*) 23 | { 24 | return -1; 25 | } 26 | 27 | void 28 | fmtinit(void) 29 | { 30 | quotefmtinstall(); 31 | archfmtinstall(); 32 | } 33 | -------------------------------------------------------------------------------- /sys/src/nix/test/Tests: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | 3 | # change the boot sequence to run tests. 4 | 5 | # remove stale state from tests: 6 | rm -f [0-9]*/^(koutput output FAIL) k[0-9]*/^(koutput output FAIL) 7 | 8 | # arrange for them to run after rebooting 9 | if(test -e /cfg/$sysname/_runtests) 10 | mv /cfg/$sysname/_runtests /cfg/$sysname/runtests 11 | if(! test -x /cfg/$sysname/runtests){ 12 | echo there is no /cfg/$sysname/runtests 13 | exit no 14 | } 15 | reboot 16 | -------------------------------------------------------------------------------- /sys/src/nix/root/bigloop.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void 5 | main(int argc, char *argv[]) 6 | { 7 | ulong num = 1; 8 | int i; 9 | 10 | if (argc > 1) 11 | num = strtoul(argv[1], 0, 0); 12 | print("Try to malloc %ulld bytes in %ld loops\n", num*0x200000ULL, num); 13 | for(i = 0; i < num; i++) 14 | if (sbrk(0x200000) == nil){ 15 | print("%d sbrk failed\n", i); 16 | break; 17 | } 18 | print("Did it\n"); 19 | while(1); 20 | } 21 | 22 | /* 6c bigloop.c; 6l -o bigloop bigloop.6 */ 23 | -------------------------------------------------------------------------------- /sys/src/nix/test/1/kern: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | 3 | rfork ne 4 | 5 | # import rc functions popular among scripts, e.g. fail 6 | # 7 | . ../tools 8 | 9 | # we might have a main.c file here and do something like: 10 | # bind main.c ../../k10/main.c 11 | # to override the source used for this test 12 | 13 | # we might change the std source like this: 14 | # sed 's/initialTCs = [0-9]+/initialTCs = 16/' < ../../k10/main.c >main.c 15 | # bind main.c ../../k10/main.c 16 | 17 | cd /sys/src/nix/k10 18 | mk clean 19 | mk install 20 | -------------------------------------------------------------------------------- /sys/src/nix/bench/1/output: -------------------------------------------------------------------------------- 1 | # sleep 2 2 | 0.00u 0.02s 2.02r rc -c sleep 2 3 | 0.00u 0.03s 2.02r rc -c sleep 2 4 | 0.00u 0.02s 2.02r rc -c sleep 2 5 | 0.00u 0.01s 2.03r rc -c sleep 2 6 | 0.00u 0.03s 2.02r rc -c sleep 2 7 | 0.00u 0.02s 2.02r rc -c sleep 2 8 | 0.00u 0.02s 2.02r rc -c sleep 2 9 | 0.00u 0.04s 2.02r rc -c sleep 2 10 | 0.00u 0.02s 2.02r rc -c sleep 2 11 | 0.00u 0.04s 2.03r rc -c sleep 2 12 | times 0 0.025 2.022 13 | #cat /dev/debug 14 | steal 1 15 | donate 0 16 | locks 965080 17 | glare 6450 18 | inglare 8840 19 | qlock 73101 20 | qlockq 66 21 | -------------------------------------------------------------------------------- /sys/src/nix/k10/cpuidamd64.s: -------------------------------------------------------------------------------- 1 | /* 2 | * The CPUID instruction is always supported on the amd64. 3 | */ 4 | TEXT cpuid(SB), 1, $-4 5 | MOVL RARG, AX 6 | 7 | CPUID /* argument in AX */ 8 | 9 | MOVQ info+8(FP), BP 10 | MOVL AX, 0(BP) 11 | MOVL BX, 4(BP) 12 | MOVL CX, 8(BP) 13 | MOVL DX, 12(BP) 14 | RET 15 | 16 | /* 17 | * Basic timing loop to determine CPU frequency. 18 | * The AAM instruction is not available in 64-bit mode. 19 | */ 20 | TEXT aamloop(SB), 1, $-4 21 | MOVL c+0(FP), CX 22 | aaml1: 23 | XORQ AX, AX /* close enough */ 24 | LOOP aaml1 25 | RET 26 | -------------------------------------------------------------------------------- /sys/src/nix/bench/1/kern: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | 3 | rfork ne 4 | 5 | # import rc functions popular among scripts, e.g. fail 6 | # 7 | . ../tools 8 | 9 | # we might have a source file here and do something like: 10 | # to override the source used for this benchmark 11 | bind proc.c ../../port/proc.c 12 | 13 | cp /cfg/pxe/003048ff2106 pxeorig 14 | cp 003048ff2106 /cfg/pxe 15 | 16 | # we might change the std source like this: 17 | # sed 's/initialTCs = [0-9]+/initialTCs = 16/' < ../../k10/main.c >main.c 18 | # bind main.c ../../k10/main.c 19 | 20 | cd /sys/src/nix/k10 21 | mk clean 22 | mk install 23 | -------------------------------------------------------------------------------- /sys/src/nix/nix: -------------------------------------------------------------------------------- 1 | #!/bin/rc -x 2 | # 3 | # To run the resulting kernel see the scripts in /bin/nix/ 4 | # (after binding). 5 | objtype=amd64 6 | mkdir -p $home/bin/rc/nix 7 | bind -b $home/nix-os/sys/src/nix/rc $home/bin/rc/nix 8 | unmount /sys/include >[2]/dev/null 9 | unmount /sys/src/libc/9syscall >[2]/dev/null 10 | bind -b $home/nix-os/sys/include /sys/include 11 | bind -c $home/nix-os/sys/src/libc/9syscall /sys/src/libc/9syscall 12 | cd $home/nix-os/sys 13 | for(d in man/[1-9]){ 14 | unmount /sys/$d >[2]/dev/null 15 | bind -b $d /sys/$d 16 | } 17 | # Set up git. 18 | cd .. 19 | git/fs 20 | -------------------------------------------------------------------------------- /sys/src/nix/k10/root/k8root.namespace: -------------------------------------------------------------------------------- 1 | # root 2 | mount -a $rootsrv /root $rootspec 3 | bind -a /root / 4 | bind -c /root/mnt /mnt 5 | 6 | # kernel devices 7 | bind #c /dev 8 | bind #d /fd 9 | bind -c #e /env 10 | bind #p /proc 11 | bind -c #s /srv 12 | 13 | # mount points 14 | 15 | # authentication 16 | mount -a /srv/factotum /mnt 17 | 18 | # standard bin 19 | bind /root/$cputype/bin /bin 20 | bind -a /root/rc/bin /bin 21 | 22 | # networks 23 | bind -a #I /net 24 | bind -a #l0 /net 25 | #mount -a /srv/cs /net 26 | #mount -a /srv/dns /net 27 | 28 | bind -c /usr/$user/tmp /tmp 29 | cd /usr/$user 30 | -------------------------------------------------------------------------------- /sys/src/nix/mk/mkrootall: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | 3 | rfork e 4 | n=`{echo $#*^'%3' | hoc} 5 | if(! ~ $n 0){ 6 | echo 'usage: mkrootall [name cname file]...' >[1=2] 7 | exit usage 8 | } 9 | 10 | tmp=mkroot.$pid.out 11 | fn sigexit { 12 | rm -f $tmp 13 | } 14 | 15 | allcname=() 16 | while(! ~ $#* 0){ 17 | name=$1 18 | cname=$2 19 | file=$3 20 | shift 21 | shift 22 | shift 23 | allcname=($allcname $cname) 24 | cp $file $tmp 25 | t=`{file $tmp} 26 | # do not strip venti - it uses its own symbols 27 | if(~ $"t *executable* && ! ~ $name venti) 28 | strip $tmp 29 | aux/data2s $cname < $tmp 30 | } 31 | exit 0 32 | -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/multiboot.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "io.h" 7 | 8 | MMap mmap[20]; 9 | int nmmap; 10 | 11 | Mbi multibootheader; 12 | 13 | void 14 | mkmultiboot(void) 15 | { 16 | if(nmmap != 0){ 17 | multibootheader.cmdline = PADDR(BOOTLINE); 18 | multibootheader.flags |= Fcmdline; 19 | multibootheader.mmapaddr = PADDR(mmap); 20 | multibootheader.mmaplength = nmmap*sizeof(MMap); 21 | multibootheader.flags |= Fmmap; 22 | if(vflag) 23 | print("&multibootheader %#p\n", &multibootheader); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /sys/src/nix/words: -------------------------------------------------------------------------------- 1 | 2 | To compile and use it you have to do the binds shown in ./nix 3 | 4 | This is the main nix source tree. 5 | It's using 2M pages, and supports 1G pages. 6 | In there, there are experimental frameworks for zero-copy, tubes, what else? 7 | 8 | The main author was initially jmk and perhaps others from bell labs, when it was 9k. 9 | Today it has been changed by many others including (|sort order): 10 | esoriano 11 | forsyth 12 | jmk 13 | nemo 14 | npe 15 | paurea 16 | rminnich 17 | 18 | You can reach as at nix A_T lsub.org 19 | But don't write A_T like that. 20 | Fri Sep 2 22:03:15 CET 2011 21 | -------------------------------------------------------------------------------- /sys/src/nix/k10/l64cpuid.s: -------------------------------------------------------------------------------- 1 | /* 2 | * The CPUID instruction is always supported on the amd64. 3 | */ 4 | TEXT cpuid(SB), $-4 5 | MOVL RARG, AX /* function in AX */ 6 | MOVLQZX cx+8(FP), CX /* iterator/index/etc. */ 7 | 8 | CPUID 9 | 10 | MOVQ info+16(FP), BP 11 | MOVL AX, 0(BP) 12 | MOVL BX, 4(BP) 13 | MOVL CX, 8(BP) 14 | MOVL DX, 12(BP) 15 | RET 16 | 17 | /* 18 | * Basic timing loop to determine CPU frequency. 19 | * The AAM instruction is not available in 64-bit mode. 20 | */ 21 | TEXT aamloop(SB), 1, $-4 22 | MOVLQZX RARG, CX 23 | aaml1: 24 | XORQ AX, AX /* close enough */ 25 | LOOP aaml1 26 | RET 27 | -------------------------------------------------------------------------------- /sys/src/cmd/rc/io.h: -------------------------------------------------------------------------------- 1 | #define EOF (-1) 2 | #define NBUF 512 3 | 4 | struct io{ 5 | int fd; 6 | uchar *bufp, *ebuf, *strp; 7 | uchar buf[NBUF]; 8 | }; 9 | io *err; 10 | 11 | io *openfd(int), *openstr(void), *opencore(char *, int); 12 | int emptybuf(io*); 13 | void pchr(io*, int); 14 | int rchr(io*); 15 | void closeio(io*); 16 | void flush(io*); 17 | int fullbuf(io*, int); 18 | void pdec(io*, int); 19 | void poct(io*, unsigned); 20 | void pptr(io*, void*); 21 | void pquo(io*, char*); 22 | void pwrd(io*, char*); 23 | void pstr(io*, char*); 24 | void pcmd(io*, tree*); 25 | void pval(io*, word*); 26 | void pfnc(io*, thread*); 27 | void pfmt(io*, char*, ...); 28 | -------------------------------------------------------------------------------- /sys/src/nix/bench/1/runbench: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | 3 | # 4 | # kernel as of /n/nixdump/2012/0119/sys/src/nix/bench 5 | # Single sched, 32 TCs. 6 | # Time to make a kernel 7 | # 8 | 9 | rfork ne 10 | 11 | # restore the pxe file we saved 12 | cp pxeorig /cfg/pxe/003048ff2106 13 | 14 | # import rc functions popular among scripts, e.g. fail 15 | # 16 | . ../tools 17 | 18 | # How much time does it take to make a kernel 19 | ../Time 'cd /sys/src/nix/k10 ; mk clean ; mk' 20 | 21 | 22 | # What's the value for measures taken from the kernel? 23 | # echo '#cat /dev/debug' 24 | # cat /dev/debug 25 | # NB: this is an example. /dev/debug is reported already by Time 26 | 27 | -------------------------------------------------------------------------------- /sys/src/nix/port/pmc.h: -------------------------------------------------------------------------------- 1 | 2 | enum{ 3 | PmcCtlNullval = 0xdead, 4 | }; 5 | 6 | typedef struct PmcCtlCtrId PmcCtlCtrId; 7 | 8 | 9 | struct PmcCtlCtrId { 10 | char portdesc[KNAMELEN]; 11 | char archdesc[KNAMELEN]; 12 | }; 13 | 14 | int pmcnregs(void); 15 | int pmcsetctl(u32int coreno, PmcCtl *p, u32int regno); 16 | int pmctrans(PmcCtl *p); 17 | int pmcgetctl(u32int coreno, PmcCtl *p, u32int regno); 18 | int pmcdescstr(char *str, int nstr); 19 | int pmcctlstr(char *str, int nstr, PmcCtl *p); 20 | u64int pmcgetctr(u32int coreno, u32int regno); 21 | int pmcsetctr(u32int coreno, u64int v, u32int regno); 22 | 23 | void pmcupdate(Mach *m); 24 | extern void (*_pmcupdate)(Mach *m); 25 | -------------------------------------------------------------------------------- /sys/src/nix/ip/inferno.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "../port/error.h" 7 | #include "ip.h" 8 | 9 | /* 10 | * some hacks for commonality twixt inferno and plan9 11 | */ 12 | 13 | char* 14 | commonuser(void) 15 | { 16 | return up->user; 17 | } 18 | 19 | Chan* 20 | commonfdtochan(int fd, int mode, int a, int b) 21 | { 22 | return fdtochan(fd, mode, a, b); 23 | } 24 | 25 | char* 26 | commonerror(void) 27 | { 28 | return up->errstr; 29 | } 30 | 31 | char* 32 | bootp(Ipifc*) 33 | { 34 | return "unimplmented"; 35 | } 36 | 37 | int 38 | bootpread(char*, ulong, int) 39 | { 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /sys/src/nix/ip/nullmedium.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "../port/error.h" 7 | 8 | #include "ip.h" 9 | 10 | static void 11 | nullbind(Ipifc*, int, char**) 12 | { 13 | error("cannot bind null device"); 14 | } 15 | 16 | static void 17 | nullunbind(Ipifc*) 18 | { 19 | } 20 | 21 | static void 22 | nullbwrite(Ipifc*, Block*, int, uchar*) 23 | { 24 | error("nullbwrite"); 25 | } 26 | 27 | Medium nullmedium = 28 | { 29 | .name= "null", 30 | .bind= nullbind, 31 | .unbind= nullunbind, 32 | .bwrite= nullbwrite, 33 | }; 34 | 35 | void 36 | nullmediumlink(void) 37 | { 38 | addipmedium(&nullmedium); 39 | } 40 | -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/ureg.h: -------------------------------------------------------------------------------- 1 | typedef struct Ureg Ureg; 2 | 3 | struct Ureg 4 | { 5 | ulong di; /* general registers */ 6 | ulong si; /* ... */ 7 | ulong bp; /* ... */ 8 | ulong nsp; 9 | ulong bx; /* ... */ 10 | ulong dx; /* ... */ 11 | ulong cx; /* ... */ 12 | ulong ax; /* ... */ 13 | ulong gs; /* data segments */ 14 | ulong fs; /* ... */ 15 | ulong es; /* ... */ 16 | ulong ds; /* ... */ 17 | ulong trap; /* trap type */ 18 | ulong ecode; /* error code (or zero) */ 19 | ulong pc; /* pc */ 20 | ulong cs; /* old context */ 21 | ulong flags; /* old flags */ 22 | union { 23 | ulong usp; 24 | ulong sp; 25 | }; 26 | ulong ss; /* old stack segment */ 27 | }; 28 | -------------------------------------------------------------------------------- /sys/src/nix/bench/Time: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | rfork e 3 | cmd=$1 4 | echo '#' $1 5 | echo measuring $1... >'#c/cons' 6 | rm -f /tmp/bench.time 7 | rc -c $cmd >'#c/cons' # warm cache and be able to see the output of the cmd... 8 | echo >/dev/sysstat 9 | for(i in `{seq 10}){ 10 | time rc -c $cmd >/dev/null >>[2]/tmp/bench.time 11 | tail -1 /tmp/bench.time 12 | tail -1 /tmp/bench.time >'#c/cons' 13 | } 14 | cp /dev/sysstat /tmp/sysstat 15 | sed 's/[sur]//g' /tmp/$pid.ini 11 | 12 | # You must clean up the VMs after running vmx. We rarely get clean 13 | # exits, so you have to pay attention. 14 | # 15 | 16 | vmx -c /dev/cons -w 1024x768 -m /tmp/$pid.ini $home/nix-os/sys/src/nix/k10/9k8cpu $* 17 | 18 | # Clean up 19 | rm -f /tmp/$pid.ini 20 | echo stop >> '#X/0/ctl' 21 | echo quit >> '#X/0/ctl' 22 | 23 | exit 24 | 25 | ##BEGIN_INI 26 | #vgasize=1024x768x16 27 | #mouseport=ps2 28 | ##END_INI 29 | -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/queue.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "io.h" 7 | 8 | int 9 | qgetc(IOQ *q) 10 | { 11 | int c; 12 | 13 | if(q->in == q->out) 14 | return -1; 15 | c = *q->out; 16 | if(q->out == q->buf+sizeof(q->buf)-1) 17 | q->out = q->buf; 18 | else 19 | q->out++; 20 | return c; 21 | } 22 | 23 | static int 24 | qputc(IOQ *q, int c) 25 | { 26 | uchar *nextin; 27 | if(q->in >= &q->buf[sizeof(q->buf)-1]) 28 | nextin = q->buf; 29 | else 30 | nextin = q->in+1; 31 | if(nextin == q->out) 32 | return -1; 33 | *q->in = c; 34 | q->in = nextin; 35 | return 0; 36 | } 37 | 38 | void 39 | qinit(IOQ *q) 40 | { 41 | q->in = q->out = q->buf; 42 | q->getc = qgetc; 43 | q->putc = qputc; 44 | } 45 | -------------------------------------------------------------------------------- /sys/src/nix/mk/bootmkfile: -------------------------------------------------------------------------------- 1 | BOOTDIR=../boot 2 | BOOTLIB=$BOOTDIR/libboot.a$O 3 | 4 | BOOTFILES=\ 5 | bootauth.$O\ 6 | aux.$O\ 7 | boot.$O\ 8 | bootcache.$O\ 9 | bootip.$O\ 10 | local.$O\ 11 | embed.$O\ 12 | settime.$O\ 13 | sac.$O\ 14 | paq.$O\ 15 | printstub.$O\ 16 | 17 | $BOOTLIB(%.$O):N: %.$O 18 | 19 | $BOOTLIB: ${BOOTFILES:%=$BOOTLIB(%)} 20 | names=`{membername $newprereq} 21 | ar vu $BOOTLIB $names 22 | rm $names 23 | 24 | $BOOTFILES: $BOOTDIR/boot.h 25 | 26 | %.$O: $BOOTDIR/%.c 27 | $CC -I$BOOTDIR $CFLAGS $BOOTDIR/$stem.c 28 | 29 | boot$CONF.out: ../mk/parse $CONF print.$O $BOOTDIR/boot.c $BOOTLIB 30 | awk -f ../mk/parse -- -mkbootconf $CONF > boot$CONF.c 31 | $CC $CFLAGS boot$CONF.c 32 | $CC $CFLAGS ../boot/printstub.c 33 | $LD -o boot$CONF.out boot$CONF.$O $BOOTLIB printstub.$O 34 | -------------------------------------------------------------------------------- /sys/src/nix/test/runtests: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | 3 | echo tests... 4 | cd /sys/src/nix/test 5 | . tools 6 | failed=() 7 | tests=[0-9]* 8 | if(test -e k[0-9]*) 9 | tests=($tests k[0-9]*) 10 | for(t in $tests){ 11 | cd $t || fail cannot cd into test $t 12 | if(test -e FAIL) 13 | failed=($failed $t) 14 | if not{ 15 | if(! test -e output && ! test -e FAIL) { 16 | echo running test $t 17 | if(test -x kern && ! test -e koutput){ 18 | log running kern for test $t 19 | if(! kern >koutput >[2=1]){ 20 | touch FAIL 21 | fail test $t failed 22 | } 23 | reboot 24 | } 25 | if(! runtest>output >[2=1]){ 26 | touch FAIL 27 | fail test $t failed 28 | } 29 | echo test $t ok 30 | } 31 | } 32 | cd .. 33 | } 34 | if(! ~ $#failed 0) 35 | echo tests $failed failed 36 | if not 37 | echo all tests passed 38 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | #The following people have contributed source code to nix. 2 | 3 | Noah Evans 4 | Ron Minnich 5 | John Floren 6 | Francisco J Ballesteros 7 | Charles Forsyth 8 | Enrique Soriano 9 | Gorka Guardiola 10 | James Mckie 11 | Christian Neukirchen 12 | Erik Quanstrom 13 | Erik Quanstrom 14 | Bakul Shah 15 | David du Colombier <0intro@gmail.com> 16 | Akshat Kumar 17 | Akshat Kumar 18 | Anthony Martin 19 | Marius Hillenbrand 20 | Paul Lalonde 21 | -------------------------------------------------------------------------------- /sys/include/trace.h: -------------------------------------------------------------------------------- 1 | typedef enum Tevent { 2 | SAdmit = 0, /* Edf admit */ 3 | SRelease, /* Edf release, waiting to be scheduled */ 4 | SEdf, /* running under EDF */ 5 | SRun, /* running best effort */ 6 | SReady, /* runnable but not running */ 7 | SSleep, /* blocked */ 8 | SYield, /* blocked waiting for release */ 9 | SSlice, /* slice exhausted */ 10 | SDeadline, /* proc's deadline */ 11 | SExpel, /* Edf expel */ 12 | SDead, /* proc dies */ 13 | SInts, /* Interrupt start */ 14 | SInte, /* Interrupt end */ 15 | SUser, /* user event */ 16 | SLock, /* blocked on a queue or lock */ 17 | Nevent, 18 | } Tevent; 19 | 20 | typedef struct Traceevent Traceevent; 21 | struct Traceevent { 22 | u32int pid; 23 | u32int etype; /* Event type */ 24 | u64int time; /* time stamp */ 25 | u32int core; /* core number */ 26 | }; 27 | -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/fs.h: -------------------------------------------------------------------------------- 1 | typedef struct File File; 2 | typedef struct Fs Fs; 3 | 4 | #include "dosfs.h" 5 | #include "kfs.h" 6 | 7 | struct File{ 8 | union{ 9 | Dosfile dos; 10 | Kfsfile kfs; 11 | int walked; 12 | }; 13 | Fs *fs; 14 | char *path; 15 | }; 16 | 17 | struct Fs{ 18 | union { 19 | Dos dos; 20 | Kfs kfs; 21 | }; 22 | int dev; /* device id */ 23 | long (*diskread)(Fs*, void*, long); /* disk read routine */ 24 | vlong (*diskseek)(Fs*, vlong); /* disk seek routine */ 25 | long (*read)(File*, void*, long); 26 | int (*walk)(File*, char*); 27 | File root; 28 | }; 29 | 30 | extern int chatty; 31 | extern int dotini(Fs*); 32 | extern int fswalk(Fs*, char*, File*); 33 | extern int fsread(File*, void*, long); 34 | extern int fsboot(Fs*, char*, Boot*); 35 | 36 | #define BADPTR(x) ((ulong)x < (ulong)(KZERO+0x7c00)) 37 | -------------------------------------------------------------------------------- /sys/src/nix/boot/getpasswd.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include <../boot/boot.h> 4 | 5 | void 6 | getpasswd(char *p, int len) 7 | { 8 | char c; 9 | int i, n, fd; 10 | 11 | fd = open("#c/consctl", OWRITE); 12 | if(fd < 0) 13 | fatal("can't open consctl; please reboot"); 14 | write(fd, "rawon", 5); 15 | Prompt: 16 | print("password: "); 17 | n = 0; 18 | for(;;){ 19 | do{ 20 | i = read(0, &c, 1); 21 | if(i < 0) 22 | fatal("can't read cons; please reboot"); 23 | }while(i == 0); 24 | switch(c){ 25 | case '\n': 26 | p[n] = '\0'; 27 | close(fd); 28 | print("\n"); 29 | return; 30 | case '\b': 31 | if(n > 0) 32 | n--; 33 | break; 34 | case 'u' - 'a' + 1: /* cntrl-u */ 35 | print("\n"); 36 | goto Prompt; 37 | default: 38 | if(n < len - 1) 39 | p[n++] = c; 40 | break; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /sys/src/nix/bench/tools: -------------------------------------------------------------------------------- 1 | fn fail { 2 | echo $* >[1=2] 3 | exit fail 4 | } 5 | 6 | fn log { 7 | echo $* 8 | echo $* >/dev/cons 9 | } 10 | 11 | 12 | fn repeatforallnumcores { 13 | test -e kern || fail no kernel bench 14 | test -e 003048ff2106 || fail no pxe file 15 | test -e koutput || fail no koutput 16 | test -e output || fail no output 17 | 18 | NC=`{grep '^bootfile' 003048ff2106 | awk '{print $NF}'} 19 | if(~ $NC 32){ 20 | cp output output.32 21 | cp KMESG KMESG.32 22 | exit '' 23 | } 24 | @{ 25 | NNC=`{echo $NC + 1|hoc} 26 | mv 003048ff2106 003048ff2106_ 27 | sed 's/-ck .*/-ck '^$NNC^' '^$NNC^'/' < 003048ff2106_ >003048ff2106 28 | 29 | mv output output.$NC 30 | mv KMESG KMESG.$NC 31 | cp 003048ff2106 /cfg/pxe 32 | # mv koutput koutput.$NC 33 | echo reboot to run `{pwd} with $NNC cores... 34 | reboot 35 | @} >'#c/cons' >[2]'#c/cons' 36 | status='' 37 | } 38 | -------------------------------------------------------------------------------- /sys/src/nix/bench/Locks: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | rfork e 3 | cmd=$1 4 | echo '#' $1 5 | echo measuring $1... >'#c/cons' 6 | rm -f /tmp/bench.time 7 | rc -c $cmd >'#c/cons' # warm cache and be able to see the output of the cmd... 8 | # 9 | # collect stats. A single run this time. 10 | # 11 | echo >/dev/sysstat 12 | bind -a '#W' /dev 13 | echo start >/dev/wsctl 14 | time rc -c $cmd >/dev/null >>[2]/tmp/bench.time 15 | echo stop >/dev/wsctl 16 | cp /dev/wsdata /tmp/wsdata 17 | cp /dev/sysstat /tmp/sysstat 18 | tail -1 /tmp/bench.time 19 | tail -1 /tmp/bench.time >'#c/cons' 20 | sed 's/[sur]//g' = KSEG0 && pa < KSEG0+TMFM) 30 | return pa-KSEG0; 31 | if(pa > KSEG2) 32 | return pa-KSEG2; 33 | 34 | panic("PADDR: va %#p pa #%p @ %#p\n", va, _PADDR(va), getcallerpc(&va)); 35 | return 0; 36 | } 37 | 38 | KMap* 39 | kmap(Page* page) 40 | { 41 | DBG("kmap(%#llux) @ %#p: %#p %#p\n", 42 | page->pa, getcallerpc(&page), 43 | page->pa, KADDR(page->pa)); 44 | 45 | return KADDR(page->pa); 46 | } 47 | -------------------------------------------------------------------------------- /sys/src/nix/bench/runbenchs: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | 3 | echo benchs... 4 | cd /sys/src/nix/bench 5 | . tools 6 | failed=() 7 | benchs=`{ls -d [0-9]* | sort -n} 8 | if(test -e k[0-9]*) 9 | benchs=($benchs k[0-9]*) 10 | 11 | for(t in $benchs){ 12 | cd $t || fail cannot cd into benchs $t 13 | if(test -e FAIL) 14 | failed=($failed $t) 15 | if not{ 16 | if(! test -e output && ! test -e FAIL) { 17 | echo running bench $t 18 | if(test -x kern && ! test -e koutput){ 19 | echo running kern for bench $t 20 | if(! kern >koutput >[2=1]){ 21 | touch FAIL 22 | fail bench $t failed 23 | } 24 | reboot 25 | } 26 | if(test -x kern) 27 | cp /dev/kmesg KMESG 28 | if(! runbench>output >[2=1]){ 29 | touch FAIL 30 | fail bench $t failed 31 | } 32 | echo bench $t ok 33 | } 34 | } 35 | cd .. 36 | } 37 | if(! ~ $#failed 0) 38 | echo benchs $failed failed 39 | if not 40 | echo all benchs done 41 | 42 | rm /cfg/$sysname/runbenchs 43 | -------------------------------------------------------------------------------- /sys/src/nix/mk/mkrr: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | 3 | rfork en 4 | 5 | switch($#*){ 6 | case 1 7 | PROTO=$1.proto 8 | case 2 9 | PROTO=$2 10 | case * 11 | echo $0: usage: $0 conf [proto] 12 | exit "usage" 13 | } 14 | 15 | ramfs -S ramfs.$pid 16 | mount -c /srv/ramfs.$pid /tmp 17 | mkdir /tmp/mnt /tmp/empty 18 | 19 | # clean up files and procs on exit 20 | fn sigexit { 21 | echo sync>>/srv/flcons.$pid 22 | unmount /tmp/mnt 23 | unmount /tmp 24 | echo halt>>/srv/flcons.$pid 25 | rm -f /srv/*.$pid 26 | kill ramfs fossil|rc 27 | } 28 | 29 | {syscall seek 1 8388608 0; echo} >>/tmp/fldisk |[0=2] grep -v 'no error$' 30 | fossil/flfmt -b 4096 -y /tmp/fldisk 31 | 32 | fossil/conf -w /tmp/fldisk <val; 14 | while(ntrap) for(i = 0;i!=NSIG;i++) while(trap[i]){ 15 | --trap[i]; 16 | --ntrap; 17 | if(getpid()!=mypid) Exit(getstatus()); 18 | trapreq = vlook(Signame[i]); 19 | if(trapreq->fn){ 20 | start(trapreq->fn, trapreq->pc, (struct var *)0); 21 | runq->local = newvar(strdup("*"), runq->local); 22 | runq->local->val = copywords(starval, (struct word *)0); 23 | runq->local->changed = 1; 24 | runq->redir = runq->startredir = 0; 25 | } 26 | else if(i==SIGINT || i==SIGQUIT){ 27 | /* 28 | * run the stack down until we uncover the 29 | * command reading loop. Xreturn will exit 30 | * if there is none (i.e. if this is not 31 | * an interactive rc.) 32 | */ 33 | while(!runq->iflag) Xreturn(); 34 | } 35 | else Exit(getstatus()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /sys/src/nix/boot/sac.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include <../boot/boot.h> 4 | 5 | /* 6 | * HACK - take over from boot since file system is not 7 | * available on a pipe 8 | */ 9 | 10 | void 11 | configsac(Method *mp) 12 | { 13 | int fd; 14 | char cmd[64]; 15 | 16 | USED(mp); 17 | 18 | /* 19 | * create the name space, mount the root fs 20 | */ 21 | if(bind("/", "/", MREPL) < 0) 22 | fatal("bind /"); 23 | if(bind("#C", "/", MAFTER) < 0) 24 | fatal("bind /"); 25 | 26 | /* fixed sysname - enables correct namespace file */ 27 | fd = open("#c/sysname", OWRITE); 28 | if(fd < 0) 29 | fatal("open sysname"); 30 | write(fd, "brick", 5); 31 | close(fd); 32 | 33 | fd = open("#c/hostowner", OWRITE); 34 | if(fd < 0) 35 | fatal("open sysname"); 36 | write(fd, "brick", 5); 37 | close(fd); 38 | 39 | sprint(cmd, "/%s/init", cputype); 40 | print("starting %s\n", cmd); 41 | execl(cmd, "init", "-c", 0); 42 | fatal(cmd); 43 | } 44 | 45 | int 46 | connectsac(void) 47 | { 48 | /* does not get here */ 49 | return -1; 50 | } 51 | -------------------------------------------------------------------------------- /sys/src/nix/port/mul64fract.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | 3 | /* mul64fract(uvlong*r, uvlong a, uvlong b) 4 | * 5 | * Multiply two 64 numbers and return the middle 64 bits of the 128 bit result. 6 | * 7 | * The assumption is that one of the numbers is a 8 | * fixed point number with the integer portion in the 9 | * high word and the fraction in the low word. 10 | * 11 | * There should be an assembler version of this routine 12 | * for each architecture. This one is intended to 13 | * make ports easier. 14 | * 15 | * ignored r0 = lo(a0*b0) 16 | * lsw of result r1 = hi(a0*b0) +lo(a0*b1) +lo(a1*b0) 17 | * msw of result r2 = hi(a0*b1) +hi(a1*b0) +lo(a1*b1) 18 | * ignored r3 = hi(a1*b1) 19 | */ 20 | 21 | void 22 | mul64fract(uvlong *r, uvlong a, uvlong b) 23 | { 24 | uvlong bh, bl; 25 | uvlong ah, al; 26 | uvlong res; 27 | 28 | bl = b & 0xffffffffULL; 29 | bh = b >> 32; 30 | al = a & 0xffffffffULL; 31 | ah = a >> 32; 32 | 33 | res = (al*bl)>>32; 34 | res += (al*bh); 35 | res += (ah*bl); 36 | res += (ah*bh)<<32; 37 | 38 | *r = res; 39 | } 40 | -------------------------------------------------------------------------------- /sys/src/nix/port/initcode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * IMPORTANT! DO NOT ADD LIBRARY CALLS TO THIS FILE. 3 | * The entire text image must fit on one page 4 | * (and there's no data segment, so any read/write data must be on the stack). 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | char cons[] = "#c/cons"; 11 | char boot[] = "/boot/boot"; 12 | char dev[] = "/dev"; 13 | char c[] = "#c"; 14 | char e[] = "#e"; 15 | char ec[] = "#ec"; 16 | char s[] = "#s"; 17 | char srv[] = "/srv"; 18 | char env[] = "/env"; 19 | 20 | void 21 | startboot(char *argv0, char **argv) 22 | { 23 | char buf[200]; 24 | 25 | USED(argv0); 26 | /* 27 | * open the console here so that /boot/boot, 28 | * which could be a shell script, can inherit the open fds. 29 | */ 30 | open(cons, OREAD); 31 | open(cons, OWRITE); 32 | open(cons, OWRITE); 33 | bind(c, dev, MAFTER); 34 | bind(ec, env, MAFTER); 35 | bind(e, env, MCREATE|MAFTER); 36 | bind(s, srv, MREPL|MCREATE); 37 | exec(boot, argv); 38 | 39 | rerrstr(buf, sizeof buf); 40 | buf[sizeof buf - 1] = '\0'; 41 | _exits(buf); 42 | } 43 | -------------------------------------------------------------------------------- /sys/src/nix/k10/l64fpu.s: -------------------------------------------------------------------------------- 1 | /* 2 | * SIMD Floating Point. 3 | * Note: for x87 instructions which have both a 'wait' and 'nowait' version, 4 | * 8a only knows the 'wait' mnemonic but does NOT insertthe WAIT prefix byte 5 | * (i.e. they act like their FNxxx variations) so WAIT instructions must be 6 | * explicitly placed in the code if necessary. 7 | */ 8 | TEXT _clts(SB), 1, $-4 9 | CLTS 10 | RET 11 | 12 | TEXT _fldcw(SB), 1, $-4 /* Load x87 FPU Control Word */ 13 | MOVQ RARG, cw+0(FP) 14 | FLDCW cw+0(FP) 15 | RET 16 | 17 | TEXT _fnclex(SB), 1, $-4 18 | FCLEX 19 | RET 20 | 21 | TEXT _fninit(SB), 1, $-4 22 | FINIT /* no WAIT */ 23 | RET 24 | 25 | TEXT _fxrstor(SB), 1, $-4 26 | FXRSTOR64 (RARG) 27 | RET 28 | 29 | TEXT _fxsave(SB), 1, $-4 30 | FXSAVE64 (RARG) 31 | RET 32 | 33 | TEXT _fwait(SB), 1, $-4 34 | WAIT 35 | RET 36 | 37 | TEXT _ldmxcsr(SB), 1, $-4 /* Load MXCSR */ 38 | MOVQ RARG, mxcsr+0(FP) 39 | LDMXCSR mxcsr+0(FP) 40 | RET 41 | 42 | TEXT _stts(SB), 1, $-4 43 | MOVQ CR0, AX 44 | ORQ $8, AX /* Ts */ 45 | MOVQ AX, CR0 46 | RET 47 | -------------------------------------------------------------------------------- /sys/src/cmd/rc/mkfile: -------------------------------------------------------------------------------- 1 | $test.out 61 | 62 | listing: 63 | pr mkfile $HFILES $FILES $FILES9 $FILESUNIX $YFILES|lp -du 64 | -------------------------------------------------------------------------------- /sys/src/nix/root/rcmain: -------------------------------------------------------------------------------- 1 | # 2 | # rcmain 3 | # Plan 9 initial boot environment version 4 | # 5 | home=/ 6 | ifs=' 7 | ' 8 | prompt=('# ' ' ') 9 | path=(. /bin /boot) 10 | 11 | finit 12 | fn sigexit 13 | fn ps {@{ 14 | cd /proc; 15 | for(i in `{echo [1-9] [1-9][0-9] [1-9][0-9][0-9] [1-9][0-9][0-9][0-9] [1-9][0-9][0-9][0-9][0-9] [1-9][0-9][0-9][0-9][0-9]*|sed 's/\[.*\][ \*]//'}){ 16 | for(f in $i^/status $i^/args) 17 | >[2]/dev/null sed '' $f 18 | }|sed -e '$!N;s/([^ ])$/\1/;ta' -e 'P;D;b' -e ':a;s/\n//' \ 19 | |sed 's/ +/ /g;s/^([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+ +[^ ]+ +[^ ]+ +[^ ]+ +[^ ]+ +[^ ]+) +([^ ]+)+ ([^ ]+ +[^ ]+)(.*)/\2 '^$i^' \5K \3 \1 \7/' 20 | }} 21 | fn netstat {@{ 22 | for(p in tcp udp){ 23 | cd /net/$p; 24 | for(i in `{echo [0-9] [1-9][0-9] [1-9][0-9][0-9] [1-9][0-9][0-9]*|sed 's/\[.*\][ \*]//'}){ 25 | echo -n $p' '$i' *owner* '; 26 | cat $i/status $i/local $i/remote \ 27 | | sed -n -e :a -e '$!N; s/ .*//; s/!/ /; s/\n/ /; ta; 28 | s/([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+)/\1 \3 \5 \4/p' 29 | } 30 | } 31 | }} 32 | 33 | status='' 34 | if(! ~ $#* 0) . $* 35 | . -i '#d/0' 36 | exit $status 37 | -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/kfs.h: -------------------------------------------------------------------------------- 1 | typedef struct Qid9p1 Qid9p1; 2 | typedef struct Dentry Dentry; 3 | typedef struct Kfsfile Kfsfile; 4 | typedef struct Kfs Kfs; 5 | 6 | /* DONT TOUCH, this is the disk structure */ 7 | struct Qid9p1 8 | { 9 | long path; 10 | long version; 11 | }; 12 | 13 | //#define NAMELEN 28 /* size of names */ 14 | #define NDBLOCK 6 /* number of direct blocks in Dentry */ 15 | 16 | /* DONT TOUCH, this is the disk structure */ 17 | struct Dentry 18 | { 19 | char name[NAMELEN]; 20 | short uid; 21 | short gid; 22 | ushort mode; 23 | /* 24 | #define DALLOC 0x8000 25 | #define DDIR 0x4000 26 | #define DAPND 0x2000 27 | #define DLOCK 0x1000 28 | #define DREAD 0x4 29 | #define DWRITE 0x2 30 | #define DEXEC 0x1 31 | */ 32 | Qid9p1 qid; 33 | long size; 34 | long dblock[NDBLOCK]; 35 | long iblock; 36 | long diblock; 37 | long atime; 38 | long mtime; 39 | }; 40 | 41 | struct Kfsfile 42 | { 43 | Dentry; 44 | long off; 45 | }; 46 | 47 | struct Kfs 48 | { 49 | int RBUFSIZE; 50 | int BUFSIZE; 51 | int DIRPERBUF; 52 | int INDPERBUF; 53 | int INDPERBUF2; 54 | }; 55 | 56 | extern int kfsinit(Fs*); 57 | 58 | -------------------------------------------------------------------------------- /sys/src/nix/boot/nopsession.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "../boot/boot.h" 6 | 7 | static Fcall hdr; 8 | 9 | static void 10 | rpc(int fd, int type) 11 | { 12 | int n, l; 13 | uchar buf[128], *p; 14 | 15 | hdr.type = type; 16 | hdr.tag = NOTAG; 17 | n = convS2M(&hdr, buf, sizeof(buf)); 18 | if(write(fd, buf, n) != n) 19 | fatal("write rpc"); 20 | 21 | print("..."); 22 | p = buf; 23 | l = 0; 24 | while(l < 3) { 25 | n = read(fd, p, 3); 26 | if(n <= 0) 27 | fatal("read rpc"); 28 | if(n == 2 && l == 0 && buf[0] == 'O' && buf[1] == 'K') 29 | continue; 30 | p += n; 31 | l += n; 32 | } 33 | if(convM2S(buf, n, &hdr) == 0){ 34 | print("%ux %ux %ux\n", buf[0], buf[1], buf[2]); 35 | fatal("rpc format"); 36 | } 37 | if(hdr.tag != NOTAG) 38 | fatal("rpc tag not NOTAG"); 39 | if(hdr.type == Rerror){ 40 | print("error %s;", hdr.ename); 41 | fatal("remote error"); 42 | } 43 | if(hdr.type != type+1) 44 | fatal("not reply"); 45 | } 46 | 47 | void 48 | nop(int fd) 49 | { 50 | print("nop"); 51 | /*rpc(fd, Tnop);*/ /* PAL: DANGER - stubbing? */ 52 | } 53 | -------------------------------------------------------------------------------- /sys/src/nix/mk/mkenum: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | 3 | awk ' 4 | BEGIN{ 5 | oargc = 0; 6 | for(argc = 1; argc < ARGC; argc++){ 7 | if(ARGV[argc] !~ /^-.+/ || ARGV[argc] ~ /--/) 8 | break; 9 | if(ARGV[argc] != "-D") 10 | oargv[ARGV[argc]] = oargc++; 11 | else 12 | DEBUG = 1; 13 | ARGV[argc] = ""; 14 | } 15 | } 16 | 17 | /^enum([ \t]*{|$)/{ 18 | inenum = 1; 19 | if(DEBUG) 20 | printf "inenum = 1\n"; 21 | next; 22 | } 23 | 24 | inenum && /^};$/{ 25 | if(DEBUG) 26 | printf "inenum = 0\n"; 27 | inenum = 0; 28 | } 29 | 30 | inenum && $0 ~ /^[ \t]+[_A-Za-z][_0-9A-Za-z]+[ \t]+=[ \t]+[0-9A-Z_a-z()<> ]+,/{ 31 | tab = "\t"; 32 | if(length($1) < 8) 33 | sep = tab tab; 34 | else 35 | sep = tab; 36 | split($3, a, ","); 37 | printf "#define %s%s%s", $1, sep, a[1]; 38 | if(match($0, /\/\*.*\*\/$/)){ 39 | len = length(a[1]); 40 | sep = ""; 41 | while(len < 24){ 42 | sep = sep tab; 43 | len += 8; 44 | } 45 | printf "%s%s", sep, substr($0, RSTART); 46 | } 47 | printf "\n" 48 | } 49 | 50 | !inenum && /^#(define|include) /{ 51 | printf "%s\n", $0; 52 | } 53 | 54 | /^$/{ 55 | printf "\n"; 56 | } 57 | 58 | END{ 59 | }' $* 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2021 Plan 9 Foundation 2 | Copyright © 2011 NIX Contributors 3 | Copyright © 20XX 9front authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/print.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | 7 | static int spinning; 8 | static char* wheel[4] = { "\b|", "\b/", "\b-", "\b\\", }; 9 | static int spoke; 10 | 11 | void 12 | startwheel(void) 13 | { 14 | spoke = 1; 15 | consputs("|", 1); 16 | spinning = 1; 17 | } 18 | 19 | void 20 | turnwheel(int dir) 21 | { 22 | if(!spinning) 23 | return; 24 | spoke += dir; 25 | consputs(wheel[spoke & 3], 2); 26 | } 27 | 28 | void 29 | stopwheel(void) 30 | { 31 | consputs("\b", 1); 32 | spinning = 0; 33 | } 34 | 35 | int 36 | print(char* fmt, ...) 37 | { 38 | va_list arg; 39 | char buf[PRINTSIZE], *e, *p; 40 | 41 | p = buf; 42 | if(spinning) 43 | *p++ = '\b'; 44 | 45 | va_start(arg, fmt); 46 | e = vseprint(p, buf+sizeof(buf), fmt, arg); 47 | va_end(arg); 48 | 49 | if(spinning && e < &buf[PRINTSIZE-2]){ 50 | *e++ = ' '; 51 | *e = 0; 52 | } 53 | consputs(buf, e-buf); 54 | 55 | return e-buf; 56 | } 57 | 58 | static Lock fmtl; 59 | 60 | void 61 | _fmtlock(void) 62 | { 63 | lock(&fmtl); 64 | } 65 | 66 | void 67 | _fmtunlock(void) 68 | { 69 | unlock(&fmtl); 70 | } 71 | 72 | int 73 | _efgfmt(Fmt*) 74 | { 75 | return -1; 76 | } 77 | -------------------------------------------------------------------------------- /sys/src/nix/port/aoe.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ATA-over-Ethernet (AoE) protocol 3 | */ 4 | enum { 5 | ACata, 6 | ACconfig, 7 | }; 8 | 9 | enum { 10 | AQCread, 11 | AQCtest, 12 | AQCprefix, 13 | AQCset, 14 | AQCfset, 15 | }; 16 | 17 | enum { 18 | AEcmd = 1, 19 | AEarg, 20 | AEdev, 21 | AEcfg, 22 | AEver, 23 | }; 24 | 25 | enum { 26 | Aoetype = 0x88a2, 27 | Aoesectsz = 512, /* standard sector size */ 28 | Aoever = 1, 29 | 30 | AFerr = 1<<2, 31 | AFrsp = 1<<3, 32 | 33 | AAFwrite= 1, 34 | AAFext = 1<<6, 35 | }; 36 | 37 | typedef struct { 38 | uchar dst[Eaddrlen]; 39 | uchar src[Eaddrlen]; 40 | uchar type[2]; 41 | uchar verflag; 42 | uchar error; 43 | uchar major[2]; 44 | uchar minor; 45 | uchar cmd; 46 | uchar tag[4]; 47 | uchar payload[]; 48 | } Aoehdr; 49 | 50 | #define AOEHDRSZ offsetof(Aoehdr, payload[0]) 51 | 52 | typedef struct { 53 | Aoehdr; 54 | uchar aflag; 55 | uchar errfeat; 56 | uchar scnt; 57 | uchar cmdstat; 58 | uchar lba[6]; 59 | uchar res[2]; 60 | uchar payload[]; 61 | } Aoeata; 62 | 63 | #define AOEATASZ offsetof(Aoeata, payload[0]) 64 | 65 | typedef struct { 66 | Aoehdr; 67 | uchar bufcnt[2]; 68 | uchar fwver[2]; 69 | uchar scnt; 70 | uchar verccmd; 71 | uchar cslen[2]; 72 | uchar payload[]; 73 | } Aoeqc; 74 | 75 | #define AOEQCSZ offsetof(Aoeqc, payload[0]) 76 | 77 | extern char Echange[]; 78 | extern char Enotup[]; 79 | -------------------------------------------------------------------------------- /sys/include/tos.h: -------------------------------------------------------------------------------- 1 | typedef struct Callq Callq; 2 | typedef struct Nixcall Nixcall; 3 | typedef struct Nixret Nixret; 4 | typedef struct Plink Plink; 5 | typedef struct Tos Tos; 6 | 7 | #pragma incomplete Plink 8 | 9 | #define CALLQSZ 512 10 | 11 | struct Nixcall 12 | { 13 | void* tag; 14 | int scall; 15 | va_list sarg; 16 | }; 17 | 18 | struct Nixret 19 | { 20 | void* tag; 21 | int sret; 22 | char* err; 23 | }; 24 | 25 | struct Callq 26 | { 27 | int ksleep; 28 | unsigned int qr; /* don't use uint for ape */ 29 | unsigned int qw; 30 | unsigned int rr; 31 | unsigned int rw; 32 | Nixcall q[CALLQSZ]; 33 | Nixret r[CALLQSZ]; 34 | }; 35 | 36 | struct Tos 37 | { 38 | struct /* Per process profiling */ 39 | { 40 | Plink *pp; /* known to be 0(ptr) */ 41 | Plink *next; /* known to be 4(ptr) */ 42 | Plink *last; 43 | Plink *first; 44 | ulong pid; 45 | ulong what; 46 | } prof; 47 | uvlong cyclefreq; /* cycle clock frequency if there is one, 0 otherwise */ 48 | vlong kcycles; /* cycles spent in kernel */ 49 | vlong pcycles; /* cycles spent in process (kernel + user) */ 50 | ulong pid; /* might as well put the pid here */ 51 | ulong clock; 52 | 53 | int nixtype; /* role of the core we are running at */ 54 | int core; /* core we are running at */ 55 | Callq callq; /* NIX queue based system calls */ 56 | /* top of stack is here */ 57 | }; 58 | 59 | extern Tos *_tos; 60 | -------------------------------------------------------------------------------- /sys/src/libc/9syscall/sys.h: -------------------------------------------------------------------------------- 1 | #define SYSR1 0 2 | #define _ERRSTR 1 3 | #define BIND 2 4 | #define CHDIR 3 5 | #define CLOSE 4 6 | #define DUP 5 7 | #define ALARM 6 8 | #define EXEC 7 9 | #define EXITS 8 10 | #define _FSESSION 9 11 | #define FAUTH 10 12 | #define _FSTAT 11 13 | #define SEGBRK 12 14 | #define _MOUNT 13 15 | #define OPEN 14 16 | #define _READ 15 17 | #define OSEEK 16 18 | #define SLEEP 17 19 | #define _STAT 18 20 | #define RFORK 19 21 | #define _WRITE 20 22 | #define PIPE 21 23 | #define CREATE 22 24 | #define FD2PATH 23 25 | #define BRK_ 24 26 | #define REMOVE 25 27 | #define _WSTAT 26 28 | #define _FWSTAT 27 29 | #define NOTIFY 28 30 | #define NOTED 29 31 | #define SEGATTACH 30 32 | #define SEGDETACH 31 33 | #define SEGFREE 32 34 | #define SEGFLUSH 33 35 | #define RENDEZVOUS 34 36 | #define UNMOUNT 35 37 | #define _WAIT 36 38 | #define SEMACQUIRE 37 39 | #define SEMRELEASE 38 40 | #define SEEK 39 41 | #define FVERSION 40 42 | #define ERRSTR 41 43 | #define STAT 42 44 | #define FSTAT 43 45 | #define WSTAT 44 46 | #define FWSTAT 45 47 | #define MOUNT 46 48 | #define AWAIT 47 49 | #define PREAD 50 50 | #define PWRITE 51 51 | #define SEMSLEEP 52 52 | #define SEMWAKEUP 53 53 | #define SEMALT 54 54 | #define EXECAC 55 55 | #define NIXSYSCALL 56 56 | #define ZIOPREAD 57 57 | #define ZIOPWRITE 58 58 | #define ZIOFREE 59 59 | #define TSEMACQUIRE 60 60 | -------------------------------------------------------------------------------- /sys/src/nix/boot/paq.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include <../boot/boot.h> 4 | 5 | char *fparts[] = 6 | { 7 | "add bootldr 0x0000000 0x0040000", 8 | "add params 0x0040000 0x0080000", 9 | "add kernel 0x0080000 0x0140000", 10 | "add user 0x0140000 0x0200000", 11 | "add ramdisk 0x0200000 0x0600000", 12 | }; 13 | 14 | void 15 | configpaq(Method*) 16 | { 17 | int fd; 18 | int i; 19 | 20 | if(bind("#F", "/dev", MAFTER) < 0) 21 | fatal("bind #c"); 22 | if(bind("#p", "/proc", MREPL) < 0) 23 | fatal("bind #p"); 24 | fd = open("/dev/flash/flashctl", OWRITE); 25 | if(fd < 0) 26 | fatal("opening flashctl"); 27 | for(i = 0; i < nelem(fparts); i++) 28 | if(fprint(fd, fparts[i]) < 0) 29 | fatal(fparts[i]); 30 | close(fd); 31 | } 32 | 33 | int 34 | connectpaq(void) 35 | { 36 | int p[2]; 37 | char **arg, **argp; 38 | 39 | print("paq..."); 40 | if(pipe(p)<0) 41 | fatal("pipe"); 42 | switch(fork()){ 43 | case -1: 44 | fatal("fork"); 45 | case 0: 46 | arg = malloc(10*sizeof(char*)); 47 | argp = arg; 48 | *argp++ = "paqfs"; 49 | *argp++ = "-v"; 50 | *argp++ = "-i"; 51 | *argp++ = "/dev/flash/ramdisk"; 52 | *argp = 0; 53 | 54 | dup(p[0], 0); 55 | dup(p[1], 1); 56 | close(p[0]); 57 | close(p[1]); 58 | exec("/boot/paqfs", arg); 59 | fatal("can't exec paqfs"); 60 | default: 61 | break; 62 | } 63 | waitpid(); 64 | 65 | close(p[1]); 66 | return p[0]; 67 | } 68 | -------------------------------------------------------------------------------- /sys/src/nix/k10/etherif.h: -------------------------------------------------------------------------------- 1 | enum 2 | { 3 | Eaddrlen = 6, 4 | ETHERMINTU = 60, /* minimum transmit size */ 5 | ETHERMAXTU = 1514, /* maximum transmit size */ 6 | ETHERHDRSIZE = 14, /* size of an ethernet header */ 7 | 8 | MaxEther = 48, 9 | Ntypes = 8, 10 | }; 11 | 12 | typedef struct Ether Ether; 13 | struct Ether { 14 | ISAConf; /* hardware info */ 15 | 16 | int ctlrno; 17 | int tbdf; /* type+busno+devno+funcno */ 18 | uchar ea[Eaddrlen]; 19 | 20 | void (*attach)(Ether*); /* filled in by reset routine */ 21 | void (*detach)(Ether*); 22 | void (*transmit)(Ether*); 23 | void (*interrupt)(Ureg*, void*); 24 | long (*ifstat)(Ether*, void*, long, ulong); 25 | long (*ctl)(Ether*, void*, long); /* custom ctl messages */ 26 | void (*power)(Ether*, int); /* power on/off */ 27 | void (*shutdown)(Ether*); /* shutdown hardware before reboot */ 28 | void *ctlr; 29 | 30 | int scan[Ntypes]; /* base station scanning interval */ 31 | int nscan; /* number of base station scanners */ 32 | 33 | Netif; 34 | }; 35 | 36 | typedef struct Etherpkt Etherpkt; 37 | struct Etherpkt 38 | { 39 | uchar d[Eaddrlen]; 40 | uchar s[Eaddrlen]; 41 | uchar type[2]; 42 | uchar data[1500]; 43 | }; 44 | 45 | extern Block* etheriq(Ether*, Block*, int); 46 | extern void addethercard(char*, int(*)(Ether*)); 47 | extern ulong ethercrc(uchar*, int); 48 | extern int parseether(uchar*, char*); 49 | 50 | #define NEXT(x, l) (((x)+1)%(l)) 51 | #define PREV(x, l) (((x) == 0) ? (l)-1: (x)-1) 52 | -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/etherif.h: -------------------------------------------------------------------------------- 1 | typedef struct RingBuf { 2 | uchar owner; 3 | uchar unused; 4 | ushort len; 5 | uchar pkt[sizeof(Etherpkt)]; 6 | } RingBuf; 7 | 8 | enum { 9 | Host = 0, /* buffer owned by host */ 10 | Interface = 1, /* buffer owned by card */ 11 | 12 | Nrb = 32, /* default number of receive buffers */ 13 | Ntb = 8, /* default number of transmit buffers */ 14 | }; 15 | 16 | typedef struct Ether Ether; 17 | struct Ether { 18 | ISAConf; /* hardware info */ 19 | int ctlrno; 20 | int state; 21 | int tbdf; 22 | 23 | void (*attach)(Ether*); /* filled in by reset routine */ 24 | void (*transmit)(Ether*); 25 | void (*interrupt)(Ureg*, void*); 26 | void (*detach)(Ether*); 27 | void *ctlr; 28 | 29 | ushort nrb; /* number of software receive buffers */ 30 | ushort ntb; /* number of software transmit buffers */ 31 | RingBuf *rb; /* software receive buffers */ 32 | RingBuf *tb; /* software transmit buffers */ 33 | 34 | ushort rh; /* first receive buffer belonging to host */ 35 | ushort ri; /* first receive buffer belonging to card */ 36 | 37 | ushort th; /* first transmit buffer belonging to host */ 38 | ushort ti; /* first transmit buffer belonging to card */ 39 | int tbusy; /* transmitter is busy */ 40 | 41 | Netif; 42 | }; 43 | 44 | extern void etherrloop(Ether*, Etherpkt*, long); 45 | extern void addethercard(char*, int(*)(Ether*)); 46 | 47 | #define NEXT(x, l) (((x)+1)%(l)) 48 | #define PREV(x, l) (((x) == 0) ? (l)-1: (x)-1) 49 | -------------------------------------------------------------------------------- /sys/src/nix/boot/bootauth.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "../boot/boot.h" 6 | 7 | char *authaddr; 8 | static void glenda(void); 9 | 10 | void 11 | authentication(int cpuflag) 12 | { 13 | char *argv[16], **av; 14 | int ac; 15 | 16 | if(access("/boot/factotum", AEXEC) < 0){ 17 | glenda(); 18 | return; 19 | } 20 | 21 | /* start agent */ 22 | ac = 0; 23 | av = argv; 24 | av[ac++] = "factotum"; 25 | if(getenv("debugfactotum")) 26 | av[ac++] = "-p"; 27 | // av[ac++] = "-d"; /* debug traces */ 28 | // av[ac++] = "-D"; /* 9p messages */ 29 | if(cpuflag) 30 | av[ac++] = "-S"; 31 | else 32 | av[ac++] = "-u"; 33 | av[ac++] = "-sfactotum"; 34 | if(authaddr != nil){ 35 | av[ac++] = "-a"; 36 | av[ac++] = authaddr; 37 | } 38 | av[ac] = 0; 39 | switch(fork()){ 40 | case -1: 41 | fatal("starting factotum"); 42 | case 0: 43 | exec("/boot/factotum", av); 44 | fatal("execing /boot/factotum"); 45 | default: 46 | break; 47 | } 48 | 49 | /* wait for agent to really be there */ 50 | while(access("/mnt/factotum", 0) < 0) 51 | sleep(250); 52 | 53 | if(cpuflag) 54 | return; 55 | } 56 | 57 | static void 58 | glenda(void) 59 | { 60 | int fd; 61 | char *s; 62 | 63 | s = getenv("user"); 64 | if(s == nil) 65 | s = "glenda"; 66 | 67 | fd = open("#c/hostowner", OWRITE); 68 | if(fd >= 0){ 69 | if(write(fd, s, strlen(s)) != strlen(s)) 70 | fprint(2, "setting #c/hostowner to %s: %r\n", s); 71 | close(fd); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /sys/src/nix/port/edf.h: -------------------------------------------------------------------------------- 1 | enum { 2 | Maxsteps = 200 * 100 * 2, /* 100 periods of 200 procs */ 3 | 4 | /* Edf.flags field */ 5 | Admitted = 0x01, 6 | Sporadic = 0x02, 7 | Yieldonblock = 0x04, 8 | Sendnotes = 0x08, 9 | Deadline = 0x10, 10 | Yield = 0x20, 11 | Extratime = 0x40, 12 | 13 | Infinity = ~0ULL, 14 | }; 15 | 16 | typedef struct Edf Edf; 17 | 18 | struct Edf { 19 | /* All times in µs */ 20 | /* time intervals */ 21 | long D; /* Deadline */ 22 | long Delta; /* Inherited deadline */ 23 | long T; /* period */ 24 | long C; /* Cost */ 25 | long S; /* Slice: time remaining in this period */ 26 | /* times (only low-order bits of absolute time) */ 27 | long r; /* (this) release time */ 28 | long d; /* (this) deadline */ 29 | long t; /* Start of next period, t += T at release */ 30 | long s; /* Time at which this proc was last scheduled */ 31 | /* for schedulability testing */ 32 | long testDelta; 33 | int testtype; /* Release or Deadline */ 34 | long testtime; 35 | Proc *testnext; 36 | /* other */ 37 | ushort flags; 38 | Timer; 39 | /* Stats */ 40 | long edfused; 41 | long extraused; 42 | long aged; 43 | ulong periods; 44 | ulong missed; 45 | }; 46 | 47 | extern Lock edftestlock; /* for atomic admitting/expelling */ 48 | 49 | #pragma varargck type "t" long 50 | #pragma varargck type "U" uvlong 51 | 52 | /* Interface: */ 53 | Edf* edflock(Proc*); 54 | void edfunlock(void); 55 | 56 | 57 | /* sched interface, used only by edf */ 58 | Sched* procsched(Proc*); 59 | -------------------------------------------------------------------------------- /sys/src/nix/boot/embed.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include <../boot/boot.h> 4 | 5 | static char *paqfile; 6 | 7 | void 8 | configembed(Method *m) 9 | { 10 | if(*sys == '/' || *sys == '#'){ 11 | /* 12 | * if the user specifies the disk in the boot cmd or 13 | * 'root is from' prompt, use it 14 | */ 15 | paqfile = sys; 16 | } else if(m->arg){ 17 | /* 18 | * a default is supplied when the kernel is made 19 | */ 20 | paqfile = m->arg; 21 | } 22 | } 23 | 24 | int 25 | connectembed(void) 26 | { 27 | int i, p[2]; 28 | Dir *dir; 29 | char **arg, **argp; 30 | 31 | dir = dirstat("/boot/paqfs"); 32 | if(dir == nil) 33 | return -1; 34 | free(dir); 35 | 36 | dir = dirstat(paqfile); 37 | if(dir == nil || dir->mode & DMDIR) 38 | return -1; 39 | free(dir); 40 | 41 | print("paqfs..."); 42 | if(bind("#c", "/dev", MREPL) < 0) 43 | fatal("bind #c"); 44 | if(bind("#p", "/proc", MREPL) < 0) 45 | fatal("bind #p"); 46 | if(pipe(p)<0) 47 | fatal("pipe"); 48 | switch(fork()){ 49 | case -1: 50 | fatal("fork"); 51 | case 0: 52 | arg = malloc((bargc+5)*sizeof(char*)); 53 | argp = arg; 54 | *argp++ = "/boot/paqfs"; 55 | *argp++ = "-iv"; 56 | *argp++ = paqfile; 57 | for(i=1; ireset(); 20 | } 21 | 22 | void 23 | devtabinit(void) 24 | { 25 | int i; 26 | 27 | for(i = 0; devtab[i] != nil; i++) 28 | devtab[i]->init(); 29 | } 30 | 31 | void 32 | devtabshutdown(void) 33 | { 34 | int i; 35 | 36 | /* 37 | * Shutdown in reverse order. 38 | */ 39 | for(i = 0; devtab[i] != nil; i++) 40 | ; 41 | for(i--; i >= 0; i--) 42 | devtab[i]->shutdown(); 43 | } 44 | 45 | 46 | Dev* 47 | devtabget(int dc, int user) 48 | { 49 | int i; 50 | 51 | for(i = 0; devtab[i] != nil; i++){ 52 | if(devtab[i]->dc == dc) 53 | return devtab[i]; 54 | } 55 | 56 | if(user == 0) 57 | panic("devtabget %C\n", dc); 58 | 59 | return nil; 60 | } 61 | 62 | long 63 | devtabread(Chan*, void* buf, long n, vlong off) 64 | { 65 | int i; 66 | Dev *dev; 67 | char *alloc, *e, *p; 68 | 69 | alloc = malloc(READSTR); 70 | if(alloc == nil) 71 | error(Enomem); 72 | 73 | p = alloc; 74 | e = p + READSTR; 75 | for(i = 0; devtab[i] != nil; i++){ 76 | dev = devtab[i]; 77 | p = seprint(p, e, "#%C %s\n", dev->dc, dev->name); 78 | } 79 | 80 | if(waserror()){ 81 | free(alloc); 82 | nexterror(); 83 | } 84 | n = readstr(off, buf, n, alloc); 85 | free(alloc); 86 | poperror(); 87 | 88 | return n; 89 | } 90 | -------------------------------------------------------------------------------- /sys/src/cmd/rc/subr.c: -------------------------------------------------------------------------------- 1 | #include "rc.h" 2 | #include "exec.h" 3 | #include "io.h" 4 | #include "fns.h" 5 | 6 | void * 7 | emalloc(long n) 8 | { 9 | void *p = Malloc(n); 10 | 11 | if(p==0) 12 | panic("Can't malloc %d bytes", n); 13 | /* if(err){ pfmt(err, "malloc %d->%p\n", n, p); flush(err); } /**/ 14 | return p; 15 | } 16 | 17 | void 18 | efree(void *p) 19 | { 20 | /* pfmt(err, "free %p\n", p); flush(err); /**/ 21 | if(p) 22 | free(p); 23 | else pfmt(err, "free 0\n"); 24 | } 25 | extern int lastword, lastdol; 26 | 27 | void 28 | yyerror(char *m) 29 | { 30 | pfmt(err, "rc: "); 31 | if(runq->cmdfile && !runq->iflag) 32 | pfmt(err, "%s:%d: ", runq->cmdfile, runq->lineno); 33 | else if(runq->cmdfile) 34 | pfmt(err, "%s: ", runq->cmdfile); 35 | else if(!runq->iflag) 36 | pfmt(err, "line %d: ", runq->lineno); 37 | if(tok[0] && tok[0]!='\n') 38 | pfmt(err, "token %q: ", tok); 39 | pfmt(err, "%s\n", m); 40 | flush(err); 41 | lastword = 0; 42 | lastdol = 0; 43 | while(lastc!='\n' && lastc!=EOF) advance(); 44 | nerror++; 45 | setvar("status", newword(m, (word *)0)); 46 | } 47 | char *bp; 48 | 49 | static void 50 | iacvt(int n) 51 | { 52 | if(n<0){ 53 | *bp++='-'; 54 | n=-n; /* doesn't work for n==-inf */ 55 | } 56 | if(n/10) 57 | iacvt(n/10); 58 | *bp++=n%10+'0'; 59 | } 60 | 61 | void 62 | inttoascii(char *s, long n) 63 | { 64 | bp = s; 65 | iacvt(n); 66 | *bp='\0'; 67 | } 68 | 69 | void 70 | panic(char *s, int n) 71 | { 72 | pfmt(err, "rc: "); 73 | pfmt(err, s, n); 74 | pchr(err, '\n'); 75 | flush(err); 76 | Abort(); 77 | } 78 | -------------------------------------------------------------------------------- /sys/src/nix/ip/ptclbsum.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "../port/error.h" 7 | #include "ip.h" 8 | 9 | static short endian = 1; 10 | static uchar* aendian = (uchar*)&endian; 11 | #define LITTLE *aendian 12 | 13 | ushort 14 | ptclbsum(uchar *addr, int len) 15 | { 16 | ulong losum, hisum, mdsum, x; 17 | ulong t1, t2; 18 | 19 | losum = 0; 20 | hisum = 0; 21 | mdsum = 0; 22 | 23 | x = 0; 24 | if(PTR2UINT(addr) & 1) { 25 | if(len) { 26 | hisum += addr[0]; 27 | len--; 28 | addr++; 29 | } 30 | x = 1; 31 | } 32 | while(len >= 16) { 33 | t1 = *(ushort*)(addr+0); 34 | t2 = *(ushort*)(addr+2); mdsum += t1; 35 | t1 = *(ushort*)(addr+4); mdsum += t2; 36 | t2 = *(ushort*)(addr+6); mdsum += t1; 37 | t1 = *(ushort*)(addr+8); mdsum += t2; 38 | t2 = *(ushort*)(addr+10); mdsum += t1; 39 | t1 = *(ushort*)(addr+12); mdsum += t2; 40 | t2 = *(ushort*)(addr+14); mdsum += t1; 41 | mdsum += t2; 42 | len -= 16; 43 | addr += 16; 44 | } 45 | while(len >= 2) { 46 | mdsum += *(ushort*)addr; 47 | len -= 2; 48 | addr += 2; 49 | } 50 | if(x) { 51 | if(len) 52 | losum += addr[0]; 53 | if(LITTLE) 54 | losum += mdsum; 55 | else 56 | hisum += mdsum; 57 | } else { 58 | if(len) 59 | hisum += addr[0]; 60 | if(LITTLE) 61 | hisum += mdsum; 62 | else 63 | losum += mdsum; 64 | } 65 | 66 | losum += hisum >> 8; 67 | losum += (hisum & 0xff) << 8; 68 | while(hisum = losum>>16) 69 | losum = hisum + (losum & 0xffff); 70 | 71 | return losum & 0xffff; 72 | } 73 | -------------------------------------------------------------------------------- /sys/src/cmd/rc/pfnc.c: -------------------------------------------------------------------------------- 1 | #include "rc.h" 2 | #include "exec.h" 3 | #include "io.h" 4 | #include "fns.h" 5 | struct{ 6 | void (*f)(void); 7 | char *name; 8 | }fname[] = { 9 | Xappend, "Xappend", 10 | Xasync, "Xasync", 11 | Xbang, "Xbang", 12 | Xclose, "Xclose", 13 | Xdup, "Xdup", 14 | Xeflag, "Xeflag", 15 | Xexit, "Xexit", 16 | Xfalse, "Xfalse", 17 | Xifnot, "Xifnot", 18 | Xjump, "Xjump", 19 | Xmark, "Xmark", 20 | Xpopm, "Xpopm", 21 | Xrdwr, "Xrdwr", 22 | Xread, "Xread", 23 | Xreturn, "Xreturn", 24 | Xtrue, "Xtrue", 25 | Xif, "Xif", 26 | Xwastrue, "Xwastrue", 27 | Xword, "Xword", 28 | Xwrite, "Xwrite", 29 | Xmatch, "Xmatch", 30 | Xcase, "Xcase", 31 | Xconc, "Xconc", 32 | Xassign, "Xassign", 33 | Xdol, "Xdol", 34 | Xcount, "Xcount", 35 | Xlocal, "Xlocal", 36 | Xunlocal, "Xunlocal", 37 | Xfn, "Xfn", 38 | Xdelfn, "Xdelfn", 39 | Xpipe, "Xpipe", 40 | Xpipewait, "Xpipewait", 41 | Xrdcmds, "Xrdcmds", 42 | (void (*)(void))Xerror, "Xerror", 43 | Xbackq, "Xbackq", 44 | Xpipefd, "Xpipefd", 45 | Xsubshell, "Xsubshell", 46 | Xdelhere, "Xdelhere", 47 | Xfor, "Xfor", 48 | Xglob, "Xglob", 49 | Xrdfn, "Xrdfn", 50 | Xsimple, "Xsimple", 51 | Xsub, "Xsub", 52 | Xqdol, "Xqdol", 53 | 0}; 54 | 55 | void 56 | pfnc(io *fd, thread *t) 57 | { 58 | int i; 59 | void (*fn)(void) = t->code[t->pc].f; 60 | list *a; 61 | pfmt(fd, "pid %d cycle %p %d ", getpid(), t->code, t->pc); 62 | for(i = 0;fname[i].f;i++) if(fname[i].f==fn){ 63 | pstr(fd, fname[i].name); 64 | break; 65 | } 66 | if(!fname[i].f) 67 | pfmt(fd, "%p", fn); 68 | for(a = t->argv;a;a = a->next) pfmt(fd, " (%v)", a->words); 69 | pchr(fd, '\n'); 70 | flush(fd); 71 | } 72 | -------------------------------------------------------------------------------- /sys/src/nix/ip/pktmedium.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "../port/error.h" 7 | 8 | #include "ip.h" 9 | 10 | 11 | static void pktbind(Ipifc*, int, char**); 12 | static void pktunbind(Ipifc*); 13 | static void pktbwrite(Ipifc*, Block*, int, uchar*); 14 | static void pktin(Fs*, Ipifc*, Block*); 15 | 16 | Medium pktmedium = 17 | { 18 | .name= "pkt", 19 | .hsize= 14, 20 | .mintu= 40, 21 | .maxtu= 4*1024, 22 | .maclen= 6, 23 | .bind= pktbind, 24 | .unbind= pktunbind, 25 | .bwrite= pktbwrite, 26 | .pktin= pktin, 27 | .unbindonclose= 1, 28 | }; 29 | 30 | /* 31 | * called to bind an IP ifc to an ethernet device 32 | * called with ifc wlock'd 33 | */ 34 | static void 35 | pktbind(Ipifc*, int, char**) 36 | { 37 | } 38 | 39 | /* 40 | * called with ifc wlock'd 41 | */ 42 | static void 43 | pktunbind(Ipifc*) 44 | { 45 | } 46 | 47 | /* 48 | * called by ipoput with a single packet to write 49 | */ 50 | static void 51 | pktbwrite(Ipifc *ifc, Block *bp, int, uchar*) 52 | { 53 | /* enqueue onto the conversation's rq */ 54 | bp = concatblock(bp); 55 | if(ifc->conv->snoopers.ref > 0) 56 | qpass(ifc->conv->sq, copyblock(bp, BLEN(bp))); 57 | qpass(ifc->conv->rq, bp); 58 | } 59 | 60 | /* 61 | * called with ifc rlocked when someone write's to 'data' 62 | */ 63 | static void 64 | pktin(Fs *f, Ipifc *ifc, Block *bp) 65 | { 66 | if(ifc->lifc == nil) 67 | freeb(bp); 68 | else { 69 | if(ifc->conv->snoopers.ref > 0) 70 | qpass(ifc->conv->sq, copyblock(bp, BLEN(bp))); 71 | ipiput4(f, ifc, bp); 72 | } 73 | } 74 | 75 | void 76 | pktmediumlink(void) 77 | { 78 | addipmedium(&pktmedium); 79 | } 80 | -------------------------------------------------------------------------------- /sys/src/cmd/rc/var.c: -------------------------------------------------------------------------------- 1 | #include "rc.h" 2 | #include "exec.h" 3 | #include "fns.h" 4 | 5 | int 6 | hash(char *s, int n) 7 | { 8 | int h = 0, i = 1; 9 | while(*s) h+=*s++*i++; 10 | h%=n; 11 | return h<0?h+n:h; 12 | } 13 | #define NKW 30 14 | struct kw{ 15 | char *name; 16 | int type; 17 | struct kw *next; 18 | }*kw[NKW]; 19 | 20 | void 21 | kenter(int type, char *name) 22 | { 23 | int h = hash(name, NKW); 24 | struct kw *p = new(struct kw); 25 | p->type = type; 26 | p->name = name; 27 | p->next = kw[h]; 28 | kw[h] = p; 29 | } 30 | 31 | void 32 | kinit(void) 33 | { 34 | kenter(FOR, "for"); 35 | kenter(IN, "in"); 36 | kenter(WHILE, "while"); 37 | kenter(IF, "if"); 38 | kenter(NOT, "not"); 39 | kenter(TWIDDLE, "~"); 40 | kenter(BANG, "!"); 41 | kenter(SUBSHELL, "@"); 42 | kenter(SWITCH, "switch"); 43 | kenter(FN, "fn"); 44 | } 45 | 46 | tree* 47 | klook(char *name) 48 | { 49 | struct kw *p; 50 | tree *t = token(name, WORD); 51 | for(p = kw[hash(name, NKW)];p;p = p->next) 52 | if(strcmp(p->name, name)==0){ 53 | t->type = p->type; 54 | t->iskw = 1; 55 | break; 56 | } 57 | return t; 58 | } 59 | 60 | var* 61 | gvlook(char *name) 62 | { 63 | int h = hash(name, NVAR); 64 | var *v; 65 | for(v = gvar[h];v;v = v->next) if(strcmp(v->name, name)==0) return v; 66 | return gvar[h] = newvar(strdup(name), gvar[h]); 67 | } 68 | 69 | var* 70 | vlook(char *name) 71 | { 72 | var *v; 73 | if(runq) 74 | for(v = runq->local;v;v = v->next) 75 | if(strcmp(v->name, name)==0) return v; 76 | return gvlook(name); 77 | } 78 | 79 | void 80 | setvar(char *name, word *val) 81 | { 82 | struct var *v = vlook(name); 83 | freewords(v->val); 84 | v->val = val; 85 | v->changed = 1; 86 | } 87 | -------------------------------------------------------------------------------- /sys/src/nix/k10/l64syscall.s: -------------------------------------------------------------------------------- 1 | #include "mem.h" 2 | #include "amd64l.h" 3 | 4 | MODE $64 5 | 6 | /* 7 | */ 8 | TEXT touser(SB), 1, $-4 9 | CLI 10 | SWAPGS 11 | MOVQ $SSEL(SiUDS, SsRPL3), AX 12 | MOVW AX, DS 13 | MOVW AX, ES 14 | MOVW AX, FS 15 | MOVW AX, GS 16 | 17 | MOVQ $(UTZERO+0x28), CX /* ip */ 18 | MOVQ $If, R11 /* flags */ 19 | 20 | MOVQ RARG, SP /* sp */ 21 | 22 | BYTE $0x48; SYSRET /* SYSRETQ */ 23 | 24 | /* 25 | */ 26 | TEXT syscallentry(SB), 1, $-4 27 | SWAPGS 28 | BYTE $0x65; MOVQ 0, RMACH /* m-> (MOVQ GS:0x0, R15) */ 29 | MOVQ 16(RMACH), RUSER /* m->proc */ 30 | MOVQ SP, R13 31 | MOVQ 16(RUSER), SP /* m->proc->kstack */ 32 | ADDQ $KSTACK, SP 33 | PUSHQ $SSEL(SiUDS, SsRPL3) /* old stack segment */ 34 | PUSHQ R13 /* old sp */ 35 | PUSHQ R11 /* old flags */ 36 | PUSHQ $SSEL(SiUCS, SsRPL3) /* old code segment */ 37 | PUSHQ CX /* old ip */ 38 | 39 | SUBQ $(18*8), SP /* unsaved registers */ 40 | 41 | MOVW $SSEL(SiUDS, SsRPL3), (15*8+0)(SP) 42 | MOVW ES, (15*8+2)(SP) 43 | MOVW FS, (15*8+4)(SP) 44 | MOVW GS, (15*8+6)(SP) 45 | 46 | PUSHQ SP /* Ureg* */ 47 | PUSHQ RARG /* system call number */ 48 | CALL syscall(SB) 49 | 50 | TEXT syscallreturn(SB), 1, $-4 51 | MOVQ 16(SP), AX /* Ureg.ax */ 52 | MOVQ (16+6*8)(SP), BP /* Ureg.bp */ 53 | _syscallreturn: 54 | ADDQ $(17*8), SP /* registers + arguments */ 55 | 56 | CLI 57 | SWAPGS 58 | MOVW 0(SP), DS 59 | MOVW 2(SP), ES 60 | MOVW 4(SP), FS 61 | MOVW 6(SP), GS 62 | 63 | MOVQ 24(SP), CX /* ip */ 64 | MOVQ 40(SP), R11 /* flags */ 65 | 66 | MOVQ 48(SP), SP /* sp */ 67 | 68 | BYTE $0x48; SYSRET /* SYSRETQ */ 69 | 70 | TEXT sysrforkret(SB), 1, $-4 71 | MOVQ $0, AX 72 | JMP _syscallreturn 73 | -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/dosfs.h: -------------------------------------------------------------------------------- 1 | typedef struct Dosboot Dosboot; 2 | typedef struct Dos Dos; 3 | typedef struct Dosdir Dosdir; 4 | typedef struct Dosfile Dosfile; 5 | typedef struct Dospart Dospart; 6 | 7 | struct Dospart 8 | { 9 | uchar flag; /* active flag */ 10 | uchar shead; /* starting head */ 11 | uchar scs[2]; /* starting cylinder/sector */ 12 | uchar type; /* partition type */ 13 | uchar ehead; /* ending head */ 14 | uchar ecs[2]; /* ending cylinder/sector */ 15 | uchar start[4]; /* starting sector */ 16 | uchar len[4]; /* length in sectors */ 17 | }; 18 | 19 | #define FAT12 0x01 20 | #define FAT16 0x04 21 | #define EXTEND 0x05 22 | #define FATHUGE 0x06 23 | #define FAT32 0x0b 24 | #define FAT32X 0x0c 25 | #define EXTHUGE 0x0f 26 | #define DMDDO 0x54 27 | #define PLAN9 0x39 28 | #define LEXTEND 0x85 29 | 30 | struct Dosfile{ 31 | Dos *dos; /* owning dos file system */ 32 | char name[8]; 33 | char ext[3]; 34 | uchar attr; 35 | long length; 36 | long pstart; /* physical start cluster address */ 37 | long pcurrent; /* physical current cluster address */ 38 | long lcurrent; /* logical current cluster address */ 39 | long offset; 40 | }; 41 | 42 | struct Dos{ 43 | long start; /* start of file system */ 44 | int sectsize; /* in bytes */ 45 | int clustsize; /* in sectors */ 46 | int clustbytes; /* in bytes */ 47 | int nresrv; /* sectors */ 48 | int nfats; /* usually 2 */ 49 | int rootsize; /* number of entries */ 50 | int volsize; /* in sectors */ 51 | int mediadesc; 52 | int fatsize; /* in sectors */ 53 | int fatclusters; 54 | int fatbits; /* 12 or 16 */ 55 | long fataddr; /* sector number */ 56 | long rootaddr; 57 | long rootclust; 58 | long dataaddr; 59 | long freeptr; 60 | }; 61 | 62 | extern int dosinit(Fs*); 63 | -------------------------------------------------------------------------------- /sys/src/nix/port/latin1.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | 3 | /* 4 | * The code makes two assumptions: strlen(ld) is 1 or 2; latintab[i].ld can be a 5 | * prefix of latintab[j].ld only when j=5) 55 | return unicode(k); 56 | else 57 | return -5; 58 | for(l=latintab; l->ld!=0; l++) 59 | if(k[0] == l->ld[0]){ 60 | if(n == 1) 61 | return -2; 62 | if(l->ld[1] == 0) 63 | c = k[1]; 64 | else if(l->ld[1] != k[1]) 65 | continue; 66 | else if(n == 2) 67 | return -3; 68 | else 69 | c = k[2]; 70 | for(p=l->si; *p!=0; p++) 71 | if(*p == c) 72 | return l->so[p - l->si]; 73 | return -1; 74 | } 75 | return -1; 76 | } 77 | -------------------------------------------------------------------------------- /sys/src/cmd/rc/fns.h: -------------------------------------------------------------------------------- 1 | void Abort(void); 2 | void Closedir(int); 3 | int Creat(char*); 4 | int Dup(int, int); 5 | int Dup1(int); 6 | int Eintr(void); 7 | int Executable(char*); 8 | void Execute(word*, word*); 9 | void Exit(char*); 10 | int ForkExecute(char*, char**, int, int, int); 11 | int Globsize(char*); 12 | int Isatty(int); 13 | void Memcpy(void*, void*, long); 14 | void Noerror(void); 15 | int Opendir(char*); 16 | long Read(int, void*, long); 17 | int Readdir(int, void*, int); 18 | long Seek(int, long, long); 19 | void Trapinit(void); 20 | void Unlink(char*); 21 | void Updenv(void); 22 | void Vinit(void); 23 | int Waitfor(int, int); 24 | long Write(int, void*, long); 25 | void addwaitpid(int); 26 | int advance(void); 27 | int back(int); 28 | void cleanhere(char*); 29 | void codefree(code*); 30 | int compile(tree*); 31 | char * list2str(word*); 32 | int count(word*); 33 | void deglob(void*); 34 | void delwaitpid(int); 35 | void dotrap(void); 36 | void freenodes(void); 37 | void freewords(word*); 38 | void globlist(void); 39 | int havewaitpid(int); 40 | int idchr(int); 41 | void inttoascii(char*, long); 42 | void kinit(void); 43 | int mapfd(int); 44 | int match(void*, void*, int); 45 | int matchfn(void*, void*); 46 | char** mkargv(word*); 47 | void clearwaitpids(void); 48 | void panic(char*, int); 49 | void pathinit(void); 50 | void poplist(void); 51 | void popword(void); 52 | void pprompt(void); 53 | void pushlist(void); 54 | void pushredir(int, int, int); 55 | void pushword(char*); 56 | void readhere(void); 57 | word* searchpath(char*); 58 | void setstatus(char*); 59 | void setvar(char*, word*); 60 | void skipnl(void); 61 | void start(code*, int, var*); 62 | int truestatus(void); 63 | void usage(char*); 64 | int wordchr(int); 65 | void yyerror(char*); 66 | int yylex(void); 67 | int yyparse(void); 68 | -------------------------------------------------------------------------------- /sys/src/nix/k10/sipi.h: -------------------------------------------------------------------------------- 1 | uchar sipihandler[]={ 2 | 0xea,0x58,0x30,0x00,0x00,0x90,0x90,0x90, 3 | 0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0xa5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 4 | 0xff,0xff,0x00,0x00,0x00,0x9a,0xcf,0x00,0xff,0xff,0x00,0x00,0x00,0x92,0xcf,0x00, 5 | 0x00,0x00,0x00,0x00,0x00,0x98,0x20,0x00,0x1f,0x00,0x10,0x30,0x00,0x00,0x00,0x00, 6 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x20,0x00,0x00,0x00, 7 | 0x00,0x00,0x00,0x80,0x00,0x00,0x17,0x00,0x36,0x30,0x00,0xf0,0xff,0xff,0xff,0xff, 8 | 0x8c,0xc8,0x8e,0xd8,0x0f,0x01,0x16,0x30,0x30,0x0f,0x20,0xc0,0x83,0xc8,0x01,0x0f, 9 | 0x22,0xc0,0xeb,0x00,0xb8,0x10,0x00,0x8e,0xd8,0x8e,0xc0,0x8e,0xe0,0x8e,0xe8,0x8e, 10 | 0xd0,0x66,0xea,0x81,0x30,0x00,0x00,0x08,0x00,0xbd,0x00,0x00,0xe0,0xfe,0x8b,0x6d, 11 | 0x20,0xc1,0xed,0x18,0xbe,0x00,0x60,0x10,0x00,0x89,0xf0,0x0f,0x22,0xd8,0x89,0xc2, 12 | 0x81,0xea,0x00,0x60,0x00,0x00,0x83,0xc2,0x03,0x89,0x10,0x2d,0x00,0x60,0x00,0x00, 13 | 0x81,0xc2,0x00,0x10,0x00,0x00,0x89,0x10,0xba,0x83,0x00,0x00,0x00,0x05,0x00,0x10, 14 | 0x00,0x00,0x89,0x10,0x0f,0x20,0xe0,0x83,0xe0,0xef,0x0d,0xa0,0x00,0x00,0x00,0x0f, 15 | 0x22,0xe0,0xb9,0x80,0x00,0x00,0xc0,0x0f,0x32,0x0d,0x00,0x01,0x00,0x00,0x0f,0x30, 16 | 0x0f,0x20,0xc2,0x81,0xe2,0xf5,0xff,0xff,0x9f,0x81,0xca,0x00,0x00,0x01,0x80,0x0f, 17 | 0x22,0xc2,0xea,0xf1,0x30,0x00,0x00,0x18,0x00,0x48,0xc7,0xc0,0xfa,0x30,0x00,0xf0, 18 | 0xff,0xe0,0x48,0xc7,0xc0,0x4e,0x30,0x00,0xf0,0x0f,0x01,0x10,0x48,0x31,0xd2,0x8e, 19 | 0xda,0x8e,0xc2,0x8e,0xe2,0x8e,0xea,0x8e,0xd2,0x8b,0xf6,0x48,0x89,0xf0,0x48,0x05, 20 | 0x00,0x00,0x00,0xf0,0x48,0x89,0xc4,0x48,0x89,0x10,0x0f,0x22,0xde,0x48,0xc7,0xc0, 21 | 0x00,0x30,0x00,0xf0,0x8b,0x70,0xfc,0x8b,0xf6,0x48,0x89,0xf0,0x48,0x05,0x00,0x00, 22 | 0x00,0xf0,0x48,0x89,0xc4,0x48,0x05,0x00,0x50,0x00,0x00,0x49,0x89,0xc7,0x49,0x89, 23 | 0xd6,0x52,0x9d,0x8b,0xed,0x55,0x49,0x8b,0x47,0x08,0xff,0xd0,0xeb,0xfe, 24 | 25 | }; 26 | -------------------------------------------------------------------------------- /NOTES: -------------------------------------------------------------------------------- 1 | # Here are some notes for a quick start. 2 | # 3 | # The bulk of the work are modifications against some Plan9 4 | # distribution. So one needs first to get the modifications 5 | # 6 | # The main repository is for now: 7 | # 8 | # https://github.com/rminnich/nix-os 9 | # 10 | # So you need to have a copy, a clone, of the main directory or 11 | # of your fork (exchange are as usual: commit to your branch 12 | # and then make a Pull Request if you want to get it merged). 13 | # 14 | # We will suppose on the following that you have put the sources 15 | # in $home/nix-os. 16 | 17 | # This is the master site; this could be your clone or you could 18 | # mount a copy etc. 19 | # 20 | cd 21 | git/clone https://github.com/rminnich/nix-os 22 | 23 | # Once you get the modifications served, the first step is to 24 | # manipulate the namespace in order for changed files to 25 | # mix with unchanged ones. The 'nix' rc script in 26 | # sys/src/nix/ will take care of that: 27 | 28 | cd nix-os/sys/src/nix 29 | nix 30 | 31 | # Compilation of boot part. You should better intercept 32 | # compiler (i.e. assembler, compiler or linker) warnings 33 | # and fix things if needed. 34 | # 35 | cd boot 36 | mk 37 | 38 | # Then the rest of the cpu kernel. 39 | # 40 | # Same remarks for the following. 41 | # 42 | cd ../k10 43 | mk ../root/nvram 44 | mk 45 | 46 | # The scripts related to nix have been binded as to be accessed 47 | # as nix/some_script. 48 | # You should have now (after the commands above) a 9k8cpu kernel 49 | # to test. 50 | # 51 | # To ease testing, there are scripts accessed as nix/some_script: 52 | 53 | # Testing with vmx. Do read the man page first, if only to know 54 | # how to "ungrab" the mouse. 55 | # Any argument passed to the script is an argument passed to the 56 | # Nix kernel. 57 | # 58 | nix/test_vmx # Paul Lalonde's script to call (single core) vmx wiht 9k8cpu 59 | -------------------------------------------------------------------------------- /sys/src/nix/test/README: -------------------------------------------------------------------------------- 1 | This is regression testing for nix. 2 | Each directory named with a number represents a single test. 3 | (e.g., 1/ 2/ ...) 4 | A test directory may be also named k1, k2, k.... 5 | All k tests run affter all std. tests. They are meant to install ad-hoc 6 | kernels for testing. 7 | 8 | The script actually running the tests is runtests, which should be run from 9 | cpustart during the machine boot process. 10 | That is, include 11 | test -x /cfg/$sysname/runtests && /cfg/$sysname/runtests 12 | in your cpustart file. 13 | It is not meant to start the testing sequence by hand. 14 | To (re)run all the tests, you should run ./Tests instead. 15 | 16 | See 1/ for a template. Copy it to your own and tweak it at will. 17 | 18 | To start testing, run the script ./Tests in clu, which would 19 | change the boot sequence such that the machine starts to run tests 20 | (perhaps installing different kernels and rebooting) until all 21 | tests have been run or one has failed. 22 | 23 | Each directory must contain: 24 | 25 | - kern: a script used to compile and install a kernel used for testing 26 | if no such file is found, no new kernel is installed. the current one 27 | is used. Otherwise, the indicated kernel is installed and the machine 28 | reboots using this kernel. 29 | 30 | - runtest: a script used to run a test. This is mandatory. 31 | 32 | - whichever other files must be available for the tests to run. 33 | 34 | Tests generate within each test directory: 35 | 36 | - koutput: a file keeping the output for a kern that did run 37 | - output: a file keeping the output for a test that did run 38 | - FAIL: an empty file, reporting that a test did fail. 39 | 40 | 41 | BEWARE that if you install a kernel for a test then that kernel is used 42 | for all following tests. 43 | As a convention, tests installing a kernel should be named k0, k1, ... 44 | test 1 installs the std kernel, so that all tests use the regular kernel. 45 | 46 | -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/fs.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "io.h" 7 | 8 | #include "fs.h" 9 | 10 | /* 11 | * grab next element from a path, return the pointer to unprocessed portion of 12 | * path. 13 | */ 14 | char * 15 | nextelem(char *path, char *elem) 16 | { 17 | int i; 18 | 19 | while(*path == '/') 20 | path++; 21 | if(*path==0 || *path==' ') 22 | return 0; 23 | for(i=0; *path!='\0' && *path!='/' && *path!=' '; i++){ 24 | if(i==NAMELEN){ 25 | print("name component too long\n"); 26 | return 0; 27 | } 28 | *elem++ = *path++; 29 | } 30 | *elem = '\0'; 31 | return path; 32 | } 33 | 34 | int 35 | fswalk(Fs *fs, char *path, File *f) 36 | { 37 | char element[NAMELEN]; 38 | 39 | *f = fs->root; 40 | if(BADPTR(fs->walk)) 41 | panic("fswalk bad pointer fs->walk"); 42 | 43 | f->path = path; 44 | while(path = nextelem(path, element)){ 45 | switch(fs->walk(f, element)){ 46 | case -1: 47 | return -1; 48 | case 0: 49 | return 0; 50 | } 51 | } 52 | return 1; 53 | } 54 | 55 | /* 56 | * boot 57 | */ 58 | int 59 | fsboot(Fs *fs, char *path, Boot *b) 60 | { 61 | File file; 62 | long n; 63 | static char buf[8192]; 64 | 65 | switch(fswalk(fs, path, &file)){ 66 | case -1: 67 | print("error walking to %s\n", path); 68 | return -1; 69 | case 0: 70 | print("%s not found\n", path); 71 | return -1; 72 | case 1: 73 | print("found %s\n", path); 74 | break; 75 | } 76 | 77 | while((n = fsread(&file, buf, sizeof buf)) > 0) { 78 | if(bootpass(b, buf, n) != MORE) 79 | break; 80 | } 81 | 82 | bootpass(b, nil, 0); /* tries boot */ 83 | return -1; 84 | } 85 | 86 | int 87 | fsread(File *file, void *a, long n) 88 | { 89 | if(BADPTR(file->fs)) 90 | panic("bad pointer file->fs in fsread"); 91 | if(BADPTR(file->fs->read)) 92 | panic("bad pointer file->fs->read in fsread"); 93 | return file->fs->read(file, a, n); 94 | } 95 | -------------------------------------------------------------------------------- /sys/src/nix/boot/bootcache.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include <../boot/boot.h> 4 | 5 | uchar statbuf[Statsz]; 6 | 7 | int 8 | cache(int fd) 9 | { 10 | int argc, i, p[2]; 11 | char *argv[5], bd[32], buf[256], partition[64], *pp; 12 | 13 | if(stat("/boot/cfs", statbuf, sizeof statbuf) < 0) 14 | return fd; 15 | 16 | *partition = 0; 17 | 18 | bind("#S", "/dev", MAFTER); 19 | readfile("#e/cfs", buf, sizeof(buf)); 20 | if(*buf){ 21 | argc = tokenize(buf, argv, 4); 22 | for(i = 0; i < argc; i++){ 23 | if(strcmp(argv[i], "off") == 0) 24 | return fd; 25 | else if(stat(argv[i], statbuf, sizeof statbuf) >= 0){ 26 | strncpy(partition, argv[i], sizeof(partition)-1); 27 | partition[sizeof(partition)-1] = 0; 28 | } 29 | } 30 | } 31 | 32 | if(*partition == 0){ 33 | readfile("#e/bootdisk", bd, sizeof(bd)); 34 | if(*bd){ 35 | if(pp = strchr(bd, ':')) 36 | *pp = 0; 37 | /* damned artificial intelligence */ 38 | i = strlen(bd); 39 | if(strcmp("disk", &bd[i-4]) == 0) 40 | bd[i-4] = 0; 41 | else if(strcmp("fs", &bd[i-2]) == 0) 42 | bd[i-2] = 0; 43 | else if(strcmp("fossil", &bd[i-6]) == 0) 44 | bd[i-6] = 0; 45 | sprint(partition, "%scache", bd); 46 | if(stat(partition, statbuf, sizeof statbuf) < 0) 47 | *bd = 0; 48 | } 49 | if(*bd == 0){ 50 | sprint(partition, "%scache", bootdisk); 51 | if(stat(partition, statbuf, sizeof statbuf) < 0) 52 | return fd; 53 | } 54 | } 55 | 56 | print("cfs..."); 57 | if(pipe(p)<0) 58 | fatal("pipe"); 59 | switch(fork()){ 60 | case -1: 61 | fatal("fork"); 62 | case 0: 63 | close(p[1]); 64 | dup(fd, 0); 65 | close(fd); 66 | dup(p[0], 1); 67 | close(p[0]); 68 | if(fflag) 69 | execl("/boot/cfs", "bootcfs", "-rs", "-f", partition, 0); 70 | else 71 | execl("/boot/cfs", "bootcfs", "-s", "-f", partition, 0); 72 | break; 73 | default: 74 | close(p[0]); 75 | close(fd); 76 | fd = p[1]; 77 | break; 78 | } 79 | return fd; 80 | } 81 | -------------------------------------------------------------------------------- /sys/src/nix/port/alarm.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | 7 | static Alarms alarms; 8 | static Rendez alarmr; 9 | 10 | void 11 | alarmkproc(void*) 12 | { 13 | Proc *rp; 14 | ulong now; 15 | 16 | for(;;){ 17 | now = sys->ticks; 18 | qlock(&alarms); 19 | while((rp = alarms.head) && rp->alarm <= now){ 20 | if(rp->alarm != 0L){ 21 | if(canqlock(&rp->debug)){ 22 | if(!waserror()){ 23 | postnote(rp, 0, "alarm", NUser); 24 | poperror(); 25 | } 26 | qunlock(&rp->debug); 27 | rp->alarm = 0L; 28 | }else 29 | break; 30 | } 31 | alarms.head = rp->palarm; 32 | } 33 | qunlock(&alarms); 34 | 35 | sleep(&alarmr, return0, 0); 36 | } 37 | } 38 | 39 | /* 40 | * called every clock tick 41 | */ 42 | void 43 | checkalarms(void) 44 | { 45 | Proc *p; 46 | ulong now; 47 | 48 | p = alarms.head; 49 | now = sys->ticks; 50 | 51 | if(p && p->alarm <= now) 52 | wakeup(&alarmr); 53 | } 54 | 55 | ulong 56 | procalarm(ulong time) 57 | { 58 | Proc **l, *f; 59 | ulong when, old; 60 | 61 | if(up->alarm) 62 | old = tk2ms(up->alarm - sys->ticks); 63 | else 64 | old = 0; 65 | if(time == 0) { 66 | up->alarm = 0; 67 | return old; 68 | } 69 | when = ms2tk(time)+sys->ticks; 70 | 71 | qlock(&alarms); 72 | l = &alarms.head; 73 | for(f = *l; f; f = f->palarm) { 74 | if(up == f){ 75 | *l = f->palarm; 76 | break; 77 | } 78 | l = &f->palarm; 79 | } 80 | 81 | up->palarm = 0; 82 | if(alarms.head) { 83 | l = &alarms.head; 84 | for(f = *l; f; f = f->palarm) { 85 | if(f->alarm > when) { 86 | up->palarm = f; 87 | *l = up; 88 | goto done; 89 | } 90 | l = &f->palarm; 91 | } 92 | *l = up; 93 | } 94 | else 95 | alarms.head = up; 96 | done: 97 | up->alarm = when; 98 | qunlock(&alarms); 99 | 100 | return old; 101 | } 102 | -------------------------------------------------------------------------------- /sys/src/nix/boot/boot.h: -------------------------------------------------------------------------------- 1 | typedef struct Method Method; 2 | struct Method 3 | { 4 | char *name; 5 | void (*config)(Method*); 6 | int (*connect)(void); 7 | char *arg; 8 | }; 9 | enum 10 | { 11 | Statsz= 256, 12 | Nbarg= 16, 13 | }; 14 | 15 | extern void authentication(int); 16 | extern char* bootdisk; 17 | extern char* rootdir; 18 | extern int (*cfs)(int); 19 | extern int cpuflag; 20 | extern char cputype[]; 21 | extern int fflag; 22 | extern int kflag; 23 | extern Method method[]; 24 | extern void (*pword)(int, Method*); 25 | extern char sys[]; 26 | extern uchar hostkey[]; 27 | extern uchar statbuf[Statsz]; 28 | extern int bargc; 29 | extern char *bargv[Nbarg]; 30 | 31 | /* libc equivalent */ 32 | extern int cache(int); 33 | extern char* checkkey(Method*, char*, char*); 34 | extern void fatal(char*); 35 | extern void getpasswd(char*, int); 36 | extern void key(int, Method*); 37 | extern int outin(char*, char*, int); 38 | extern int plumb(char*, char*, int*, char*); 39 | extern int readfile(char*, char*, int); 40 | extern long readn(int, void*, long); 41 | extern void run(char *file, ...); 42 | extern int sendmsg(int, char*); 43 | extern void setenv(char*, char*); 44 | extern void settime(int, int, char*); 45 | extern void srvcreate(char*, int); 46 | extern void warning(char*); 47 | extern int writefile(char*, char*, int); 48 | extern void boot(int, char **); 49 | extern void doauthenticate(int, Method*); 50 | extern int old9p(int); 51 | extern int parsefields(char*, char**, int, char*); 52 | 53 | /* methods */ 54 | extern void configtcp(Method*); 55 | extern int connecttcp(void); 56 | 57 | extern void configlocal(Method*); 58 | extern int connectlocal(void); 59 | 60 | extern void configsac(Method*); 61 | extern int connectsac(void); 62 | 63 | extern void configpaq(Method*); 64 | extern int connectpaq(void); 65 | 66 | extern void configembed(Method*); 67 | extern int connectembed(void); 68 | 69 | extern void configip(int, char**, int); 70 | 71 | /* hack for passing authentication address */ 72 | extern char *authaddr; 73 | -------------------------------------------------------------------------------- /sys/src/nix/port/rebootcmd.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "../port/error.h" 7 | 8 | #include 9 | 10 | static ulong 11 | l2be(long l) 12 | { 13 | uchar *cp; 14 | 15 | cp = (uchar*)&l; 16 | return (cp[0]<<24) | (cp[1]<<16) | (cp[2]<<8) | cp[3]; 17 | } 18 | 19 | 20 | static void 21 | readn(Chan *c, void *vp, long n) 22 | { 23 | char *p; 24 | long nn; 25 | 26 | p = vp; 27 | while(n > 0) { 28 | nn = c->dev->read(c, p, n, c->offset); 29 | if(nn == 0) 30 | error(Eshort); 31 | c->offset += nn; 32 | p += nn; 33 | n -= nn; 34 | } 35 | } 36 | 37 | static void 38 | setbootcmd(int argc, char *argv[]) 39 | { 40 | char *buf, *p, *ep; 41 | int i; 42 | 43 | buf = malloc(1024); 44 | if(buf == nil) 45 | error(Enomem); 46 | p = buf; 47 | ep = buf + 1024; 48 | for(i=0; iref; 21 | unlock(r); 22 | return x; 23 | } 24 | 25 | int 26 | decref(Ref *r) 27 | { 28 | int x; 29 | 30 | lock(r); 31 | x = --r->ref; 32 | unlock(r); 33 | if(x < 0) 34 | panic("decref pc=%#p", getcallerpc(&r)); 35 | 36 | return x; 37 | } 38 | 39 | void 40 | procrestore(Proc *p) 41 | { 42 | uvlong t; 43 | 44 | if(p->kp) 45 | return; 46 | cycles(&t); 47 | p->pcycles -= t; 48 | 49 | fpuprocrestore(p); 50 | } 51 | 52 | /* 53 | * Save the mach dependent part of the process state. 54 | * NB: the caller should mmuflushtlb after procsave(). 55 | * procsave/procrestore don't touch the mmu, they 56 | * care about fpu, mostly. 57 | */ 58 | void 59 | procsave(Proc *p) 60 | { 61 | uvlong t; 62 | 63 | cycles(&t); 64 | p->pcycles += t; 65 | 66 | fpuprocsave(p); 67 | } 68 | 69 | static void 70 | linkproc(void) 71 | { 72 | spllo(); 73 | up->kpfun(up->kparg); 74 | pexit("kproc dying", 0); 75 | } 76 | 77 | void 78 | kprocchild(Proc* p, void (*func)(void*), void* arg) 79 | { 80 | /* 81 | * gotolabel() needs a word on the stack in 82 | * which to place the return PC used to jump 83 | * to linkproc(). 84 | */ 85 | p->sched.pc = PTR2UINT(linkproc); 86 | p->sched.sp = PTR2UINT(p->kstack+KSTACK-BY2SE); 87 | p->sched.sp = STACKALIGN(p->sched.sp); 88 | 89 | p->kpfun = func; 90 | p->kparg = arg; 91 | } 92 | 93 | /* 94 | * put the processor in the halt state if we've no processes to run. 95 | * an interrupt will get us going again. 96 | * The boot TC in nix can't halt, because it must stay alert in 97 | * case an AC makes a handler process ready. 98 | * We should probably use mwait in that case. 99 | */ 100 | void 101 | idlehands(void) 102 | { 103 | if(0) 104 | if(m->machno != 0) 105 | halt(); 106 | } 107 | -------------------------------------------------------------------------------- /sys/src/nix/k10/l64acsyscall.s: -------------------------------------------------------------------------------- 1 | #include "mem.h" 2 | #include "amd64l.h" 3 | 4 | MODE $64 5 | 6 | /* 7 | */ 8 | TEXT acsyscallentry(SB), 1, $-4 9 | SWAPGS 10 | BYTE $0x65; MOVQ 0, RMACH /* m-> (MOVQ GS:0x0, R15) */ 11 | MOVQ 16(RMACH), RUSER /* m->proc */ 12 | MOVQ 24(RUSER), R12 /* m->proc->dbgregs */ 13 | 14 | /* save sp to r13; set up kstack so we can call acsyscall */ 15 | MOVQ SP, R13 16 | MOVQ 24(RMACH), SP /* m->stack */ 17 | ADDQ $MACHSTKSZ, SP 18 | 19 | MOVQ $SSEL(SiUDS, SsRPL3), BX /* old stack segment */ 20 | MOVQ BX, 176(R12) /* save ss */ 21 | MOVQ R13, 168(R12) /* old sp */ 22 | MOVQ R11, 160(R12) /* old flags */ 23 | MOVQ $SSEL(SiUCS, SsRPL3), BX /* old code segment */ 24 | MOVQ BX, 152(R12) /* save cs */ 25 | MOVQ CX, 144(R12) /* old ip */ 26 | 27 | MOVW $SSEL(SiUDS, SsRPL3), 120(R12) 28 | MOVW ES, 122(R12) 29 | MOVW FS, 124(R12) 30 | MOVW GS, 126(R12) 31 | 32 | MOVQ RARG, 0(R12) /* system call number: up->dbgregs->ax */ 33 | CALL acsyscall(SB) 34 | NDNR: JMP NDNR 35 | 36 | TEXT _acsysret(SB), 1, $-4 37 | CLI 38 | SWAPGS 39 | 40 | MOVQ 24(RUSER), R12 /* m->proc->dbgregs */ 41 | MOVQ 0(R12), AX /* m->proc->dbgregs->ax */ 42 | MOVQ (6*8)(R12), BP /* m->proc->dbgregs->bp */ 43 | ADDQ $(15*8), R12 /* after ax--r15, 8 bytes each */ 44 | 45 | MOVW 0(R12), DS 46 | MOVW 2(R12), ES 47 | MOVW 4(R12), FS 48 | MOVW 6(R12), GS 49 | 50 | MOVQ 24(R12), CX /* ip */ 51 | MOVQ 40(R12), R11 /* flags */ 52 | 53 | MOVQ 48(R12), SP /* sp */ 54 | 55 | BYTE $0x48; SYSRET /* SYSRETQ */ 56 | 57 | /* 58 | * Return from an exec() system call that we never did, 59 | * DX is ar0->p by the time we call it. See syscall() 60 | */ 61 | TEXT xactouser(SB), 1, $-4 62 | CLI 63 | BYTE $0x65; MOVQ 0, RMACH /* m-> (MOVQ GS:0x0, R15) */ 64 | MOVQ 16(RMACH), RUSER /* m->proc */ 65 | MOVQ 24(RUSER), R12 /* m->proc->dbgregs */ 66 | MOVQ 144(R12), CX /* old ip */ 67 | MOVQ 0(R12), BX /* save AX */ 68 | SWAPGS 69 | MOVQ $SSEL(SiUDS, SsRPL3), AX 70 | MOVW AX, DS 71 | MOVW AX, ES 72 | MOVW AX, FS 73 | MOVW AX, GS 74 | 75 | MOVQ BX, AX /* restore AX */ 76 | MOVQ $If, R11 /* flags */ 77 | 78 | MOVQ RARG, SP /* sp */ 79 | 80 | BYTE $0x48; SYSRET /* SYSRETQ */ 81 | -------------------------------------------------------------------------------- /sys/src/nix/port/rdb.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | 7 | #include "ureg.h" 8 | 9 | #define DBG if(0)scrprint 10 | #pragma varargck argpos scrprint 1 11 | static Ureg ureg; 12 | 13 | static void 14 | scrprint(char *fmt, ...) 15 | { 16 | char buf[128]; 17 | va_list va; 18 | int n; 19 | 20 | va_start(va, fmt); 21 | n = vseprint(buf, buf+sizeof buf, fmt, va)-buf; 22 | va_end(va); 23 | putstrn(buf, n); 24 | } 25 | 26 | static char* 27 | getline(void) 28 | { 29 | static char buf[128]; 30 | int i, c; 31 | 32 | for(;;){ 33 | for(i=0; i 4){ 84 | mesg(Rerr, Ecount); 85 | break; 86 | } 87 | a = addr(min+0); 88 | scrprint("mput %.8lux\n", a); 89 | memmove(a, min+5, n); 90 | mesg(Rmput, mout); 91 | break; 92 | * 93 | */ 94 | default: 95 | DBG("unknown %c\n", *req); 96 | iprint("Eunknown message\n"); 97 | break; 98 | } 99 | } 100 | } 101 | 102 | void 103 | rdb(void) 104 | { 105 | splhi(); 106 | iprint("rdb..."); 107 | callwithureg(talkrdb); 108 | } 109 | -------------------------------------------------------------------------------- /sys/src/nix/ip/loopbackmedium.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "../port/error.h" 7 | 8 | #include "ip.h" 9 | 10 | enum 11 | { 12 | Maxtu= 16*1024, 13 | }; 14 | 15 | typedef struct LB LB; 16 | struct LB 17 | { 18 | Proc *readp; 19 | Queue *q; 20 | Fs *f; 21 | }; 22 | 23 | static void loopbackread(void *a); 24 | 25 | static void 26 | loopbackbind(Ipifc *ifc, int, char**) 27 | { 28 | LB *lb; 29 | 30 | lb = smalloc(sizeof(*lb)); 31 | lb->f = ifc->conv->p->f; 32 | lb->q = qopen(1024*1024, Qmsg, nil, nil); 33 | ifc->arg = lb; 34 | ifc->mbps = 10001; 35 | 36 | kproc("loopbackread", loopbackread, ifc); 37 | 38 | } 39 | 40 | static void 41 | loopbackunbind(Ipifc *ifc) 42 | { 43 | LB *lb = ifc->arg; 44 | 45 | if(lb->readp) 46 | postnote(lb->readp, 1, "unbind", NUser); 47 | 48 | /* wait for reader to die */ 49 | while(lb->readp != 0) 50 | tsleep(&up->sleep, return0, 0, 300); 51 | 52 | /* clean up */ 53 | qfree(lb->q); 54 | free(lb); 55 | } 56 | 57 | static void 58 | loopbackbwrite(Ipifc *ifc, Block *bp, int, uchar*) 59 | { 60 | LB *lb; 61 | 62 | lb = ifc->arg; 63 | if(qpass(lb->q, bp) < 0) 64 | ifc->outerr++; 65 | ifc->out++; 66 | } 67 | 68 | static void 69 | loopbackread(void *a) 70 | { 71 | Ipifc *ifc; 72 | Block *bp; 73 | LB *lb; 74 | 75 | ifc = a; 76 | lb = ifc->arg; 77 | lb->readp = up; /* hide identity under a rock for unbind */ 78 | if(waserror()){ 79 | lb->readp = 0; 80 | pexit("hangup", 1); 81 | } 82 | for(;;){ 83 | bp = qbread(lb->q, Maxtu); 84 | if(bp == nil) 85 | continue; 86 | ifc->in++; 87 | if(!canrlock(ifc)){ 88 | freeb(bp); 89 | continue; 90 | } 91 | if(waserror()){ 92 | runlock(ifc); 93 | nexterror(); 94 | } 95 | if(ifc->lifc == nil) 96 | freeb(bp); 97 | else 98 | ipiput4(lb->f, ifc, bp); 99 | runlock(ifc); 100 | poperror(); 101 | } 102 | } 103 | 104 | Medium loopbackmedium = 105 | { 106 | .hsize= 0, 107 | .mintu= 0, 108 | .maxtu= Maxtu, 109 | .maclen= 0, 110 | .name= "loopback", 111 | .bind= loopbackbind, 112 | .unbind= loopbackunbind, 113 | .bwrite= loopbackbwrite, 114 | }; 115 | 116 | void 117 | loopbackmediumlink(void) 118 | { 119 | addipmedium(&loopbackmedium); 120 | } 121 | -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/alarm.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "io.h" 7 | #define MAXALARM 10 8 | 9 | Alarm alarmtab[MAXALARM]; 10 | 11 | /* 12 | * Insert new into list after where 13 | */ 14 | void 15 | insert(List **head, List *where, List *new) 16 | { 17 | if(where == 0){ 18 | new->next = *head; 19 | *head = new; 20 | }else{ 21 | new->next = where->next; 22 | where->next = new; 23 | } 24 | 25 | } 26 | 27 | /* 28 | * Delete old from list. where->next is known to be old. 29 | */ 30 | void 31 | delete(List **head, List *where, List *old) 32 | { 33 | if(where == 0){ 34 | *head = old->next; 35 | return; 36 | } 37 | where->next = old->next; 38 | } 39 | 40 | Alarm* 41 | newalarm(void) 42 | { 43 | int i; 44 | Alarm *a; 45 | 46 | for(i=0,a=alarmtab; i < nelem(alarmtab); i++,a++) 47 | if(a->busy==0 && a->f==0){ 48 | a->f = 0; 49 | a->arg = 0; 50 | a->busy = 1; 51 | return a; 52 | } 53 | panic("newalarm"); 54 | return 0; /* not reached */ 55 | } 56 | 57 | Alarm* 58 | alarm(int ms, void (*f)(Alarm*), void *arg) 59 | { 60 | Alarm *a, *w, *pw; 61 | ulong s; 62 | 63 | if(ms < 0) 64 | ms = 0; 65 | s = splhi(); 66 | a = newalarm(); 67 | a->dt = MS2TK(ms); 68 | a->f = f; 69 | a->arg = arg; 70 | pw = 0; 71 | for(w=m->alarm; w; pw=w, w=w->next){ 72 | if(w->dt <= a->dt){ 73 | a->dt -= w->dt; 74 | continue; 75 | } 76 | w->dt -= a->dt; 77 | break; 78 | } 79 | insert(&m->alarm, pw, a); 80 | splx(s); 81 | return a; 82 | } 83 | 84 | void 85 | cancel(Alarm *a) 86 | { 87 | a->f = 0; 88 | } 89 | 90 | void 91 | alarminit(void) 92 | { 93 | } 94 | 95 | #define NA 10 /* alarms per clock tick */ 96 | void 97 | checkalarms(void) 98 | { 99 | int i, n, s; 100 | Alarm *a; 101 | void (*f)(Alarm*); 102 | Alarm *alist[NA]; 103 | 104 | s = splhi(); 105 | a = m->alarm; 106 | if(a){ 107 | for(n=0; a && a->dt<=0 && nalarm, 0, a); 110 | a = m->alarm; 111 | } 112 | if(a) 113 | a->dt--; 114 | 115 | for(i = 0; i < n; i++){ 116 | f = alist[i]->f; /* avoid race with cancel */ 117 | if(f) 118 | (*f)(alist[i]); 119 | alist[i]->busy = 0; 120 | } 121 | } 122 | splx(s); 123 | } 124 | -------------------------------------------------------------------------------- /sys/src/nix/port/ps.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | 7 | int 8 | nprocs(void) 9 | { 10 | return procalloc.nproc; 11 | } 12 | 13 | void 14 | pshash(Proc *p) 15 | { 16 | int h; 17 | 18 | h = p->pid % nelem(procalloc.ht); 19 | lock(&procalloc); 20 | p->pidhash = procalloc.ht[h]; 21 | procalloc.ht[h] = p; 22 | unlock(&procalloc); 23 | } 24 | 25 | void 26 | psunhash(Proc *p) 27 | { 28 | int h; 29 | Proc **l; 30 | 31 | h = p->pid % nelem(procalloc.ht); 32 | lock(&procalloc); 33 | for(l = &procalloc.ht[h]; *l != nil; l = &(*l)->pidhash) 34 | if(*l == p){ 35 | *l = p->pidhash; 36 | break; 37 | } 38 | unlock(&procalloc); 39 | } 40 | 41 | int 42 | psindex(int pid) 43 | { 44 | Proc *p; 45 | int h; 46 | int s; 47 | 48 | s = -1; 49 | h = pid % nelem(procalloc.ht); 50 | lock(&procalloc); 51 | for(p = procalloc.ht[h]; p != nil; p = p->pidhash) 52 | if(p->pid == pid){ 53 | s = p->index; 54 | break; 55 | } 56 | unlock(&procalloc); 57 | return s; 58 | } 59 | 60 | Proc* 61 | psincref(int i) 62 | { 63 | /* 64 | * Placeholder. 65 | */ 66 | if(i >= conf.nproc) 67 | return nil; 68 | return &procalloc.arena[i]; 69 | } 70 | 71 | void 72 | psdecref(Proc *p) 73 | { 74 | /* 75 | * Placeholder. 76 | */ 77 | USED(p); 78 | } 79 | 80 | void 81 | psrelease(Proc* p) 82 | { 83 | p->qnext = procalloc.free; 84 | procalloc.free = p; 85 | procalloc.nproc--; 86 | } 87 | 88 | Proc* 89 | psalloc(void) 90 | { 91 | Proc *p; 92 | 93 | lock(&procalloc); 94 | for(;;) { 95 | if(p = procalloc.free) 96 | break; 97 | 98 | unlock(&procalloc); 99 | resrcwait("no procs"); 100 | lock(&procalloc); 101 | } 102 | procalloc.free = p->qnext; 103 | procalloc.nproc++; 104 | unlock(&procalloc); 105 | 106 | return p; 107 | } 108 | 109 | void 110 | psinit(int nproc) 111 | { 112 | Proc *p; 113 | int i; 114 | 115 | procalloc.free = malloc(nproc*sizeof(Proc)); 116 | if(procalloc.free == nil) 117 | panic("cannot allocate %ud procs (%udMB)\n", nproc, nproc*sizeof(Proc)/(1024*1024)); 118 | procalloc.arena = procalloc.free; 119 | 120 | p = procalloc.free; 121 | for(i=0; iqnext = p+1; 123 | p->index = i; 124 | } 125 | p->qnext = 0; 126 | p->index = i; 127 | } 128 | -------------------------------------------------------------------------------- /sys/src/nix/k10/qqsort.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PAL: a gross hack for a linker problem 3 | */ 4 | /* 5 | * qsort -- simple quicksort 6 | */ 7 | 8 | #include "u.h" 9 | 10 | typedef 11 | struct 12 | { 13 | int (*cmp)(void*, void*); 14 | void (*swap)(char*, char*, long); 15 | long es; 16 | } Sort; 17 | 18 | static void 19 | swapb(char *i, char *j, long es) 20 | { 21 | char c; 22 | 23 | do { 24 | c = *i; 25 | *i++ = *j; 26 | *j++ = c; 27 | es--; 28 | } while(es != 0); 29 | 30 | } 31 | 32 | static void 33 | swapi(char *ii, char *ij, long es) 34 | { 35 | long *i, *j, c; 36 | 37 | i = (long*)ii; 38 | j = (long*)ij; 39 | do { 40 | c = *i; 41 | *i++ = *j; 42 | *j++ = c; 43 | es -= sizeof(long); 44 | } while(es != 0); 45 | } 46 | 47 | static char* 48 | pivot(char *a, long n, Sort *p) 49 | { 50 | long j; 51 | char *pi, *pj, *pk; 52 | 53 | j = n/6 * p->es; 54 | pi = a + j; /* 1/6 */ 55 | j += j; 56 | pj = pi + j; /* 1/2 */ 57 | pk = pj + j; /* 5/6 */ 58 | if(p->cmp(pi, pj) < 0) { 59 | if(p->cmp(pi, pk) < 0) { 60 | if(p->cmp(pj, pk) < 0) 61 | return pj; 62 | return pk; 63 | } 64 | return pi; 65 | } 66 | if(p->cmp(pj, pk) < 0) { 67 | if(p->cmp(pi, pk) < 0) 68 | return pi; 69 | return pk; 70 | } 71 | return pj; 72 | } 73 | 74 | static void 75 | qsorts(char *a, usize n, Sort *p) 76 | { 77 | long j, es; 78 | char *pi, *pj, *pn; 79 | 80 | es = p->es; 81 | while(n > 1) { 82 | if(n > 10) { 83 | pi = pivot(a, n, p); 84 | } else 85 | pi = a + (n>>1)*es; 86 | 87 | p->swap(a, pi, es); 88 | pi = a; 89 | pn = a + n*es; 90 | pj = pn; 91 | for(;;) { 92 | do 93 | pi += es; 94 | while(pi < pn && p->cmp(pi, a) < 0); 95 | do 96 | pj -= es; 97 | while(pj > a && p->cmp(pj, a) > 0); 98 | if(pj < pi) 99 | break; 100 | p->swap(pi, pj, es); 101 | } 102 | p->swap(a, pj, es); 103 | j = (pj - a) / es; 104 | 105 | n = n-j-1; 106 | if(j >= n) { 107 | qsorts(a, j, p); 108 | a += (j+1)*es; 109 | } else { 110 | qsorts(a + (j+1)*es, n, p); 111 | n = j; 112 | } 113 | } 114 | } 115 | 116 | void 117 | qqsort(void *va, long n, long es, int (*cmp)(void*, void*)) 118 | { 119 | Sort s; 120 | 121 | s.cmp = cmp; 122 | s.es = es; 123 | s.swap = swapi; 124 | if(((uintptr)va | es) % sizeof(long)) 125 | s.swap = swapb; 126 | qsorts((char*)va, n, &s); 127 | } 128 | -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/mkfile: -------------------------------------------------------------------------------- 1 | objtype=386 # sic 2 | >22) & 0x03FF)<<2) 18 | 19 | TEXT _warp64(SB), $0 20 | CLI 21 | MOVL cr3+0(FP), BP /* pml4 */ 22 | 23 | MOVL CR3, CX /* load address of PDB */ 24 | ADDL $KZERO, CX 25 | MOVL PDO(KZERO)(CX), DX /* double-map KZERO at 0 */ 26 | MOVL DX, PDO(0)(CX) 27 | 28 | MOVL CR3, CX 29 | MOVL CX, CR3 /* load and flush the mmu */ 30 | 31 | MOVL $_start32id<>-KZERO(SB), AX 32 | JMP* AX /* jump to identity-map */ 33 | 34 | TEXT _start32id<>(SB), $0 35 | MOVL CR0, DX /* turn off paging */ 36 | ANDL $~0x80000000, DX /* ~(PG) */ 37 | 38 | MOVL $_stop32pg<>-KZERO(SB), AX 39 | MOVL DX, CR0 40 | JMP* AX /* forward into the past */ 41 | 42 | TEXT _stop32pg<>(SB), $0 43 | MOVL $multibootheader-KZERO(SB), BX 44 | MOVL $0x2badb002, AX 45 | MOVL $0x00110000, CX 46 | JMP* CX 47 | MOVL CR4, AX 48 | ORL $0x00000020, AX /* Pae */ 49 | MOVL AX, CR4 50 | 51 | MOVL BP, CR3 /* pml4 */ 52 | 53 | MOVL $0xC0000080, CX /* Extended Feature Enable */ 54 | RDMSR 55 | ORL $0x00000100, AX /* Long Mode Enable */ 56 | MOVL $0xC0000080, CX 57 | WRMSR 58 | 59 | MOVL CR0, DX /* enable paging */ 60 | ORL $0x80010000, DX 61 | MOVL $_start32cm<>-KZERO(SB), AX 62 | MOVL DX, CR0 63 | JMP* AX 64 | 65 | TEXT _start32cm<>(SB), $0 /* compatibility mode */ 66 | MOVL $_gdtptr64<>-KZERO(SB), AX /* load a long-mode GDT */ 67 | MOVL (AX), GDTR 68 | MOVL $_start64lm<>-KZERO(SB), AX 69 | JMP* AX 70 | 71 | TEXT _start64lm<>(SB), $0 /* finally - long mode */ 72 | MOVL $multibootheader-KZERO(SB), BX /* multiboot data pointer */ 73 | MOVL $0x2badb002, AX /* multiboot magic */ 74 | FARJUMP((1<<3), 0x00110000) /* selector 1, in GDT, RPL 0 */ 75 | _idle: 76 | JMP _idle 77 | 78 | TEXT _gdt64<>(SB), $0 79 | LONG $0x00000000; LONG $0x00000000 /* NULL descriptor */ 80 | LONG $0x00000000; LONG $0x00209800 /* CS */ 81 | LONG $0x00000000; LONG $0x00008000 /* DS */ 82 | 83 | TEXT _gdtptr64<>(SB), $0 84 | WORD $(3*8-1) 85 | LONG $_gdt64<>-KZERO(SB) 86 | -------------------------------------------------------------------------------- /sys/src/nix/k10/msi.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "io.h" 7 | #include "apic.h" 8 | 9 | enum { 10 | Dpcicap = 1<<0, 11 | Dmsicap = 1<<1, 12 | Dvec = 1<<2, 13 | Debug = 0, 14 | }; 15 | 16 | enum { 17 | /* address */ 18 | Msiabase = 0xfee00000u, 19 | Msiadest = 1<<12, /* same as 63:56 of apic vector */ 20 | Msiaedest = 1<<4, /* same as 55:48 of apic vector */ 21 | Msialowpri = 1<<3, /* redirection hint */ 22 | Msialogical = 1<<2, 23 | 24 | /* data */ 25 | Msidlevel = 1<<15, 26 | Msidassert = 1<<14, 27 | Msidlogical = 1<<11, 28 | Msidmode = 1<<8, /* 3 bits; delivery mode */ 29 | Msidvector = 0xff<<0, 30 | }; 31 | 32 | enum{ 33 | /* msi capabilities */ 34 | Vmask = 1<<8, 35 | Cap64 = 1<<7, 36 | Mmesgmsk = 7<<4, 37 | Mmcap = 7<<1, 38 | Msienable = 1<<0, 39 | }; 40 | 41 | static int 42 | msicap(Pcidev *p) 43 | { 44 | int c; 45 | 46 | c = pcicap(p, PciCapMSI); 47 | if(c == -1) 48 | return 0; 49 | return c; 50 | } 51 | 52 | static int 53 | blacklist(Pcidev *p) 54 | { 55 | switch(p->vid<<16 | p->did){ 56 | case 0x11ab<<16 | 0x6485: 57 | return -1; 58 | } 59 | return 0; 60 | } 61 | 62 | int 63 | pcimsienable(Pcidev *p, uvlong vec) 64 | { 65 | char *s; 66 | uint c, f, d, datao, lopri, dmode, logical; 67 | 68 | c = msicap(p); 69 | if(c == 0) 70 | return -1; 71 | 72 | f = pcicfgr16(p, c + 2) & ~Mmesgmsk; 73 | 74 | if(blacklist(p) != 0) 75 | return -1; 76 | datao = 8; 77 | d = vec>>48; 78 | lopri = (vec & 0x700) == MTlp; 79 | logical = (vec & Lm) != 0; 80 | pcicfgw32(p, c + 4, Msiabase | Msiaedest * d 81 | | Msialowpri * lopri | Msialogical * logical); 82 | if(f & Cap64){ 83 | datao += 4; 84 | pcicfgw32(p, c + 8, 0); 85 | } 86 | dmode = (vec >> 8) & 7; 87 | pcicfgw16(p, c + datao, Msidassert | Msidlogical * logical 88 | | Msidmode * dmode | (uint)vec & 0xff); 89 | if(f & Vmask) 90 | pcicfgw32(p, c + datao + 4, 0); 91 | 92 | /* leave vectors configured but disabled for debugging */ 93 | if((s = getconf("*nomsi")) != nil && atoi(s) != 0) 94 | return -1; 95 | 96 | pcicfgw16(p, c + 2, f); 97 | return 0; 98 | } 99 | 100 | int 101 | pcimsimask(Pcidev *p, int mask) 102 | { 103 | uint c, f; 104 | 105 | c = msicap(p); 106 | if(c == 0) 107 | return -1; 108 | f = pcicfgr16(p, c + 2) & ~Msienable; 109 | if(mask){ 110 | pcicfgw16(p, c + 2, f & ~Msienable); 111 | // pciclrbme(p); cheeze 112 | }else{ 113 | pcisetbme(p); 114 | pcicfgw16(p, c + 2, f | Msienable); 115 | } 116 | return 0; 117 | } 118 | -------------------------------------------------------------------------------- /sys/src/nix/port/parse.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "../port/error.h" 7 | 8 | /* 9 | * Generous estimate of number of fields, including terminal nil pointer 10 | */ 11 | static int 12 | ncmdfield(char *p, int n) 13 | { 14 | int white, nwhite; 15 | char *ep; 16 | int nf; 17 | 18 | if(p == nil) 19 | return 1; 20 | 21 | nf = 0; 22 | ep = p+n; 23 | white = 1; /* first text will start field */ 24 | while(p < ep){ 25 | nwhite = (strchr(" \t\r\n", *p++ & 0xFF) != 0); /* UTF is irrelevant */ 26 | if(white && !nwhite) /* beginning of field */ 27 | nf++; 28 | white = nwhite; 29 | } 30 | return nf+1; /* +1 for nil */ 31 | } 32 | 33 | /* 34 | * parse a command written to a device 35 | */ 36 | Cmdbuf* 37 | parsecmd(char *p, int n) 38 | { 39 | Cmdbuf *volatile cb; 40 | int nf; 41 | char *sp; 42 | 43 | nf = ncmdfield(p, n); 44 | 45 | /* allocate Cmdbuf plus string pointers plus copy of string including \0 */ 46 | sp = smalloc(sizeof(*cb) + nf * sizeof(char*) + n + 1); 47 | cb = (Cmdbuf*)sp; 48 | cb->f = (char**)(&cb[1]); 49 | cb->buf = (char*)(&cb->f[nf]); 50 | 51 | if(up!=nil && waserror()){ 52 | free(cb); 53 | nexterror(); 54 | } 55 | memmove(cb->buf, p, n); 56 | if(up != nil) 57 | poperror(); 58 | 59 | /* dump new line and null terminate */ 60 | if(n > 0 && cb->buf[n-1] == '\n') 61 | n--; 62 | cb->buf[n] = '\0'; 63 | 64 | cb->nf = tokenize(cb->buf, cb->f, nf-1); 65 | cb->f[cb->nf] = nil; 66 | 67 | return cb; 68 | } 69 | 70 | /* 71 | * Reconstruct original message, for error diagnostic 72 | */ 73 | void 74 | cmderror(Cmdbuf *cb, char *s) 75 | { 76 | int i; 77 | char *p, *e; 78 | 79 | p = up->genbuf; 80 | e = p+ERRMAX-10; 81 | p = seprint(p, e, "%s \"", s); 82 | for(i=0; inf; i++){ 83 | if(i > 0) 84 | p = seprint(p, e, " "); 85 | p = seprint(p, e, "%q", cb->f[i]); 86 | } 87 | strcpy(p, "\""); 88 | error(up->genbuf); 89 | } 90 | 91 | /* 92 | * Look up entry in table 93 | */ 94 | Cmdtab* 95 | lookupcmd(Cmdbuf *cb, Cmdtab *ctab, int nctab) 96 | { 97 | int i; 98 | Cmdtab *ct; 99 | 100 | if(cb->nf == 0) 101 | error("empty control message"); 102 | 103 | for(ct = ctab, i=0; icmd, "*") !=0) /* wildcard always matches */ 105 | if(strcmp(ct->cmd, cb->f[0]) != 0) 106 | continue; 107 | if(ct->narg != 0 && ct->narg != cb->nf) 108 | cmderror(cb, Ecmdargs); 109 | return ct; 110 | } 111 | 112 | cmderror(cb, "unknown control message"); 113 | return nil; 114 | } 115 | -------------------------------------------------------------------------------- /sys/src/nix/port/rmap.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | 7 | void 8 | rmapfree(RMap* rmap, uintptr addr, uint size) 9 | { 10 | Map *mp; 11 | uint t; 12 | 13 | if(size == 0) 14 | return; 15 | 16 | lock(rmap); 17 | for(mp = rmap->map; mp->addr <= addr && mp->size; mp++) 18 | ; 19 | 20 | if(mp > rmap->map && (mp-1)->addr+(mp-1)->size == addr){ 21 | (mp-1)->size += size; 22 | if(addr+size == mp->addr){ 23 | (mp-1)->size += mp->size; 24 | while(mp->size){ 25 | mp++; 26 | (mp-1)->addr = mp->addr; 27 | (mp-1)->size = mp->size; 28 | } 29 | } 30 | }else{ 31 | if(addr+size == mp->addr && mp->size){ 32 | mp->addr -= size; 33 | mp->size += size; 34 | }else{ 35 | do{ 36 | if(mp >= rmap->mapend){ 37 | print("mapfree: %s: losing 0x%luX, %ud\n", rmap->name, addr, size); 38 | break; 39 | } 40 | t = mp->addr; 41 | mp->addr = addr; 42 | addr = t; 43 | t = mp->size; 44 | mp->size = size; 45 | mp++; 46 | }while((size = t) != 0); 47 | } 48 | } 49 | unlock(rmap); 50 | } 51 | 52 | uintptr 53 | rmapalloc(RMap* rmap, uintptr addr, uint size, int align) 54 | { 55 | Map *mp; 56 | ulong maddr, oaddr; 57 | 58 | lock(rmap); 59 | for(mp = rmap->map; mp->size; mp++){ 60 | maddr = mp->addr; 61 | 62 | if(addr){ 63 | /* 64 | * A specific address range has been given: 65 | * if the current map entry is greater then 66 | * the address is not in the map; 67 | * if the current map entry does not overlap 68 | * the beginning of the requested range then 69 | * continue on to the next map entry; 70 | * if the current map entry does not entirely 71 | * contain the requested range then the range 72 | * is not in the map. 73 | */ 74 | if(maddr > addr) 75 | break; 76 | if(mp->size < addr - maddr) /* maddr+mp->size < addr, but no overflow */ 77 | continue; 78 | if(addr - maddr > mp->size - size) /* addr+size > maddr+mp->size, but no overflow */ 79 | break; 80 | maddr = addr; 81 | } 82 | 83 | if(align > 0) 84 | maddr = ((maddr+align-1)/align)*align; 85 | if(mp->addr+mp->size-maddr < size) 86 | continue; 87 | 88 | oaddr = mp->addr; 89 | mp->addr = maddr+size; 90 | mp->size -= maddr-oaddr+size; 91 | if(mp->size == 0){ 92 | do{ 93 | mp++; 94 | (mp-1)->addr = mp->addr; 95 | }while((mp-1)->size = mp->size); 96 | } 97 | 98 | unlock(rmap); 99 | if(oaddr != maddr) 100 | rmapfree(rmap, oaddr, maddr-oaddr); 101 | 102 | return maddr; 103 | } 104 | unlock(rmap); 105 | 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /sys/src/nix/386/random.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | 7 | struct Rb 8 | { 9 | QLock; 10 | Rendez producer; 11 | Rendez consumer; 12 | ulong randomcount; 13 | uchar buf[1024]; 14 | uchar *ep; 15 | uchar *rp; 16 | uchar *wp; 17 | uchar next; 18 | uchar wakeme; 19 | ushort bits; 20 | ulong randn; 21 | } rb; 22 | 23 | static int 24 | rbnotfull(void*) 25 | { 26 | int i; 27 | 28 | i = rb.rp - rb.wp; 29 | return i != 1 && i != (1 - sizeof(rb.buf)); 30 | } 31 | 32 | static int 33 | rbnotempty(void*) 34 | { 35 | return rb.wp != rb.rp; 36 | } 37 | 38 | static void 39 | genrandom(void*) 40 | { 41 | up->basepri = PriNormal; 42 | up->priority = up->basepri; 43 | 44 | for(;;){ 45 | for(;;) 46 | if(++rb.randomcount > 100000) 47 | break; 48 | if(anyhigher()) 49 | sched(); 50 | if(!rbnotfull(0)) 51 | sleep(&rb.producer, rbnotfull, 0); 52 | } 53 | } 54 | 55 | /* 56 | * produce random bits in a circular buffer 57 | */ 58 | static void 59 | randomclock(void) 60 | { 61 | if(rb.randomcount == 0 || !rbnotfull(0)) 62 | return; 63 | 64 | rb.bits = (rb.bits<<2) ^ rb.randomcount; 65 | rb.randomcount = 0; 66 | 67 | rb.next++; 68 | if(rb.next != 8/2) 69 | return; 70 | rb.next = 0; 71 | 72 | *rb.wp ^= rb.bits; 73 | if(rb.wp+1 == rb.ep) 74 | rb.wp = rb.buf; 75 | else 76 | rb.wp = rb.wp+1; 77 | 78 | if(rb.wakeme) 79 | wakeup(&rb.consumer); 80 | } 81 | 82 | void 83 | randominit(void) 84 | { 85 | /* Frequency close but not equal to HZ */ 86 | addclock0link(randomclock, 13); 87 | rb.ep = rb.buf + sizeof(rb.buf); 88 | rb.rp = rb.wp = rb.buf; 89 | kproc("genrandom", genrandom, 0); 90 | } 91 | 92 | /* 93 | * consume random bytes from a circular buffer 94 | */ 95 | ulong 96 | randomread(void *xp, ulong n) 97 | { 98 | uchar *e, *p; 99 | ulong x; 100 | 101 | p = xp; 102 | 103 | if(waserror()){ 104 | qunlock(&rb); 105 | nexterror(); 106 | } 107 | 108 | qlock(&rb); 109 | for(e = p + n; p < e; ){ 110 | if(rb.wp == rb.rp){ 111 | rb.wakeme = 1; 112 | wakeup(&rb.producer); 113 | sleep(&rb.consumer, rbnotempty, 0); 114 | rb.wakeme = 0; 115 | continue; 116 | } 117 | 118 | /* 119 | * beating clocks will be precictable if 120 | * they are synchronized. Use a cheap pseudo 121 | * random number generator to obscure any cycles. 122 | */ 123 | x = rb.randn*1103515245 ^ *rb.rp; 124 | *p++ = rb.randn = x; 125 | 126 | if(rb.rp+1 == rb.ep) 127 | rb.rp = rb.buf; 128 | else 129 | rb.rp = rb.rp+1; 130 | } 131 | qunlock(&rb); 132 | poperror(); 133 | 134 | wakeup(&rb.producer); 135 | 136 | return n; 137 | } 138 | -------------------------------------------------------------------------------- /sys/src/nix/rc/mknixboot: -------------------------------------------------------------------------------- 1 | #!/bin/rc 2 | # mknixboot - make a bootable standalone plan 9 image to copy to a usb disk. 3 | # 4 | # due to name clashes in /srv, will only work on a machine 5 | # without a fossil named `fossil' already running. 6 | 7 | rfork en 8 | srcroot=/n/boot 9 | syscfg=/sys/lib/sysconfig 10 | proto=$syscfg/proto/allproto 11 | quantum=1000000 12 | # size of image in $quantum-byte units. 1900 is enough for production system 13 | # (fs, /n/boot, ~1.2GB); 900 is ample for our install image 14 | # (sources, /n/sources/plan9, ~370MB). 15 | size=1900 16 | 17 | # by default we shall use /$objtype/9load, but you don't have to 18 | loader=/$objtype/9loadusb 19 | 20 | fn usage { 21 | echo usage: $argv0 '[-p proto] [-r root] [-s 10⁶-bytes]' >[1=2] 22 | exit usage 23 | } 24 | 25 | fn sigint sighup sigterm { 26 | rm -f /tmp/9load 27 | exit note 28 | } 29 | 30 | # figure out which kernel to use 31 | switch ($objtype) { 32 | case 386 33 | k=/$objtype/9pcf 34 | case amd64 35 | k=/$objtype/9k8cpu 36 | case * 37 | echo $0: 'can''t cope with architecture' $objtype >[1=2] 38 | exit unknown-arch 39 | } 40 | 41 | # process arguments 42 | done=0 43 | argv0=$0 44 | while (~ $done 0 && ! ~ $#* 0 && ~ $1 -*) { 45 | switch ($1) { 46 | case -k; k=$2; shift 47 | case -l; loader=$2; shift 48 | case -p; proto=$2; shift 49 | case -r; srcroot=$2; shift 50 | case -s; size=$2; shift 51 | case --; done=1 # no break in rc, alas 52 | case -*; usage 53 | } 54 | shift 55 | } 56 | 57 | if (! ~ $#* 0) 58 | usage 59 | 60 | # special case sources 61 | if (~ $srcroot /n/*) 62 | srcfs=`{ echo $srcroot | sed 's;^/n/([^/]+).*;\1;' } 63 | if (~ $srcfs sources) 64 | size=900 65 | 66 | # make empty disk image file of maximum size 67 | echo -n 'image: ' >[1=2] 68 | dd -ibs $quantum -obs $quantum -oseek `{hoc -e $size'-1'} -count 1 -quiet 1 \ 69 | image 70 | 71 | # partition it 72 | disk/partfs image 73 | cd /dev/sdXX 74 | 75 | # prep it: lay down mbr, fdisk partitions, 9 partitions 76 | echo -n mbr+fdisk+prep... >[1=2] 77 | disk/mbr -m /$objtype/mbr data 78 | disk/fdisk -baw data 79 | #disk/prep -bw -a^(9fat nvram fscfg fossil) plan9 >/dev/null 80 | disk/prep -bw -a^(9fat nvram fossil) plan9 >/dev/null 81 | 82 | # populate 9fat, nvram, fsconfig 83 | echo -n 9fat... >[1=2] 84 | cp $loader /tmp/9load # force format to use the name `9load' 85 | disk/format -b /$objtype/pbslba -d -r 2 9fat /tmp/9load $k \ 86 | $srcroot^$syscfg/usb/plan9.ini >[2=1] | 87 | grep -v '^(add .* at clust |Init|type |Adding file|used )' 88 | cp /dev/zero nvram >[2]/dev/null 89 | #cp /dev/zero fscfg >[2]/dev/null 90 | rm -f /tmp/9load 91 | 92 | # fill the fossil 93 | 9fs $srcfs 94 | echo -n load fossil... >[1=2] 95 | exec loadfossil /dev/sdXX/fossil $srcroot $proto $syscfg/usb/fossil.conf 96 | -------------------------------------------------------------------------------- /sys/src/nix/k10/apic.h: -------------------------------------------------------------------------------- 1 | /* 2 | * There are 2 flavours of APIC, Local APIC and IOAPIC, 3 | * Each I/O APIC has a unique physical address, 4 | * Local APICs are all at the same physical address as they can only be 5 | * accessed by the local CPU. APIC ids are unique to the 6 | * APIC type, so an IOAPIC and APIC both with id 0 is ok. 7 | */ 8 | typedef struct Ioapic Ioapic; 9 | typedef struct Lapic Lapic; 10 | typedef struct Apic Apic; 11 | 12 | struct Ioapic { 13 | Lock; /* IOAPIC: register access */ 14 | u32int* addr; /* IOAPIC: register base */ 15 | int nrdt; /* IOAPIC: size of RDT */ 16 | int gsib; /* IOAPIC: global RDT index */ 17 | }; 18 | 19 | struct Lapic { 20 | int machno; /* APIC */ 21 | 22 | u32int lvt[6]; 23 | int nlvt; 24 | int ver; 25 | 26 | vlong hz; /* APIC Timer frequency */ 27 | vlong max; 28 | vlong min; 29 | vlong div; 30 | }; 31 | 32 | struct Apic { 33 | int useable; /* en */ 34 | Ioapic; 35 | Lapic; 36 | }; 37 | 38 | enum { 39 | Nbus = 256, 40 | Napic = 254, /* xAPIC architectural limit */ 41 | Nrdt = 64, 42 | }; 43 | 44 | /* 45 | * Common bits for 46 | * IOAPIC Redirection Table Entry (RDT); 47 | * APIC Local Vector Table Entry (LVT); 48 | * APIC Interrupt Command Register (ICR). 49 | * [10:8] Message Type 50 | * [11] Destination Mode (RW) 51 | * [12] Delivery Status (RO) 52 | * [13] Interrupt Input Pin Polarity (RW) 53 | * [14] Remote IRR (RO) 54 | * [15] Trigger Mode (RW) 55 | * [16] Interrupt Mask 56 | */ 57 | enum { 58 | MTf = 0x00000000, /* Fixed */ 59 | MTlp = 0x00000100, /* Lowest Priority */ 60 | MTsmi = 0x00000200, /* SMI */ 61 | MTrr = 0x00000300, /* Remote Read */ 62 | MTnmi = 0x00000400, /* NMI */ 63 | MTir = 0x00000500, /* INIT/RESET */ 64 | MTsipi = 0x00000600, /* Startup IPI */ 65 | MTei = 0x00000700, /* ExtINT */ 66 | 67 | Pm = 0x00000000, /* Physical Mode */ 68 | Lm = 0x00000800, /* Logical Mode */ 69 | 70 | Ds = 0x00001000, /* Delivery Status */ 71 | IPhigh = 0x00000000, /* IIPP High */ 72 | IPlow = 0x00002000, /* IIPP Low */ 73 | Rirr = 0x00004000, /* Remote IRR */ 74 | TMedge = 0x00000000, /* Trigger Mode Edge */ 75 | TMlevel = 0x00008000, /* Trigger Mode Level */ 76 | Im = 0x00010000, /* Interrupt Mask */ 77 | }; 78 | 79 | extern Apic xlapic[Napic]; 80 | extern Apic xioapic[Napic]; 81 | extern Mach *xlapicmachptr[Napic]; /* maintained, but unused */ 82 | 83 | #define l16get(p) (((p)[1]<<8)|(p)[0]) 84 | #define l32get(p) (((u32int)l16get(p+2)<<16)|l16get(p)) 85 | #define l64get(p) (((u64int)l32get(p+4)<<32)|l32get(p)) 86 | 87 | extern void apicdump(void); 88 | extern void apictimerenab(void); 89 | extern void ioapicdump(void); 90 | 91 | extern int pcimsienable(Pcidev*, uvlong); 92 | extern int pcimsimask(Pcidev*, int); 93 | -------------------------------------------------------------------------------- /sys/src/nix/port/devwd.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "io.h" 7 | #include "../port/error.h" 8 | 9 | enum { 10 | Qdir, 11 | Qwdctl, 12 | }; 13 | 14 | static Watchdog *wd; 15 | static Dirtab wddir[] = { 16 | ".", { Qdir, 0, QTDIR }, 0, 0550, 17 | "wdctl", { Qwdctl, 0 }, 0, 0660, 18 | }; 19 | 20 | 21 | void 22 | addwatchdog(Watchdog *watchdog) 23 | { 24 | if(wd){ 25 | print("addwatchdog: watchdog already installed\n"); 26 | return; 27 | } 28 | wd = watchdog; 29 | if(wd) 30 | wd->disable(); 31 | } 32 | 33 | static Chan* 34 | wdattach(char *spec) 35 | { 36 | return devattach('w', spec); 37 | } 38 | 39 | static Walkqid* 40 | wdwalk(Chan *c, Chan *nc, char **name, int nname) 41 | { 42 | return devwalk(c, nc, name, nname, wddir, nelem(wddir), devgen); 43 | } 44 | 45 | static long 46 | wdstat(Chan *c, uchar *dp, long n) 47 | { 48 | return devstat(c, dp, n, wddir, nelem(wddir), devgen); 49 | } 50 | 51 | static Chan* 52 | wdopen(Chan* c, int omode) 53 | { 54 | return devopen(c, omode, wddir, nelem(wddir), devgen); 55 | } 56 | 57 | static void 58 | wdclose(Chan*) 59 | { 60 | } 61 | 62 | static long 63 | wdread(Chan* c, void* a, long n, vlong off) 64 | { 65 | long offset; 66 | char s[READSTR]; 67 | 68 | offset = off; 69 | switch((ulong)c->qid.path){ 70 | case Qdir: 71 | return devdirread(c, a, n, wddir, nelem(wddir), devgen); 72 | 73 | case Qwdctl: 74 | if(wd == nil || wd->stat == nil) 75 | return 0; 76 | 77 | wd->stat(s, s + READSTR); 78 | return readstr(offset, a, n, s); 79 | 80 | default: 81 | error(Egreg); 82 | break; 83 | } 84 | return 0; 85 | } 86 | 87 | static long 88 | wdwrite(Chan* c, void* a, long n, vlong off) 89 | { 90 | char *p; 91 | 92 | switch((ulong)c->qid.path){ 93 | case Qdir: 94 | error(Eperm); 95 | 96 | case Qwdctl: 97 | if(wd == nil) 98 | return n; 99 | 100 | if(off != 0ll) 101 | error(Ebadarg); 102 | 103 | if(p = strchr(a, '\n')) 104 | *p = 0; 105 | 106 | if(!strncmp(a, "enable", n)) 107 | wd->enable(); 108 | else if(!strncmp(a, "disable", n)) 109 | wd->disable(); 110 | else if(!strncmp(a, "restart", n)) 111 | wd->restart(); 112 | else 113 | error(Ebadarg); 114 | return n; 115 | 116 | default: 117 | error(Egreg); 118 | break; 119 | } 120 | 121 | return 0; 122 | } 123 | 124 | Dev wddevtab = { 125 | 'w', 126 | "watchdog", 127 | 128 | devreset, 129 | devinit, 130 | devshutdown, 131 | wdattach, 132 | wdwalk, 133 | wdstat, 134 | wdopen, 135 | devcreate, 136 | wdclose, 137 | wdread, 138 | devbread, 139 | wdwrite, 140 | devbwrite, 141 | devremove, 142 | devwstat, 143 | devpower, 144 | }; 145 | -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/mmu64.h: -------------------------------------------------------------------------------- 1 | enum { /* MSRs */ 2 | Efer = 0xC0000080, /* Extended Feature Enable */ 3 | }; 4 | 5 | enum { /* Cr0 */ 6 | Pe = 0x00000001, /* Protected Mode Enable */ 7 | Mp = 0x00000002, /* Monitor Coprocessor */ 8 | Em = 0x00000004, /* Emulate Coprocessor */ 9 | Ts = 0x00000008, /* Task Switched */ 10 | Et = 0x00000010, /* Extension Type */ 11 | Ne = 0x00000020, /* Numeric Error */ 12 | Wp = 0x00010000, /* Write Protect */ 13 | Am = 0x00040000, /* Alignment Mask */ 14 | Nw = 0x20000000, /* Not Writethrough */ 15 | Cd = 0x40000000, /* Cache Disable */ 16 | Pg = 0x80000000, /* Paging Enable */ 17 | }; 18 | 19 | enum { /* Cr3 */ 20 | Pwt = 0x00000008, /* Page-Level Writethrough */ 21 | Pcd = 0x00000010, /* Page-Level Cache Disable */ 22 | }; 23 | 24 | enum { /* Cr4 */ 25 | Vme = 0x00000001, /* Virtual-8086 Mode Extensions */ 26 | Pvi = 0x00000002, /* Protected Mode Virtual Interrupts */ 27 | //Tsd = 0x00000004, /* Time-Stamp Disable */ 28 | De = 0x00000008, /* Debugging Extensions */ 29 | Pse = 0x00000010, /* Page-Size Extensions */ 30 | Pae = 0x00000020, /* Physical Address Extension */ 31 | Mce = 0x00000040, /* Machine Check Enable */ 32 | Pge = 0x00000080, /* Page-Global Enable */ 33 | Pce = 0x00000100, /* Performance Monitoring Counter Enable */ 34 | Osfxsr = 0x00000200, /* FXSAVE/FXRSTOR Support */ 35 | Osxmmexcpt = 0x00000400, /* Unmasked Exception Support */ 36 | }; 37 | 38 | enum { /* Efer */ 39 | Sce = 0x00000001, /* System Call Extension */ 40 | Lme = 0x00000100, /* Long Mode Enable */ 41 | Lma = 0x00000400, /* Long Mode Active */ 42 | Nxe = 0x00000800, /* No-Execute Enable */ 43 | Ffxsr = 0x00004000, /* Fast FXSAVE/FXRSTOR */ 44 | }; 45 | 46 | enum { /* Pte */ 47 | PteP = 0x0000000000000001ULL,/* Present */ 48 | PteRW = 0x0000000000000002ULL,/* Read/Write */ 49 | PteUS = 0x0000000000000004ULL,/* User/Supervisor */ 50 | PtePWT = 0x0000000000000008ULL,/* Page-Level Write Through */ 51 | PtePCD = 0x0000000000000010ULL,/* Page Level Cache Disable */ 52 | PteA = 0x0000000000000020ULL,/* Accessed */ 53 | PteD = 0x0000000000000040ULL,/* Dirty */ 54 | PtePS = 0x0000000000000080ULL,/* Page Size */ 55 | PtePAT0 = PtePS, /* Level 0 PAT */ 56 | PteG = 0x0000000000000100ULL,/* Global */ 57 | PtePAT1 = 0x0000000000000800ULL,/* Level 1 PAT */ 58 | PteNX = 0x8000000000000000ULL,/* No Execute */ 59 | }; 60 | 61 | typedef u64int PTE; 62 | 63 | #define KZERO64 0xFFFFFFFF80000000ULL 64 | 65 | #define PGSIZE64 4096 66 | #define PGSHIFT64 12 /* log(PGSIZE) */ 67 | #define PTESIZE64 512 68 | #define PTESHIFT64 9 /* log(PTESIZE) */ 69 | 70 | #define PTEX64(pi, l) (((pi)>>((((l)-1)*9)+12)) & ((1< (1*MiB - 2*4*KiB)) 29 | return; 30 | sipiptr = UINT2PTR(SIPIHANDLER); 31 | memmove(sipiptr, sipihandler, sizeof(sipihandler)); 32 | DBG("sipiptr %#p sipipa %#llux\n", sipiptr, sipipa); 33 | 34 | /* 35 | * Notes: 36 | * The Universal Startup Algorithm described in the MP Spec. 1.4. 37 | * The data needed per-processor is the sum of the stack, page 38 | * table pages, vsvm page and the Mach page. The layout is similar 39 | * to that described in data.h for the bootstrap processor, but 40 | * with any unused space elided. 41 | */ 42 | for(apicno = 0; apicno < Napic; apicno++){ 43 | apic = &xlapic[apicno]; 44 | if(!apic->useable || apic->addr || apic->machno == 0) 45 | continue; 46 | 47 | /* 48 | * NOTE: for now, share the page tables with the 49 | * bootstrap processor, until the lsipi code is worked out, 50 | * so only the Mach and stack portions are used below. 51 | */ 52 | alloc = mallocalign(MACHSTKSZ+4*PTSZ+4*KiB+MACHSZ, 4096, 0, 0); 53 | if(alloc == nil) 54 | continue; 55 | memset(alloc, 0, MACHSTKSZ+4*PTSZ+4*KiB+MACHSZ); 56 | p = alloc+MACHSTKSZ; 57 | 58 | sipiptr[-1] = mmuphysaddr(PTR2UINT(p)); 59 | DBG("p %#p sipiptr[-1] %#ux\n", p, sipiptr[-1]); 60 | 61 | p += 4*PTSZ+4*KiB; 62 | 63 | /* 64 | * Committed. If the AP startup fails, can't safely 65 | * release the resources, who knows what mischief 66 | * the AP is up to. Perhaps should try to put it 67 | * back into the INIT state? 68 | */ 69 | mach = (Mach*)p; 70 | mach->machno = apic->machno; /* NOT one-to-one... */ 71 | mach->splpc = PTR2UINT(squidboy); 72 | mach->apicno = apicno; 73 | mach->stack = PTR2UINT(alloc); 74 | mach->vsvm = alloc+MACHSTKSZ+4*PTSZ; 75 | //OH OH mach->pml4 = (PTE*)(alloc+MACHSTKSZ); 76 | 77 | p = KADDR(0x467); 78 | *p++ = sipipa; 79 | *p++ = sipipa>>8; 80 | *p++ = 0; 81 | *p = 0; 82 | 83 | nvramwrite(0x0f, 0x0a); 84 | apicsipi(apicno, sipipa); 85 | 86 | for(i = 0; i < 1000; i++){ 87 | if(mach->splpc == 0) 88 | break; 89 | millidelay(5); 90 | } 91 | nvramwrite(0x0f, 0x00); 92 | 93 | DBG("mach %#p (%#p) apicid %d machno %2d %dMHz\n", 94 | mach, sys->machptr[mach->machno], 95 | apicno, mach->machno, mach->cpumhz); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/cga.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | 7 | enum { 8 | Black = 0x00, 9 | Blue = 0x01, 10 | Green = 0x02, 11 | Cyan = 0x03, 12 | Red = 0x04, 13 | Magenta = 0x05, 14 | Brown = 0x06, 15 | Grey = 0x07, 16 | 17 | Bright = 0x08, 18 | Blinking = 0x80, 19 | 20 | Attr = (Black<<4)|Grey, /* (background<<4)|foreground */ 21 | }; 22 | 23 | enum { 24 | Index = 0x3D4, 25 | Data = Index+1, 26 | 27 | Width = 80*2, 28 | Height = 25, 29 | 30 | Poststrlen = 0, 31 | Postcodelen = 2, 32 | Postlen = Poststrlen+Postcodelen, 33 | }; 34 | 35 | #define CGA ((uchar*)KADDR(0xB8000)) 36 | 37 | static Lock cgalock; 38 | static int cgapos; 39 | static int cgainitdone; 40 | 41 | static int 42 | cgaregr(int index) 43 | { 44 | outb(Index, index); 45 | return inb(Data) & 0xFF; 46 | } 47 | 48 | static void 49 | cgaregw(int index, int data) 50 | { 51 | outb(Index, index); 52 | outb(Data, data); 53 | } 54 | 55 | static void 56 | cgacursor(void) 57 | { 58 | uchar *cga; 59 | 60 | cgaregw(0x0E, (cgapos/2>>8) & 0xFF); 61 | cgaregw(0x0F, cgapos/2 & 0xFF); 62 | 63 | cga = CGA; 64 | cga[cgapos+1] = Attr; 65 | } 66 | 67 | static void 68 | cgaputc(int c) 69 | { 70 | int i; 71 | uchar *cga, *p; 72 | 73 | cga = CGA; 74 | 75 | if(c == '\n'){ 76 | cgapos = cgapos/Width; 77 | cgapos = (cgapos+1)*Width; 78 | } 79 | else if(c == '\t'){ 80 | i = 8 - ((cgapos/2)&7); 81 | while(i-- > 0) 82 | cgaputc(' '); 83 | } 84 | else if(c == '\b'){ 85 | if(cgapos >= 2) 86 | cgapos -= 2; 87 | cgaputc(' '); 88 | cgapos -= 2; 89 | } 90 | else{ 91 | cga[cgapos++] = c; 92 | cga[cgapos++] = Attr; 93 | } 94 | if(cgapos >= (Width*Height)-Postlen*2){ 95 | memmove(cga, &cga[Width], Width*(Height-1)); 96 | p = &cga[Width*(Height-1)-Postlen*2]; 97 | for(i = 0; i < Width/2; i++){ 98 | *p++ = ' '; 99 | *p++ = Attr; 100 | } 101 | cgapos -= Width; 102 | } 103 | cgacursor(); 104 | } 105 | 106 | void 107 | cgaconsputs(char* s, int n) 108 | { 109 | ilock(&cgalock); 110 | while(n-- > 0) 111 | cgaputc(*s++); 112 | iunlock(&cgalock); 113 | } 114 | 115 | void 116 | cgapost(int code) 117 | { 118 | uchar *cga; 119 | 120 | static char hex[] = "0123456789ABCDEF"; 121 | 122 | cga = CGA; 123 | cga[Width*Height-Postcodelen*2] = hex[(code>>4) & 0x0F]; 124 | cga[Width*Height-Postcodelen*2+1] = Attr; 125 | cga[Width*Height-Postcodelen*2+2] = hex[code & 0x0F]; 126 | cga[Width*Height-Postcodelen*2+3] = Attr; 127 | } 128 | 129 | void 130 | cgainit(void) 131 | { 132 | ilock(&cgalock); 133 | cgapos = cgaregr(0x0E)<<8; 134 | cgapos |= cgaregr(0x0F); 135 | cgapos *= 2; 136 | cgainitdone = 1; 137 | iunlock(&cgalock); 138 | } 139 | -------------------------------------------------------------------------------- /sys/src/nix/port/error.h: -------------------------------------------------------------------------------- 1 | extern char Enoerror[]; /* no error */ 2 | extern char Emount[]; /* inconsistent mount */ 3 | extern char Eunmount[]; /* not mounted */ 4 | extern char Eismtpt[]; /* is a mount point */ 5 | extern char Eunion[]; /* not in union */ 6 | extern char Emountrpc[]; /* mount rpc error */ 7 | extern char Eshutdown[]; /* device shut down */ 8 | extern char Enocreate[]; /* mounted directory forbids creation */ 9 | extern char Enonexist[]; /* file does not exist */ 10 | extern char Eexist[]; /* file already exists */ 11 | extern char Ebadsharp[]; /* unknown device in # filename */ 12 | extern char Enotdir[]; /* not a directory */ 13 | extern char Eisdir[]; /* file is a directory */ 14 | extern char Ebadchar[]; /* bad character in file name */ 15 | extern char Efilename[]; /* file name syntax */ 16 | extern char Eperm[]; /* permission denied */ 17 | extern char Ebadusefd[]; /* inappropriate use of fd */ 18 | extern char Ebadarg[]; /* bad arg in system call */ 19 | extern char Einuse[]; /* device or object already in use */ 20 | extern char Eio[]; /* i/o error */ 21 | extern char Etoobig[]; /* read or write too large */ 22 | extern char Etoosmall[]; /* read or write too small */ 23 | extern char Enoport[]; /* network port not available */ 24 | extern char Ehungup[]; /* i/o on hungup channel */ 25 | extern char Ebadctl[]; /* bad process or channel control request */ 26 | extern char Enodev[]; /* no free devices */ 27 | extern char Eprocdied[]; /* process exited */ 28 | extern char Enochild[]; /* no living children */ 29 | extern char Eioload[]; /* i/o error in demand load */ 30 | extern char Enovmem[]; /* virtual memory allocation failed */ 31 | extern char Ebadfd[]; /* fd out of range or not open */ 32 | extern char Enofd[]; /* no free file descriptors */ 33 | extern char Eisstream[]; /* seek on a stream */ 34 | extern char Ebadexec[]; /* exec header invalid */ 35 | extern char Etimedout[]; /* connection timed out */ 36 | extern char Econrefused[]; /* connection refused */ 37 | extern char Econinuse[]; /* connection in use */ 38 | extern char Eintr[]; /* interrupted */ 39 | extern char Enomem[]; /* kernel allocate failed */ 40 | extern char Enoswap[]; /* swap space full */ 41 | extern char Esoverlap[]; /* segments overlap */ 42 | extern char Eshort[]; /* i/o count too small */ 43 | extern char Egreg[]; /* ken has left the building */ 44 | extern char Ebadspec[]; /* bad attach specifier */ 45 | extern char Enoreg[]; /* process has no saved registers */ 46 | extern char Enoattach[]; /* mount/attach disallowed */ 47 | extern char Eshortstat[]; /* stat buffer too small */ 48 | extern char Ebadstat[]; /* malformed stat buffer */ 49 | extern char Enegoff[]; /* negative i/o offset */ 50 | extern char Ecmdargs[]; /* wrong #args in control message */ 51 | extern char Ebadip[]; /* bad ip address syntax */ 52 | extern char Edirseek[]; /* seek in directory */ 53 | -------------------------------------------------------------------------------- /sys/src/cmd/rc/tree.c: -------------------------------------------------------------------------------- 1 | #include "rc.h" 2 | #include "exec.h" 3 | #include "io.h" 4 | #include "fns.h" 5 | tree *treenodes; 6 | /* 7 | * create and clear a new tree node, and add it 8 | * to the node list. 9 | */ 10 | 11 | tree* 12 | newtree(void) 13 | { 14 | tree *t = new(tree); 15 | t->iskw = 0; 16 | t->str = 0; 17 | t->child[0] = t->child[1] = t->child[2] = 0; 18 | t->next = treenodes; 19 | treenodes = t; 20 | return t; 21 | } 22 | 23 | void 24 | freenodes(void) 25 | { 26 | tree *t, *u; 27 | for(t = treenodes;t;t = u){ 28 | u = t->next; 29 | if(t->str) 30 | efree(t->str); 31 | efree((char *)t); 32 | } 33 | treenodes = 0; 34 | } 35 | 36 | tree* 37 | tree1(int type, tree *c0) 38 | { 39 | return tree3(type, c0, (tree *)0, (tree *)0); 40 | } 41 | 42 | tree* 43 | tree2(int type, tree *c0, tree *c1) 44 | { 45 | return tree3(type, c0, c1, (tree *)0); 46 | } 47 | 48 | tree* 49 | tree3(int type, tree *c0, tree *c1, tree *c2) 50 | { 51 | tree *t; 52 | if(type==';'){ 53 | if(c0==0) 54 | return c1; 55 | if(c1==0) 56 | return c0; 57 | } 58 | t = newtree(); 59 | t->type = type; 60 | t->child[0] = c0; 61 | t->child[1] = c1; 62 | t->child[2] = c2; 63 | return t; 64 | } 65 | 66 | tree* 67 | mung1(tree *t, tree *c0) 68 | { 69 | t->child[0] = c0; 70 | return t; 71 | } 72 | 73 | tree* 74 | mung2(tree *t, tree *c0, tree *c1) 75 | { 76 | t->child[0] = c0; 77 | t->child[1] = c1; 78 | return t; 79 | } 80 | 81 | tree* 82 | mung3(tree *t, tree *c0, tree *c1, tree *c2) 83 | { 84 | t->child[0] = c0; 85 | t->child[1] = c1; 86 | t->child[2] = c2; 87 | return t; 88 | } 89 | 90 | tree* 91 | epimung(tree *comp, tree *epi) 92 | { 93 | tree *p; 94 | if(epi==0) 95 | return comp; 96 | for(p = epi;p->child[1];p = p->child[1]); 97 | p->child[1] = comp; 98 | return epi; 99 | } 100 | /* 101 | * Add a SIMPLE node at the root of t and percolate all the redirections 102 | * up to the root. 103 | */ 104 | 105 | tree* 106 | simplemung(tree *t) 107 | { 108 | tree *u; 109 | struct io *s; 110 | 111 | t = tree1(SIMPLE, t); 112 | s = openstr(); 113 | pfmt(s, "%t", t); 114 | t->str = strdup((char *)s->strp); 115 | closeio(s); 116 | for(u = t->child[0];u->type==ARGLIST;u = u->child[0]){ 117 | if(u->child[1]->type==DUP 118 | || u->child[1]->type==REDIR){ 119 | u->child[1]->child[1] = t; 120 | t = u->child[1]; 121 | u->child[1] = 0; 122 | } 123 | } 124 | return t; 125 | } 126 | 127 | tree* 128 | token(char *str, int type) 129 | { 130 | tree *t = newtree(); 131 | 132 | t->type = type; 133 | t->str = strdup(str); 134 | return t; 135 | } 136 | 137 | void 138 | freetree(tree *p) 139 | { 140 | if(p==0) 141 | return; 142 | freetree(p->child[0]); 143 | freetree(p->child[1]); 144 | freetree(p->child[2]); 145 | if(p->str) 146 | efree(p->str); 147 | efree((char *)p); 148 | } 149 | -------------------------------------------------------------------------------- /sys/src/nix/ip/chandial.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "../port/error.h" 7 | #include "../ip/ip.h" 8 | 9 | typedef struct DS DS; 10 | static Chan* call(char*, char*, DS*); 11 | static void _dial_string_parse(char*, DS*); 12 | 13 | enum 14 | { 15 | Maxstring= 128, 16 | }; 17 | 18 | struct DS 19 | { 20 | char buf[Maxstring]; /* dist string */ 21 | char *netdir; 22 | char *proto; 23 | char *rem; 24 | char *local; /* other args */ 25 | char *dir; 26 | Chan **ctlp; 27 | }; 28 | 29 | /* 30 | * the dialstring is of the form '[/net/]proto!dest' 31 | */ 32 | Chan* 33 | chandial(char *dest, char *local, char *dir, Chan **ctlp) 34 | { 35 | DS ds; 36 | char clone[Maxpath]; 37 | 38 | ds.local = local; 39 | ds.dir = dir; 40 | ds.ctlp = ctlp; 41 | 42 | _dial_string_parse(dest, &ds); 43 | if(ds.netdir == 0) 44 | ds.netdir = "/net"; 45 | 46 | /* no connection server, don't translate */ 47 | snprint(clone, sizeof(clone), "%s/%s/clone", ds.netdir, ds.proto); 48 | return call(clone, ds.rem, &ds); 49 | } 50 | 51 | static Chan* 52 | call(char *clone, char *dest, DS *ds) 53 | { 54 | int n; 55 | Chan *dchan, *cchan; 56 | char name[Maxpath], data[Maxpath], *p; 57 | 58 | cchan = namec(clone, Aopen, ORDWR, 0); 59 | 60 | /* get directory name */ 61 | if(waserror()){ 62 | cclose(cchan); 63 | nexterror(); 64 | } 65 | n = cchan->dev->read(cchan, name, sizeof(name)-1, 0); 66 | name[n] = 0; 67 | for(p = name; *p == ' '; p++) 68 | ; 69 | sprint(name, "%lud", strtoul(p, 0, 0)); 70 | p = strrchr(clone, '/'); 71 | *p = 0; 72 | if(ds->dir) 73 | snprint(ds->dir, Maxpath, "%s/%s", clone, name); 74 | snprint(data, sizeof(data), "%s/%s/data", clone, name); 75 | 76 | /* connect */ 77 | if(ds->local) 78 | snprint(name, sizeof(name), "connect %s %s", dest, ds->local); 79 | else 80 | snprint(name, sizeof(name), "connect %s", dest); 81 | cchan->dev->write(cchan, name, strlen(name), 0); 82 | 83 | /* open data connection */ 84 | dchan = namec(data, Aopen, ORDWR, 0); 85 | if(ds->ctlp) 86 | *ds->ctlp = cchan; 87 | else 88 | cclose(cchan); 89 | poperror(); 90 | return dchan; 91 | 92 | } 93 | 94 | /* 95 | * parse a dial string 96 | */ 97 | static void 98 | _dial_string_parse(char *str, DS *ds) 99 | { 100 | char *p, *p2; 101 | 102 | strncpy(ds->buf, str, Maxstring); 103 | ds->buf[Maxstring-1] = 0; 104 | 105 | p = strchr(ds->buf, '!'); 106 | if(p == 0) { 107 | ds->netdir = 0; 108 | ds->proto = "net"; 109 | ds->rem = ds->buf; 110 | } else { 111 | if(*ds->buf != '/' && *ds->buf != '#'){ 112 | ds->netdir = 0; 113 | ds->proto = ds->buf; 114 | } else { 115 | for(p2 = p; *p2 != '/'; p2--) 116 | ; 117 | *p2++ = 0; 118 | ds->netdir = ds->buf; 119 | ds->proto = p2; 120 | } 121 | *p = 0; 122 | ds->rem = p + 1; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /sys/src/nix/boot/doauthenticate.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../boot/boot.h" 5 | 6 | static char *pbmsg = "AS protocol botch"; 7 | static char *ccmsg = "can't connect to AS"; 8 | 9 | long 10 | readn(int fd, void *buf, long len) 11 | { 12 | int m, n; 13 | char *p; 14 | 15 | p = buf; 16 | for(n = 0; n < len; n += m){ 17 | m = read(fd, p+n, len-n); 18 | if(m <= 0) 19 | return -1; 20 | } 21 | return n; 22 | } 23 | 24 | static char* 25 | fromauth(Method *mp, char *trbuf, char *tbuf) 26 | { 27 | int afd; 28 | char t; 29 | char *msg; 30 | static char error[2*ERRMAX]; 31 | 32 | if(mp->auth == 0) 33 | fatal("no method for accessing auth server"); 34 | afd = (*mp->auth)(); 35 | if(afd < 0) { 36 | sprint(error, "%s: %r", ccmsg); 37 | return error; 38 | } 39 | 40 | if(write(afd, trbuf, TICKREQLEN) < 0 || read(afd, &t, 1) != 1){ 41 | close(afd); 42 | sprint(error, "%s: %r", pbmsg); 43 | return error; 44 | } 45 | switch(t){ 46 | case AuthOK: 47 | msg = 0; 48 | if(readn(afd, tbuf, 2*TICKETLEN) < 0) { 49 | sprint(error, "%s: %r", pbmsg); 50 | msg = error; 51 | } 52 | break; 53 | case AuthErr: 54 | if(readn(afd, error, ERRMAX) < 0) { 55 | sprint(error, "%s: %r", pbmsg); 56 | msg = error; 57 | } 58 | else { 59 | error[ERRMAX-1] = 0; 60 | msg = error; 61 | } 62 | break; 63 | default: 64 | msg = pbmsg; 65 | break; 66 | } 67 | 68 | close(afd); 69 | return msg; 70 | } 71 | 72 | void 73 | doauthenticate(int fd, Method *mp) 74 | { 75 | char *msg; 76 | char trbuf[TICKREQLEN]; 77 | char tbuf[2*TICKETLEN]; 78 | 79 | print("session..."); 80 | if(fsession(fd, trbuf, sizeof trbuf) < 0) 81 | fatal("session command failed"); 82 | 83 | /* no authentication required? */ 84 | memset(tbuf, 0, 2*TICKETLEN); 85 | if(trbuf[0] == 0) 86 | return; 87 | 88 | /* try getting to an auth server */ 89 | print("getting ticket..."); 90 | msg = fromauth(mp, trbuf, tbuf); 91 | print("authenticating..."); 92 | if(msg == 0) 93 | if(fauth(fd, tbuf) >= 0) 94 | return; 95 | 96 | /* didn't work, go for the security hole */ 97 | fprint(2, "no authentication server (%s), using your key as server key\n", msg); 98 | } 99 | 100 | char* 101 | checkkey(Method *mp, char *name, char *key) 102 | { 103 | char *msg; 104 | Ticketreq tr; 105 | Ticket t; 106 | char trbuf[TICKREQLEN]; 107 | char tbuf[TICKETLEN]; 108 | 109 | memset(&tr, 0, sizeof tr); 110 | tr.type = AuthTreq; 111 | strcpy(tr.authid, name); 112 | strcpy(tr.hostid, name); 113 | strcpy(tr.uid, name); 114 | convTR2M(&tr, trbuf); 115 | msg = fromauth(mp, trbuf, tbuf); 116 | if(msg == ccmsg){ 117 | fprint(2, "boot: can't contact auth server, passwd unchecked\n"); 118 | return 0; 119 | } 120 | if(msg) 121 | return msg; 122 | convM2T(tbuf, &t, key); 123 | if(t.num == AuthTc && strcmp(name, t.cuid)==0) 124 | return 0; 125 | return "no match"; 126 | } 127 | -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/ip.h: -------------------------------------------------------------------------------- 1 | typedef struct Udphdr Udphdr; 2 | struct Udphdr 3 | { 4 | uchar d[6]; /* Ethernet destination */ 5 | uchar s[6]; /* Ethernet source */ 6 | uchar type[2]; /* Ethernet packet type */ 7 | 8 | uchar vihl; /* Version and header length */ 9 | uchar tos; /* Type of service */ 10 | uchar length[2]; /* packet length */ 11 | uchar id[2]; /* Identification */ 12 | uchar frag[2]; /* Fragment information */ 13 | 14 | /* Udp pseudo ip really starts here */ 15 | uchar ttl; 16 | uchar udpproto; /* Protocol */ 17 | uchar udpplen[2]; /* Header plus data length */ 18 | uchar udpsrc[4]; /* Ip source */ 19 | uchar udpdst[4]; /* Ip destination */ 20 | uchar udpsport[2]; /* Source port */ 21 | uchar udpdport[2]; /* Destination port */ 22 | uchar udplen[2]; /* data length */ 23 | uchar udpcksum[2]; /* Checksum */ 24 | }; 25 | 26 | typedef struct Etherhdr Etherhdr; 27 | struct Etherhdr 28 | { 29 | uchar d[6]; 30 | uchar s[6]; 31 | uchar type[2]; 32 | 33 | /* Now we have the ip fields */ 34 | uchar vihl; /* Version and header length */ 35 | uchar tos; /* Type of service */ 36 | uchar length[2]; /* packet length */ 37 | uchar id[2]; /* Identification */ 38 | uchar frag[2]; /* Fragment information */ 39 | uchar ttl; /* Time to live */ 40 | uchar proto; /* Protocol */ 41 | uchar cksum[2]; /* Header checksum */ 42 | uchar src[4]; /* Ip source */ 43 | uchar dst[4]; /* Ip destination */ 44 | }; 45 | 46 | enum 47 | { 48 | IP_VER = 0x40, 49 | IP_HLEN = 0x05, /* v4: Header length in 32-bit words */ 50 | UDP_EHSIZE = 22, 51 | UDP_PHDRSIZE = 12, 52 | UDP_HDRSIZE = 20, 53 | ETHER_HDR = 14, 54 | IP_UDPPROTO = 17, 55 | ET_IP = 0x800, 56 | Bcastip = 0xffffffff, 57 | BPportsrc = 68, 58 | BPportdst = 67, 59 | TFTPport = 69, 60 | Timeout = 5000, /* milliseconds */ 61 | Bootrequest = 1, 62 | Bootreply = 2, 63 | Tftp_READ = 1, 64 | Tftp_WRITE = 2, 65 | Tftp_DATA = 3, 66 | Tftp_ACK = 4, 67 | Tftp_ERROR = 5, 68 | TFTP_SEGSIZE = 512, 69 | TFTP_HDRSIZE = 4, 70 | }; 71 | 72 | typedef struct Bootp Bootp; 73 | struct Bootp 74 | { 75 | uchar op; /* opcode */ 76 | uchar htype; /* hardware type */ 77 | uchar hlen; /* hardware address len */ 78 | uchar hops; /* hops */ 79 | uchar xid[4]; /* a random number */ 80 | uchar secs[2]; /* elapsed since client started booting */ 81 | uchar pad[2]; 82 | uchar ciaddr[4]; /* client IP address (client tells server) */ 83 | uchar yiaddr[4]; /* client IP address (server tells client) */ 84 | uchar siaddr[4]; /* server IP address */ 85 | uchar giaddr[4]; /* gateway IP address */ 86 | uchar chaddr[16]; /* client hardware address */ 87 | char sname[64]; /* server host name (optional) */ 88 | char file[128]; /* boot file name */ 89 | char vend[128]; /* vendor-specific goo */ 90 | }; 91 | 92 | typedef struct Netaddr Netaddr; 93 | struct Netaddr 94 | { 95 | ulong ip; 96 | ushort port; 97 | char ea[Eaddrlen]; 98 | }; 99 | 100 | extern int eipfmt(Fmt*); 101 | -------------------------------------------------------------------------------- /sys/src/nix/k10/k8cpufs: -------------------------------------------------------------------------------- 1 | dev +dev 2 | root 3 | cons 4 | arch 5 | env 6 | pipe 7 | proc 8 | mnt 9 | srv 10 | dup 11 | rtc 12 | ssl 13 | cap 14 | kprof 15 | pmc 16 | segment 17 | 18 | # add to get cec in the kernel 19 | # cec 20 | 21 | ether netif 22 | ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum inferno 23 | 24 | uart 25 | 26 | uart +dev 27 | uarti8250 28 | uartpci pci 29 | pmc +dev 30 | pmcio 31 | 32 | ip +dev 33 | tcp 34 | udp 35 | ipifc 36 | icmp 37 | icmp6 38 | 39 | link +dev 40 | ether8169 pci ethermii 41 | ether82557 pci 42 | ether82563 pci 43 | etherigbe pci ethermii 44 | ethermedium 45 | loopbackmedium 46 | netdevmedium 47 | 48 | # acpi hpet 49 | # ht 50 | 51 | misc +dev 52 | cache 53 | mp apic ioapic pci sipi 54 | 55 | # 56 | #boot cpu 57 | # int cpuflag = 1; 58 | #boot cpu boot $3 59 | # int cpuflag = 1; 60 | # char* bootdisk = "$3"; 61 | #boot rootdir $3 62 | # char* rootdir = "$3"; 63 | #boot (bboot|romboot|dosboot) 64 | # int cpuflag = 1; 65 | # char* bootprog = $2; 66 | #boot boot $3 67 | # char* bootdisk = "$3"; 68 | # 69 | boot cpu 70 | tcp 71 | 72 | rootdir 73 | boot.fs boot 74 | /amd64/bin/rc rc 75 | /rc/lib/rcmain 76 | /amd64/bin/echo echo 77 | /amd64/bin/date date 78 | /amd64/bin/ls ls 79 | /amd64/bin/ps ps 80 | /amd64/bin/bind bind 81 | /amd64/bin/cat cat 82 | /amd64/bin/auth/factotum factotum 83 | /amd64/bin/ip/ipconfig ipconfig 84 | ../root/big big 85 | ../root/nvram nvram 86 | 87 | conf 88 | int cpuserver = 1; 89 | 90 | # 91 | #dbgflg 92 | # chan 'c' 93 | # apic 'A' 94 | # acpi 'C' 95 | # hpet 'H' 96 | # ht 'H' 97 | # ioapic 'I' 98 | # mp 'M' 99 | # pci 'P' 100 | # arch 'V' 101 | # 102 | dbgflg 103 | apic 'A' 104 | acpi 'C' 105 | hpet 'H' 106 | ht 'H' 107 | ioapic 'I' 108 | mp 'M' 109 | arch 'V' 110 | sysproc 'E' 111 | main 'x' 112 | acore 'c' 113 | tcore 'c' 114 | syssem 'S' 115 | page 'p' 116 | pager 'p' 117 | memory 'm' 118 | 119 | amd64 +dev 120 | qqsort 121 | l32p 122 | l64v 123 | l64idt 124 | l64acidt 125 | l64syscall 126 | l64acsyscall 127 | l64fpu 128 | cpuidamd64 129 | acore 130 | arch 131 | archk10 132 | cga 133 | crap 134 | fpu 135 | i8254 136 | i8259 137 | kbd 138 | main 139 | map 140 | memory 141 | mmu 142 | multiboot 143 | random 144 | syscall 145 | tcore 146 | trap 147 | vsvm 148 | 149 | port 150 | alarm 151 | alloc xalloc 152 | allocb 153 | chan 154 | dev 155 | devtab 156 | edf 157 | fault 158 | image 159 | latin1 160 | page 161 | parse 162 | pgrp 163 | portclock 164 | print 165 | proc 166 | ps 167 | qio 168 | qlock 169 | rebootcmd 170 | segment 171 | pager 172 | sysauth 173 | sysfile 174 | sysproc 175 | sysseg 176 | systab 177 | taslock 178 | tod 179 | syssem 180 | syszio 181 | nixcall 182 | 183 | # 184 | #dir 185 | # pc -.I. 186 | # 187 | dir 188 | 386 189 | ip 190 | port 191 | 192 | lib 193 | libc 194 | libip 195 | libsec 196 | -------------------------------------------------------------------------------- /sys/src/nix/port/devdup.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "../port/error.h" 7 | 8 | /* Qid is (2*fd + (file is ctl))+1 */ 9 | 10 | static int 11 | dupgen(Chan *c, char *, Dirtab*, int, int s, Dir *dp) 12 | { 13 | Fgrp *fgrp = up->fgrp; 14 | Chan *f; 15 | static int perm[] = { 0400, 0200, 0600, 0 }; 16 | int p; 17 | Qid q; 18 | 19 | if(s == DEVDOTDOT){ 20 | devdir(c, c->qid, ".", 0, eve, DMDIR|0555, dp); 21 | return 1; 22 | } 23 | if(s == 0) 24 | return 0; 25 | s--; 26 | if(s/2 > fgrp->maxfd) 27 | return -1; 28 | if((f=fgrp->fd[s/2]) == nil) 29 | return 0; 30 | if(s & 1){ 31 | p = 0400; 32 | sprint(up->genbuf, "%dctl", s/2); 33 | }else{ 34 | p = perm[f->mode&3]; 35 | sprint(up->genbuf, "%d", s/2); 36 | } 37 | mkqid(&q, s+1, 0, QTFILE); 38 | devdir(c, q, up->genbuf, 0, eve, p, dp); 39 | return 1; 40 | } 41 | 42 | static Chan* 43 | dupattach(char *spec) 44 | { 45 | return devattach('d', spec); 46 | } 47 | 48 | static Walkqid* 49 | dupwalk(Chan *c, Chan *nc, char **name, int nname) 50 | { 51 | return devwalk(c, nc, name, nname, (Dirtab *)0, 0, dupgen); 52 | } 53 | 54 | static long 55 | dupstat(Chan *c, uchar *db, long n) 56 | { 57 | return devstat(c, db, n, (Dirtab *)0, 0L, dupgen); 58 | } 59 | 60 | static Chan* 61 | dupopen(Chan *c, int omode) 62 | { 63 | Chan *f; 64 | int fd, twicefd; 65 | 66 | if(c->qid.type & QTDIR){ 67 | if(omode != 0) 68 | error(Eisdir); 69 | c->mode = 0; 70 | c->flag |= COPEN; 71 | c->offset = 0; 72 | return c; 73 | } 74 | if(c->qid.type & QTAUTH) 75 | error(Eperm); 76 | twicefd = c->qid.path - 1; 77 | fd = twicefd/2; 78 | if((twicefd & 1)){ 79 | /* ctl file */ 80 | f = c; 81 | f->mode = openmode(omode); 82 | f->flag |= COPEN; 83 | f->offset = 0; 84 | }else{ 85 | /* fd file */ 86 | f = fdtochan(fd, openmode(omode), 0, 1); 87 | cclose(c); 88 | } 89 | if(omode & OCEXEC) 90 | f->flag |= CCEXEC; 91 | return f; 92 | } 93 | 94 | static void 95 | dupclose(Chan*) 96 | { 97 | } 98 | 99 | static long 100 | dupread(Chan *c, void *va, long n, vlong off) 101 | { 102 | char buf[256]; 103 | int fd, twicefd; 104 | 105 | if(c->qid.type & QTDIR) 106 | return devdirread(c, va, n, (Dirtab *)0, 0L, dupgen); 107 | twicefd = c->qid.path - 1; 108 | fd = twicefd/2; 109 | if(twicefd & 1){ 110 | c = fdtochan(fd, -1, 0, 1); 111 | procfdprint(c, fd, 0, buf, sizeof buf); 112 | cclose(c); 113 | return readstr(off, va, n, buf); 114 | } 115 | panic("dupread"); 116 | return 0; 117 | } 118 | 119 | static long 120 | dupwrite(Chan*, void*, long, vlong) 121 | { 122 | error(Eperm); 123 | return 0; /* not reached */ 124 | } 125 | 126 | Dev dupdevtab = { 127 | 'd', 128 | "dup", 129 | 130 | devreset, 131 | devinit, 132 | devshutdown, 133 | dupattach, 134 | dupwalk, 135 | dupstat, 136 | dupopen, 137 | devcreate, 138 | dupclose, 139 | dupread, 140 | devbread, 141 | dupwrite, 142 | devbwrite, 143 | devremove, 144 | devwstat, 145 | }; 146 | -------------------------------------------------------------------------------- /sys/src/cmd/rc/exec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Definitions used in the interpreter 3 | */ 4 | extern void Xappend(void), Xasync(void), Xbackq(void), Xbang(void), Xclose(void); 5 | extern void Xconc(void), Xcount(void), Xdelfn(void), Xdol(void), Xqdol(void), Xdup(void); 6 | extern void Xexit(void), Xfalse(void), Xfn(void), Xfor(void), Xglob(void); 7 | extern void Xjump(void), Xmark(void), Xmatch(void), Xpipe(void), Xread(void); 8 | extern void Xrdwr(void); 9 | extern void Xrdfn(void), Xunredir(void), Xstar(void), Xreturn(void), Xsubshell(void); 10 | extern void Xtrue(void), Xword(void), Xwrite(void), Xpipefd(void), Xcase(void); 11 | extern void Xlocal(void), Xunlocal(void), Xassign(void), Xsimple(void), Xpopm(void); 12 | extern void Xrdcmds(void), Xwastrue(void), Xif(void), Xifnot(void), Xpipewait(void); 13 | extern void Xdelhere(void), Xpopredir(void), Xsub(void), Xeflag(void), Xsettrue(void); 14 | extern void Xerror(char*); 15 | extern void Xerror1(char*); 16 | /* 17 | * word lists are in correct order, 18 | * i.e. word0->word1->word2->word3->0 19 | */ 20 | struct word{ 21 | char *word; 22 | word *next; 23 | }; 24 | struct list{ 25 | word *words; 26 | list *next; 27 | }; 28 | word *newword(char *, word *), *copywords(word *, word *); 29 | struct redir{ 30 | char type; /* what to do */ 31 | short from, to; /* what to do it to */ 32 | struct redir *next; /* what else to do (reverse order) */ 33 | }; 34 | #define NSTATUS ERRMAX /* length of status (from plan 9) */ 35 | /* 36 | * redir types 37 | */ 38 | #define ROPEN 1 /* dup2(from, to); close(from); */ 39 | #define RDUP 2 /* dup2(from, to); */ 40 | #define RCLOSE 3 /* close(from); */ 41 | struct thread{ 42 | union code *code; /* code for this thread */ 43 | int pc; /* code[pc] is the next instruction */ 44 | struct list *argv; /* argument stack */ 45 | struct redir *redir; /* redirection stack */ 46 | struct redir *startredir; /* redir inheritance point */ 47 | struct var *local; /* list of local variables */ 48 | char *cmdfile; /* file name in Xrdcmd */ 49 | struct io *cmdfd; /* file descriptor for Xrdcmd */ 50 | int iflast; /* static `if not' checking */ 51 | int eof; /* is cmdfd at eof? */ 52 | int iflag; /* interactive? */ 53 | int lineno; /* linenumber */ 54 | int pid; /* process for Xpipewait to wait for */ 55 | char status[NSTATUS]; /* status for Xpipewait */ 56 | tree *treenodes; /* tree nodes created by this process */ 57 | thread *ret; /* who continues when this finishes */ 58 | }; 59 | thread *runq; 60 | code *codecopy(code*); 61 | code *codebuf; /* compiler output */ 62 | int ntrap; /* number of outstanding traps */ 63 | int trap[NSIG]; /* number of outstanding traps per type */ 64 | struct builtin{ 65 | char *name; 66 | void (*fnc)(void); 67 | }; 68 | extern struct builtin Builtin[]; 69 | int eflagok; /* kludge flag so that -e doesn't exit in startup */ 70 | int havefork; 71 | 72 | void execcd(void), execwhatis(void), execeval(void), execexec(void); 73 | int execforkexec(void); 74 | void execexit(void), execshift(void); 75 | void execwait(void), execumask(void), execdot(void), execflag(void); 76 | void execfunc(var*), execcmds(io *); 77 | -------------------------------------------------------------------------------- /sys/src/nix/k10/mkfile: -------------------------------------------------------------------------------- 1 | CONF=k8cpu 2 | CONFLIST=k8cpu 3 | 4 | # override with the list of paths where to put extra 5 | # copies of the kernel. for each word $w in OTHERCOPIES, 6 | # the kernel is copied to $w/$objtype/... 7 | OTHERCOPIES='' 8 | 9 | objtype=amd64 10 | $p$CONF.gz 30 | 31 | install:QV: $p$CONF $p$CONF.gz 32 | for(d in '' $OTHERCOPIES){ 33 | if(test -d $d/$objtype){ 34 | cp $p$CONF $d/$objtype/$p$CONF 35 | cp $p$CONF.gz $d/$objtype/$p$CONF.gz 36 | ls -l $d/$objtype/$p$CONF $d/$objtype/$p$CONF.gz 37 | } 38 | } 39 | echo done 40 | 41 | init.out: init9.$O initcode.$O /$objtype/lib/libc.a 42 | $LD -l -R1 -s -o init.out init9.$O initcode.$O -lc 43 | 44 | l32p.$O: ${objtype}l.h 45 | l64idt.$O: ${objtype}l.h 46 | l64syscall.$O: ${objtype}l.h 47 | l64sipi.$O: ${objtype}l.h 48 | l64v.$O: ${objtype}l.h 49 | l64acidt.$O: ${objtype}l.h 50 | l64acsyscall.$O: ${objtype}l.h 51 | 52 | ${objtype}l.h: $objtype.h 53 | rc ../mk/mkenum $objtype.h > $target 54 | 55 | apic.$O: apic.h io.h 56 | devarch.$O: ../port/error.h /$objtype/include/ureg.h 57 | fpu.$O: amd64.h 58 | fpu.$O: /$objtype/include/ureg.h 59 | ioapic.$O: apic.h io.h 60 | main.$O: /sys/include/pool.h init.h 61 | memory.$O: amd64.h 62 | mmu.$O: amd64.h 63 | mp.$O: apic.h 64 | sipi.$O: apic.h sipi.h 65 | svm.$O: amd64.h 66 | svm.$O: /$objtype/include/ureg.h 67 | syscall.$O: ../port/error.h /sys/src/libc/9syscall/sys.h 68 | syscall.$O: /sys/include/tos.h /$objtype/include/ureg.h 69 | syscall.$O: amd64.h 70 | trap.$O: ../port/error.h io.h 71 | trap.$O: /sys/include/tos.h /$objtype/include/ureg.h 72 | 73 | devether.$O: ../port/error.h ../port/netif.h etherif.h 74 | devrtc.$O: ../port/error.h 75 | ether8169.$O: ../port/error.h ../port/ethermii.h ../port/netif.h 76 | ether8169.$O: etherif.h 77 | ether82557.$O: ../port/netif.h 78 | ether82557.$O: etherif.h io.h 79 | etherigbe.$O: ../port/error.h ../port/ethermii.h ../port/netif.h 80 | etherigbe.$O: etherif.h io.h 81 | i8259.$O: io.h 82 | kbd.$O: ../port/error.h io.h 83 | pci.$O: io.h 84 | sdscsi.$O: ../port/error.h 85 | 86 | random.$O: ../port/error.h 87 | devacpi.$O: acpi.h 88 | physalloc.$O: acpi.h 89 | 90 | sipi.h: l64sipi.$O 91 | $LD -o l64sipi.out -T0xfffffffff0003000 -R4 -l -s $prereq 92 | {echo 'uchar sipihandler[]={' 93 | xd -1x l64sipi.out | 94 | sed -e 's/^[0-9a-f]+ //' \ 95 | -e '1,2d' -e '3s/^ .. .. .. .. .. .. .. ..//' \ 96 | -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g' 97 | echo '};'} > $target 98 | 99 | ../root/nvram: 100 | dd -if /dev/zero -of ../root/nvram -bs 512 -count 1 101 | nvram=../root/nvram auth/wrkey 102 | -------------------------------------------------------------------------------- /sys/src/nix/k10/crap.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | 7 | /* 8 | Conf conf; 9 | char *confname[1] = { 10 | "console", 11 | }; 12 | char *confval[1] = { 13 | "0 b115200", 14 | }; 15 | int nconf = nelem(confname); 16 | */ 17 | 18 | /* 19 | * Where configuration info is left for the loaded programme. 20 | * This will turn into a structure as more is done by the boot loader 21 | * (e.g. why parse the .ini file twice?). 22 | * There are 3584 bytes available at CONFADDR. 23 | */ 24 | #define CONFADDR PTR2UINT(KADDR(0x0001200)) 25 | 26 | #define BOOTLINE ((char*)CONFADDR) 27 | #define BOOTLINELEN 64 28 | #define BOOTARGS ((char*)(CONFADDR+BOOTLINELEN)) 29 | #define BOOTARGSLEN (4096-0x200-BOOTLINELEN) 30 | #define MAXCONF 64 31 | 32 | char *confname[MAXCONF]; 33 | char *confval[MAXCONF]; 34 | int nconf; 35 | 36 | void 37 | crapoptions(void) 38 | { 39 | long i, n; 40 | char *cp, *line[MAXCONF], *p, *q; 41 | 42 | /* 43 | * parse configuration args from dos file plan9.ini 44 | */ 45 | cp = BOOTARGS; /* where b.com leaves its config */ 46 | cp[BOOTARGSLEN-1] = 0; 47 | 48 | /* 49 | * Strip out '\r', change '\t' -> ' '. 50 | */ 51 | p = cp; 52 | for(q = cp; *q; q++){ 53 | if(*q == '\r') 54 | continue; 55 | if(*q == '\t') 56 | *q = ' '; 57 | *p++ = *q; 58 | } 59 | *p = 0; 60 | 61 | n = getfields(cp, line, MAXCONF, 1, "\n"); 62 | for(i = 0; i < n; i++){ 63 | if(*line[i] == '#') 64 | continue; 65 | cp = strchr(line[i], '='); 66 | if(cp == nil) 67 | continue; 68 | *cp++ = '\0'; 69 | confname[nconf] = line[i]; 70 | confval[nconf] = cp; 71 | nconf++; 72 | } 73 | } 74 | 75 | char* 76 | getconf(char *name) 77 | { 78 | int i; 79 | 80 | for(i = 0; i < nconf; i++) 81 | if(cistrcmp(confname[i], name) == 0) 82 | return confval[i]; 83 | return 0; 84 | } 85 | 86 | void 87 | confsetenv(void) 88 | { 89 | int i; 90 | 91 | for(i = 0; i < nconf; i++){ 92 | if(confname[i][0] != '*') 93 | ksetenv(confname[i], confval[i], 0); 94 | ksetenv(confname[i], confval[i], 1); 95 | } 96 | } 97 | 98 | int 99 | isaconfig(char *class, int ctlrno, ISAConf *isa) 100 | { 101 | char cc[32], *p; 102 | int i; 103 | 104 | snprint(cc, sizeof cc, "%s%d", class, ctlrno); 105 | p = getconf(cc); 106 | if(p == nil) 107 | return 0; 108 | 109 | isa->type = ""; 110 | isa->nopt = tokenize(p, isa->opt, NISAOPT); 111 | for(i = 0; i < isa->nopt; i++){ 112 | p = isa->opt[i]; 113 | if(cistrncmp(p, "type=", 5) == 0) 114 | isa->type = p + 5; 115 | else if(cistrncmp(p, "port=", 5) == 0) 116 | isa->port = strtoul(p+5, &p, 0); 117 | else if(cistrncmp(p, "irq=", 4) == 0) 118 | isa->irq = strtoul(p+4, &p, 0); 119 | else if(cistrncmp(p, "dma=", 4) == 0) 120 | isa->dma = strtoul(p+4, &p, 0); 121 | else if(cistrncmp(p, "mem=", 4) == 0) 122 | isa->mem = strtoul(p+4, &p, 0); 123 | else if(cistrncmp(p, "size=", 5) == 0) 124 | isa->size = strtoul(p+5, &p, 0); 125 | else if(cistrncmp(p, "freq=", 5) == 0) 126 | isa->freq = strtoul(p+5, &p, 0); 127 | } 128 | return 1; 129 | } 130 | -------------------------------------------------------------------------------- /sys/src/nix/k10/cga.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | 7 | enum { 8 | Black = 0x00, 9 | Blue = 0x01, 10 | Green = 0x02, 11 | Cyan = 0x03, 12 | Red = 0x04, 13 | Magenta = 0x05, 14 | Brown = 0x06, 15 | Grey = 0x07, 16 | 17 | Bright = 0x08, 18 | Blinking = 0x80, 19 | 20 | Attr = (Black<<4)|Grey, /* (background<<4)|foreground */ 21 | }; 22 | 23 | enum { 24 | Index = 0x3d4, 25 | Data = Index+1, 26 | 27 | Width = 80*2, 28 | Height = 25, 29 | 30 | Poststrlen = 0, 31 | Postcodelen = 2, 32 | Postlen = Poststrlen+Postcodelen, 33 | }; 34 | 35 | #define CGA (BIOSSEG(0xb800)) 36 | 37 | static Lock cgalock; 38 | static int cgapos; 39 | static int cgainitdone; 40 | 41 | static int 42 | cgaregr(int index) 43 | { 44 | outb(Index, index); 45 | return inb(Data) & 0xff; 46 | } 47 | 48 | static void 49 | cgaregw(int index, int data) 50 | { 51 | outb(Index, index); 52 | outb(Data, data); 53 | } 54 | 55 | static void 56 | cgacursor(void) 57 | { 58 | uchar *cga; 59 | 60 | cgaregw(0x0e, (cgapos/2>>8) & 0xff); 61 | cgaregw(0x0f, cgapos/2 & 0xff); 62 | 63 | cga = CGA; 64 | cga[cgapos+1] = Attr; 65 | } 66 | 67 | /* 68 | * extern, so we could use it to debug things like 69 | * lock() if necessary. 70 | */ 71 | void 72 | cgaputc(int c) 73 | { 74 | int i; 75 | uchar *cga, *p; 76 | 77 | cga = CGA; 78 | 79 | if(c == '\n'){ 80 | cgapos = cgapos/Width; 81 | cgapos = (cgapos+1)*Width; 82 | } 83 | else if(c == '\t'){ 84 | i = 8 - ((cgapos/2)&7); 85 | while(i-- > 0) 86 | cgaputc(' '); 87 | } 88 | else if(c == '\b'){ 89 | if(cgapos >= 2) 90 | cgapos -= 2; 91 | cgaputc(' '); 92 | cgapos -= 2; 93 | } 94 | else{ 95 | cga[cgapos++] = c; 96 | cga[cgapos++] = Attr; 97 | } 98 | if(cgapos >= (Width*Height)-Postlen*2){ 99 | memmove(cga, &cga[Width], Width*(Height-1)); 100 | p = &cga[Width*(Height-1)-Postlen*2]; 101 | for(i = 0; i < Width/2; i++){ 102 | *p++ = ' '; 103 | *p++ = Attr; 104 | } 105 | cgapos -= Width; 106 | } 107 | cgacursor(); 108 | } 109 | 110 | /* 111 | * debug 112 | */ 113 | void 114 | cgaprinthex(uintptr x) 115 | { 116 | char str[30]; 117 | char *s; 118 | static char dig[] = "0123456789abcdef"; 119 | 120 | str[29] = 0; 121 | s = &str[29]; 122 | while(x != 0){ 123 | *--s = dig[x&0xF]; 124 | x >>= 4; 125 | } 126 | while(*s != 0) 127 | cgaputc(*s++); 128 | cgaputc('\n'); 129 | } 130 | 131 | void 132 | cgaconsputs(char* s, int n) 133 | { 134 | ilock(&cgalock); 135 | while(n-- > 0) 136 | cgaputc(*s++); 137 | iunlock(&cgalock); 138 | } 139 | 140 | void 141 | cgapost(int code) 142 | { 143 | uchar *cga; 144 | 145 | static char hex[] = "0123456789ABCDEF"; 146 | 147 | cga = CGA; 148 | cga[Width*Height-Postcodelen*2] = hex[(code>>4) & 0x0f]; 149 | cga[Width*Height-Postcodelen*2+1] = Attr; 150 | cga[Width*Height-Postcodelen*2+2] = hex[code & 0x0f]; 151 | cga[Width*Height-Postcodelen*2+3] = Attr; 152 | } 153 | 154 | void 155 | cgainit(void) 156 | { 157 | ilock(&cgalock); 158 | cgapos = cgaregr(0x0e)<<8; 159 | cgapos |= cgaregr(0x0f); 160 | cgapos *= 2; 161 | cgainitdone = 1; 162 | iunlock(&cgalock); 163 | } 164 | -------------------------------------------------------------------------------- /sys/src/nix/boot/settime.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "../boot/boot.h" 6 | 7 | static long lusertime(char*); 8 | 9 | char *timeserver = "#s/boot"; 10 | 11 | void 12 | settime(int islocal, int afd, char *rp) 13 | { 14 | int n, f; 15 | int timeset; 16 | Dir dir[2]; 17 | char timebuf[64]; 18 | 19 | print("time..."); 20 | timeset = 0; 21 | if(islocal){ 22 | /* 23 | * set the time from the real time clock 24 | */ 25 | f = open("#r/rtc", ORDWR); 26 | if(f >= 0){ 27 | if((n = read(f, timebuf, sizeof(timebuf)-1)) > 0){ 28 | timebuf[n] = '\0'; 29 | timeset = 1; 30 | } 31 | close(f); 32 | }else do{ 33 | strcpy(timebuf, "yymmddhhmm[ss]"); 34 | outin("\ndate/time ", timebuf, sizeof(timebuf)); 35 | }while((timeset=lusertime(timebuf)) <= 0); 36 | } 37 | if(timeset == 0){ 38 | /* 39 | * set the time from the access time of the root 40 | */ 41 | f = open(timeserver, ORDWR); 42 | if(f < 0) 43 | return; 44 | if(mount(f, afd, "/tmp", MREPL, rp) < 0){ 45 | warning("settime mount"); 46 | close(f); 47 | return; 48 | } 49 | close(f); 50 | if(stat("/tmp", statbuf, sizeof statbuf) < 0) 51 | fatal("stat"); 52 | convM2D(statbuf, sizeof statbuf, &dir[0], (char*)&dir[1]); 53 | sprint(timebuf, "%ld", dir[0].atime); 54 | unmount(0, "/tmp"); 55 | } 56 | 57 | f = open("#c/time", OWRITE); 58 | if(write(f, timebuf, strlen(timebuf)) < 0) 59 | warning("can't set #c/time"); 60 | close(f); 61 | print("\n"); 62 | } 63 | 64 | #define SEC2MIN 60L 65 | #define SEC2HOUR (60L*SEC2MIN) 66 | #define SEC2DAY (24L*SEC2HOUR) 67 | 68 | int 69 | g2(char **pp) 70 | { 71 | int v; 72 | 73 | v = 10*((*pp)[0]-'0') + (*pp)[1]-'0'; 74 | *pp += 2; 75 | return v; 76 | } 77 | 78 | /* 79 | * days per month plus days/year 80 | */ 81 | static int dmsize[] = 82 | { 83 | 365, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 84 | }; 85 | static int ldmsize[] = 86 | { 87 | 366, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 88 | }; 89 | 90 | /* 91 | * return the days/month for the given year 92 | */ 93 | static int * 94 | yrsize(int y) 95 | { 96 | 97 | if((y%4) == 0 && ((y%100) != 0 || (y%400) == 0)) 98 | return ldmsize; 99 | else 100 | return dmsize; 101 | } 102 | 103 | /* 104 | * compute seconds since Jan 1 1970 105 | */ 106 | static long 107 | lusertime(char *argbuf) 108 | { 109 | char *buf; 110 | ulong secs; 111 | int i, y, m; 112 | int *d2m; 113 | 114 | buf = argbuf; 115 | i = strlen(buf); 116 | if(i != 10 && i != 12) 117 | return -1; 118 | secs = 0; 119 | y = g2(&buf); 120 | m = g2(&buf); 121 | if(y < 70) 122 | y += 2000; 123 | else 124 | y += 1900; 125 | 126 | /* 127 | * seconds per year 128 | */ 129 | for(i = 1970; i < y; i++){ 130 | d2m = yrsize(i); 131 | secs += d2m[0] * SEC2DAY; 132 | } 133 | 134 | /* 135 | * seconds per month 136 | */ 137 | d2m = yrsize(y); 138 | for(i = 1; i < m; i++) 139 | secs += d2m[i] * SEC2DAY; 140 | 141 | secs += (g2(&buf)-1) * SEC2DAY; 142 | secs += g2(&buf) * SEC2HOUR; 143 | secs += g2(&buf) * SEC2MIN; 144 | if(*buf) 145 | secs += g2(&buf); 146 | 147 | sprint(argbuf, "%ld", secs); 148 | return secs; 149 | } 150 | -------------------------------------------------------------------------------- /sys/src/nix/port/latin1.h: -------------------------------------------------------------------------------- 1 | " ", " i", L"␣ı", 2 | "!~", "-=~", L"≄≇≉", 3 | "!", "!<=>?bmp", L"¡≮≠≯‽⊄∉⊅", 4 | "\"*", "IUiu", L"ΪΫϊϋ", 5 | "\"", "\"AEIOUYaeiouy", L"¨ÄËÏÖÜŸäëïöüÿ", 6 | "$*", "fhk", L"ϕϑϰ", 7 | "$", "BEFHILMRVaefglopv", L"ℬℰℱℋℐℒℳℛƲɑℯƒℊℓℴ℘ʋ", 8 | "\'\"", "Uu", L"Ǘǘ", 9 | "\'", "\'ACEILNORSUYZacegilnorsuyz", L"´ÁĆÉÍĹŃÓŔŚÚÝŹáćéģíĺńóŕśúýź", 10 | "*", "*ABCDEFGHIKLMNOPQRSTUWXYZabcdefghiklmnopqrstuwxyz", L"∗ΑΒΞΔΕΦΓΘΙΚΛΜΝΟΠΨΡΣΤΥΩΧΗΖαβξδεφγθικλμνοπψρστυωχηζ", 11 | "+", "-O", L"±⊕", 12 | ",", ",ACEGIKLNORSTUacegiklnorstu", L"¸ĄÇĘĢĮĶĻŅǪŖŞŢŲąçęģįķļņǫŗşţų", 13 | "-*", "l", L"ƛ", 14 | "-", "+-2:>DGHILOTZbdghiltuz~", L"∓­ƻ÷→ÐǤĦƗŁ⊖ŦƵƀðǥℏɨłŧʉƶ≂", 15 | ".", ".CEGILOZceglz", L"·ĊĖĠİĿ⊙Żċėġŀż", 16 | "/", "Oo", L"Øø", 17 | "1", ".234568", L"․½⅓¼⅕⅙⅛", 18 | "2", "-.35", L"ƻ‥⅔⅖", 19 | "3", ".458", L"…¾⅗⅜", 20 | "4", "5", L"⅘", 21 | "5", "68", L"⅚⅝", 22 | "7", "8", L"⅞", 23 | ":", "()-=", L"☹☺÷≔", 24 | "~", L"←«≤≶≲", 26 | "=", ":<=>OV", L"≕⋜≡⋝⊜⇒", 27 | ">!", "=~", L"≩⋧", 28 | ">", "<=>~", L"≷≥»≳", 29 | "?", "!?", L"‽¿", 30 | "@\'", "\'", L"ъ", 31 | "@@", "\'EKSTYZekstyz", L"ьЕКСТЫЗекстыз", 32 | "@C", "Hh", L"ЧЧ", 33 | "@E", "Hh", L"ЭЭ", 34 | "@K", "Hh", L"ХХ", 35 | "@S", "CHch", L"ЩШЩШ", 36 | "@T", "Ss", L"ЦЦ", 37 | "@Y", "AEOUaeou", L"ЯЕЁЮЯЕЁЮ", 38 | "@Z", "Hh", L"ЖЖ", 39 | "@c", "h", L"ч", 40 | "@e", "h", L"э", 41 | "@k", "h", L"х", 42 | "@s", "ch", L"щш", 43 | "@t", "s", L"ц", 44 | "@y", "aeou", L"яеёю", 45 | "@z", "h", L"ж", 46 | "@", "ABDFGIJLMNOPRUVXabdfgijlmnopruvx", L"АБДФГИЙЛМНОПРУВХабдфгийлмнопрувх", 47 | "A", "E", L"Æ", 48 | "C", "ACU", L"⋂ℂ⋃", 49 | "Dv", "Zz", L"DŽDž", 50 | "D", "-e", L"Ð∆", 51 | "G", "-", L"Ǥ", 52 | "H", "-H", L"Ħℍ", 53 | "I", "-J", L"ƗIJ", 54 | "L", "&-Jj|", L"⋀ŁLJLj⋁", 55 | "M", "#48bs", L"♮♩♪♭♯", 56 | "N", "JNj", L"NJℕNj", 57 | "O", "*+-./=EIcoprx", L"⊛⊕⊖⊙⊘⊜ŒƢ©⊚℗®⊗", 58 | "P", "P", L"ℙ", 59 | "Q", "Q", L"ℚ", 60 | "R", "R", L"ℝ", 61 | "S", "123S", L"¹²³§", 62 | "T", "-u", L"Ŧ⊨", 63 | "V", "=", L"⇐", 64 | "Y", "R", L"Ʀ", 65 | "Z", "-ACSZ", L"Ƶℤ", 66 | "^", "ACEGHIJOSUWYaceghijosuwy", L"ÂĈÊĜĤÎĴÔŜÛŴŶâĉêĝĥîĵôŝûŵŷ", 67 | "_\"", "AUau", L"ǞǕǟǖ", 68 | "_,", "Oo", L"Ǭǭ", 69 | "_.", "Aa", L"Ǡǡ", 70 | "_", "AEIOU_aeiou", L"ĀĒĪŌŪ¯āēīōū", 71 | "`\"", "Uu", L"Ǜǜ", 72 | "`", "AEIOUaeiou", L"ÀÈÌÒÙàèìòù", 73 | "a", "ben", L"↔æ∠", 74 | "b", "()+-0123456789=bknpqru", L"₍₎₊₋₀₁₂₃₄₅₆₇₈₉₌♝♚♞♟♛♜•", 75 | "c", "$Oagu", L"¢©∩≅∪", 76 | "dv", "z", L"dž", 77 | "d", "-adegz", L"ð↓‡°†ʣ", 78 | "e", "$lmns", L"€⋯—–∅", 79 | "f", "a", L"∀", 80 | "g", "$-r", L"¤ǥ∇", 81 | "h", "-v", L"ℏƕ", 82 | "i", "-bfjps", L"ɨ⊆∞ij⊇∫", 83 | "l", "\"$&\'-jz|", L"“£∧‘łlj⋄∨", 84 | "m", "iou", L"µ∈×", 85 | "n", "jo", L"nj¬", 86 | "o", "AOUaeiu", L"Å⊚Ůåœƣů", 87 | "p", "Odgrt", L"℗∂¶∏∝", 88 | "r", "\"\'O", L"”’®", 89 | "s", "()+-0123456789=abnoprstu", L"⁽⁾⁺⁻⁰ⁱ⁲⁳⁴⁵⁶⁷⁸⁹⁼ª⊂ⁿº⊃√ß∍∑", 90 | "t", "-efmsu", L"ŧ∃∴™ς⊢", 91 | "u", "-AEGIOUaegiou", L"ʉĂĔĞĬŎŬ↑ĕğĭŏŭ", 92 | "v\"", "Uu", L"Ǚǚ", 93 | "v", "ACDEGIKLNORSTUZacdegijklnorstuz", L"ǍČĎĚǦǏǨĽŇǑŘŠŤǓŽǎčďěǧǐǰǩľňǒřšťǔž", 94 | "w", "bknpqr", L"♗♔♘♙♕♖", 95 | "x", "O", L"⊗", 96 | "y", "$", L"¥", 97 | "z", "-", L"ƶ", 98 | "|", "Pp|", L"Þþ¦", 99 | "~!", "=", L"≆", 100 | "~", "-=AINOUainou~", L"≃≅ÃĨÑÕŨãĩñõũ≈", 101 | -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/error.h: -------------------------------------------------------------------------------- 1 | extern char Enoerror[]; /* no error */ 2 | extern char Emount[]; /* inconsistent mount */ 3 | extern char Eunmount[]; /* not mounted */ 4 | extern char Eunion[]; /* not in union */ 5 | extern char Emountrpc[]; /* mount rpc error */ 6 | extern char Eshutdown[]; /* mounted device shut down */ 7 | extern char Enocreate[]; /* mounted directory forbids creation */ 8 | extern char Enonexist[]; /* file does not exist */ 9 | extern char Eexist[]; /* file already exists */ 10 | extern char Ebadsharp[]; /* unknown device in # filename */ 11 | extern char Enotdir[]; /* not a directory */ 12 | extern char Eisdir[]; /* file is a directory */ 13 | extern char Ebadchar[]; /* bad character in file name */ 14 | extern char Efilename[]; /* file name syntax */ 15 | extern char Eperm[]; /* permission denied */ 16 | extern char Ebadusefd[]; /* inappropriate use of fd */ 17 | extern char Ebadarg[]; /* bad arg in system call */ 18 | extern char Einuse[]; /* device or object already in use */ 19 | extern char Eio[]; /* i/o error */ 20 | extern char Etoobig[]; /* read or write too large */ 21 | extern char Etoosmall[]; /* read or write too small */ 22 | extern char Enetaddr[]; /* bad network address */ 23 | extern char Emsgsize[]; /* message is too big for protocol */ 24 | extern char Enetbusy[]; /* network device is busy or allocated */ 25 | extern char Enoproto[]; /* network protocol not supported */ 26 | extern char Enoport[]; /* network port not available */ 27 | extern char Enoifc[]; /* bad interface or no free interface slots */ 28 | extern char Enolisten[]; /* not announced */ 29 | extern char Ehungup[]; /* write to hungup channel */ 30 | extern char Ebadctl[]; /* bad process or channel control request */ 31 | extern char Enodev[]; /* no free devices */ 32 | extern char Enoenv[]; /* no free environment resources */ 33 | extern char Emuxshutdown[]; /* mux server shut down */ 34 | extern char Emuxbusy[]; /* all mux channels busy */ 35 | extern char Emuxmsg[]; /* bad mux message format or mismatch */ 36 | extern char Eprocdied[]; /* process exited */ 37 | extern char Enochild[]; /* no living children */ 38 | extern char Eioload[]; /* i/o error in demand load */ 39 | extern char Enovmem[]; /* virtual memory allocation failed */ 40 | extern char Ebadld[]; /* illegal line discipline */ 41 | extern char Ebadfd[]; /* fd out of range or not open */ 42 | extern char Eisstream[]; /* seek on a stream */ 43 | extern char Ebadexec[]; /* exec header invalid */ 44 | extern char Etimedout[]; /* connection timed out */ 45 | extern char Econrefused[]; /* connection refused */ 46 | extern char Enetunreach[]; /* network unreachable */ 47 | extern char Eintr[]; /* interrupted */ 48 | extern char Eneedservice[]; /* service required for tcp/udp/il calls */ 49 | extern char Enomem[]; /* kernel allocate failed */ 50 | extern char Enoswap[]; /* swap space full */ 51 | extern char Esfnotcached[]; /* subfont not cached */ 52 | extern char Esoverlap[]; /* segments overlap */ 53 | extern char Emouseset[]; /* mouse type already set */ 54 | extern char Erecover[]; /* failed to recover fd */ 55 | extern char Eshort[]; /* i/o count too small */ 56 | extern char Egreg[]; /* ken scheduled it */ 57 | extern char Ebadspec[]; /* bad attach specifier */ 58 | extern char Enoreg[]; /* process has no saved registers */ 59 | -------------------------------------------------------------------------------- /sys/src/cmd/rc/here.c: -------------------------------------------------------------------------------- 1 | #include "rc.h" 2 | #include "exec.h" 3 | #include "io.h" 4 | #include "fns.h" 5 | struct here *here, **ehere; 6 | int ser = 0; 7 | char tmp[]="/tmp/here0000.0000"; 8 | char hex[]="0123456789abcdef"; 9 | 10 | void psubst(io*, uchar*); 11 | void pstrs(io*, word*); 12 | 13 | void 14 | hexnum(char *p, int n) 15 | { 16 | *p++=hex[(n>>12)&0xF]; 17 | *p++=hex[(n>>8)&0xF]; 18 | *p++=hex[(n>>4)&0xF]; 19 | *p = hex[n&0xF]; 20 | } 21 | 22 | tree* 23 | heredoc(tree *tag) 24 | { 25 | struct here *h = new(struct here); 26 | if(tag->type!=WORD) 27 | yyerror("Bad here tag"); 28 | h->next = 0; 29 | if(here) 30 | *ehere = h; 31 | else 32 | here = h; 33 | ehere=&h->next; 34 | h->tag = tag; 35 | hexnum(&tmp[9], getpid()); 36 | hexnum(&tmp[14], ser++); 37 | h->name = strdup(tmp); 38 | return token(tmp, WORD); 39 | } 40 | /* 41 | * bug: lines longer than NLINE get split -- this can cause spurious 42 | * missubstitution, or a misrecognized EOF marker. 43 | */ 44 | #define NLINE 4096 45 | 46 | void 47 | readhere(void) 48 | { 49 | struct here *h, *nexth; 50 | io *f; 51 | char *s, *tag; 52 | int c, subst; 53 | char line[NLINE+1]; 54 | for(h = here;h;h = nexth){ 55 | subst=!h->tag->quoted; 56 | tag = h->tag->str; 57 | c = Creat(h->name); 58 | if(c<0) 59 | yyerror("can't create here document"); 60 | f = openfd(c); 61 | s = line; 62 | pprompt(); 63 | while((c = rchr(runq->cmdfd))!=EOF){ 64 | if(c=='\n' || s==&line[NLINE]){ 65 | *s='\0'; 66 | if(tag && strcmp(line, tag)==0) break; 67 | if(subst) 68 | psubst(f, (uchar *)line); 69 | else 70 | pstr(f, line); 71 | s = line; 72 | if(c=='\n'){ 73 | pprompt(); 74 | pchr(f, c); 75 | } 76 | else *s++=c; 77 | } 78 | else *s++=c; 79 | } 80 | flush(f); 81 | closeio(f); 82 | cleanhere(h->name); 83 | nexth = h->next; 84 | efree((char *)h); 85 | } 86 | here = 0; 87 | doprompt = 1; 88 | } 89 | 90 | void 91 | psubst(io *f, uchar *s) 92 | { 93 | int savec, n; 94 | uchar *t, *u; 95 | word *star; 96 | while(*s){ 97 | if(*s!='$'){ 98 | if(0xa0 <= *s && *s <= 0xf5){ 99 | pchr(f, *s++); 100 | if(*s=='\0') 101 | break; 102 | } 103 | else if(0xf6 <= *s && *s <= 0xf7){ 104 | pchr(f, *s++); 105 | if(*s=='\0') 106 | break; 107 | pchr(f, *s++); 108 | if(*s=='\0') 109 | break; 110 | } 111 | pchr(f, *s++); 112 | } 113 | else{ 114 | t=++s; 115 | if(*t=='$') 116 | pchr(f, *t++); 117 | else{ 118 | while(*t && idchr(*t)) t++; 119 | savec=*t; 120 | *t='\0'; 121 | n = 0; 122 | for(u = s;*u && '0'<=*u && *u<='9';u++) n = n*10+*u-'0'; 123 | if(n && *u=='\0'){ 124 | star = vlook("*")->val; 125 | if(star && 1<=n && n<=count(star)){ 126 | while(--n) star = star->next; 127 | pstr(f, star->word); 128 | } 129 | } 130 | else 131 | pstrs(f, vlook((char *)s)->val); 132 | *t = savec; 133 | if(savec=='^') 134 | t++; 135 | } 136 | s = t; 137 | } 138 | } 139 | } 140 | 141 | void 142 | pstrs(io *f, word *a) 143 | { 144 | if(a){ 145 | while(a->next && a->next->word){ 146 | pstr(f, a->word); 147 | pchr(f, ' '); 148 | a = a->next; 149 | } 150 | pstr(f, a->word); 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /sys/src/nix/port/netif.h: -------------------------------------------------------------------------------- 1 | typedef struct Netaddr Netaddr; 2 | typedef struct Netfile Netfile; 3 | typedef struct Netif Netif; 4 | 5 | enum 6 | { 7 | Nmaxaddr= 64, 8 | Nmhash= 31, 9 | 10 | Ncloneqid= 1, 11 | Naddrqid, 12 | N2ndqid, 13 | N3rdqid, 14 | Ndataqid, 15 | Nctlqid, 16 | Nstatqid, 17 | Ntypeqid, 18 | Nifstatqid, 19 | Nmtuqid, 20 | }; 21 | 22 | /* 23 | * Macros to manage Qid's used for multiplexed devices 24 | */ 25 | #define NETTYPE(x) (((ulong)x)&0x1f) 26 | #define NETID(x) ((((ulong)x))>>5) 27 | #define NETQID(i,t) ((((ulong)i)<<5)|(t)) 28 | 29 | /* 30 | * one per multiplexed connection 31 | */ 32 | struct Netfile 33 | { 34 | QLock; 35 | 36 | int inuse; 37 | ulong mode; 38 | char owner[KNAMELEN]; 39 | 40 | int type; /* multiplexor type */ 41 | int prom; /* promiscuous mode */ 42 | int scan; /* base station scanning interval */ 43 | int bridge; /* bridge mode */ 44 | int headersonly; /* headers only - no data */ 45 | uchar maddr[8]; /* bitmask of multicast addresses requested */ 46 | int nmaddr; /* number of multicast addresses */ 47 | 48 | Queue* iq; /* input */ 49 | }; 50 | 51 | /* 52 | * a network address 53 | */ 54 | struct Netaddr 55 | { 56 | Netaddr *next; /* allocation chain */ 57 | Netaddr *hnext; 58 | uchar addr[Nmaxaddr]; 59 | int ref; 60 | }; 61 | 62 | /* 63 | * a network interface 64 | */ 65 | struct Netif 66 | { 67 | QLock; 68 | 69 | /* multiplexing */ 70 | char name[KNAMELEN]; /* for top level directory */ 71 | int nfile; /* max number of Netfiles */ 72 | Netfile **f; 73 | 74 | /* about net */ 75 | int limit; /* flow control */ 76 | int alen; /* address length */ 77 | int mbps; /* megabits per sec */ 78 | int link; /* link status */ 79 | int minmtu; 80 | int maxmtu; 81 | int mtu; 82 | uchar addr[Nmaxaddr]; 83 | uchar bcast[Nmaxaddr]; 84 | Netaddr *maddr; /* known multicast addresses */ 85 | int nmaddr; /* number of known multicast addresses */ 86 | Netaddr *mhash[Nmhash]; /* hash table of multicast addresses */ 87 | int prom; /* number of promiscuous opens */ 88 | int scan; /* number of base station scanners */ 89 | int all; /* number of -1 multiplexors */ 90 | 91 | Queue* oq; /* output */ 92 | 93 | /* statistics */ 94 | uvlong misses; 95 | uvlong inpackets; 96 | uvlong outpackets; 97 | uvlong crcs; /* input crc errors */ 98 | uvlong oerrs; /* output errors */ 99 | uvlong frames; /* framing errors */ 100 | uvlong overflows; /* packet overflows */ 101 | uvlong buffs; /* buffering errors */ 102 | uvlong soverflows; /* software overflow */ 103 | 104 | /* routines for touching the hardware */ 105 | void *arg; 106 | void (*promiscuous)(void*, int); 107 | void (*multicast)(void*, uchar*, int); 108 | int (*hwmtu)(void*, int); /* get/set mtu */ 109 | void (*scanbs)(void*, uint); /* scan for base stations */ 110 | }; 111 | 112 | void netifinit(Netif*, char*, int, ulong); 113 | Walkqid* netifwalk(Netif*, Chan*, Chan*, char **, int); 114 | Chan* netifopen(Netif*, Chan*, int); 115 | void netifclose(Netif*, Chan*); 116 | long netifread(Netif*, Chan*, void*, long, vlong); 117 | Block* netifbread(Netif*, Chan*, long, vlong); 118 | long netifwrite(Netif*, Chan*, void*, long); 119 | long netifwstat(Netif*, Chan*, uchar*, long); 120 | long netifstat(Netif*, Chan*, uchar*, long); 121 | int activemulti(Netif*, uchar*, int); 122 | -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/lib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * functions (possibly) linked in, complete, from libc. 3 | */ 4 | 5 | /* 6 | * mem routines 7 | */ 8 | extern void* memccpy(void*, void*, int, ulong); 9 | extern void* memset(void*, int, ulong); 10 | extern int memcmp(void*, void*, ulong); 11 | extern void* memmove(void*, void*, ulong); 12 | extern void* memchr(void*, int, ulong); 13 | 14 | /* 15 | * string routines 16 | */ 17 | extern char* strcat(char*, char*); 18 | extern char* strchr(char*, int); 19 | extern int strcmp(char*, char*); 20 | extern char* strcpy(char*, char*); 21 | extern char* strecpy(char*, char*, char*); 22 | extern char* strncat(char*, char*, long); 23 | extern char* strncpy(char*, char*, long); 24 | extern int strncmp(char*, char*, long); 25 | extern long strlen(char*); 26 | extern char* strrchr(char*, char); 27 | extern char* strstr(char*, char*); 28 | 29 | 30 | /* 31 | * print routines 32 | */ 33 | typedef struct Fmt Fmt; 34 | typedef int (*Fmts)(Fmt*); 35 | struct Fmt{ 36 | uchar runes; /* output buffer is runes or chars? */ 37 | void *start; /* of buffer */ 38 | void *to; /* current place in the buffer */ 39 | void *stop; /* end of the buffer; overwritten if flush fails */ 40 | int (*flush)(Fmt *); /* called when to == stop */ 41 | void *farg; /* to make flush a closure */ 42 | int nfmt; /* num chars formatted so far */ 43 | va_list args; /* args passed to dofmt */ 44 | int r; /* % format Rune */ 45 | int width; 46 | int prec; 47 | ulong flags; 48 | }; 49 | extern int print(char*, ...); 50 | extern char* vseprint(char*, char*, char*, va_list); 51 | extern int sprint(char*, char*, ...); 52 | extern int snprint(char*, int, char*, ...); 53 | extern int fmtinstall(int, int (*)(Fmt*)); 54 | extern int fmtstrcpy(Fmt*, char*); 55 | 56 | #pragma varargck argpos fmtprint 2 57 | #pragma varargck argpos print 1 58 | #pragma varargck argpos seprint 3 59 | #pragma varargck argpos snprint 3 60 | #pragma varargck argpos sprint 2 61 | #pragma varargck type "H" void* 62 | 63 | #pragma varargck type "lld" vlong 64 | #pragma varargck type "llx" vlong 65 | #pragma varargck type "lld" uvlong 66 | #pragma varargck type "llx" uvlong 67 | #pragma varargck type "ld" long 68 | #pragma varargck type "lx" long 69 | #pragma varargck type "ld" ulong 70 | #pragma varargck type "lx" ulong 71 | #pragma varargck type "d" int 72 | #pragma varargck type "x" int 73 | #pragma varargck type "c" int 74 | #pragma varargck type "C" int 75 | #pragma varargck type "d" uint 76 | #pragma varargck type "x" uint 77 | #pragma varargck type "c" uint 78 | #pragma varargck type "C" uint 79 | #pragma varargck type "f" double 80 | #pragma varargck type "e" double 81 | #pragma varargck type "g" double 82 | #pragma varargck type "s" char* 83 | #pragma varargck type "q" char* 84 | #pragma varargck type "S" Rune* 85 | #pragma varargck type "Q" Rune* 86 | #pragma varargck type "r" void 87 | #pragma varargck type "%" void 88 | #pragma varargck type "|" int 89 | #pragma varargck type "p" uintptr 90 | #pragma varargck type "p" void* 91 | #pragma varargck type "lux" void* 92 | #pragma varargck type "E" uchar* 93 | 94 | #define PRINTSIZE 256 95 | 96 | /* 97 | * one-of-a-kind 98 | */ 99 | extern int atoi(char*); 100 | extern ulong getcallerpc(void*); 101 | extern long strtol(char*, char**, int); 102 | extern ulong strtoul(char*, char**, int); 103 | extern char end[]; 104 | 105 | #define NAMELEN 28 106 | -------------------------------------------------------------------------------- /sys/src/cmd/rc/pcmd.c: -------------------------------------------------------------------------------- 1 | #include "rc.h" 2 | #include "io.h" 3 | #include "fns.h" 4 | char nl='\n'; /* change to semicolon for bourne-proofing */ 5 | #define c0 t->child[0] 6 | #define c1 t->child[1] 7 | #define c2 t->child[2] 8 | 9 | void 10 | pdeglob(io *f, char *s) 11 | { 12 | while(*s){ 13 | if(*s==GLOB) 14 | s++; 15 | pchr(f, *s++); 16 | } 17 | } 18 | 19 | void 20 | pcmd(io *f, tree *t) 21 | { 22 | if(t==0) 23 | return; 24 | switch(t->type){ 25 | default: pfmt(f, "bad %d %p %p %p", t->type, c0, c1, c2); 26 | break; 27 | case '$': pfmt(f, "$%t", c0); 28 | break; 29 | case '"': pfmt(f, "$\"%t", c0); 30 | break; 31 | case '&': pfmt(f, "%t&", c0); 32 | break; 33 | case '^': pfmt(f, "%t^%t", c0, c1); 34 | break; 35 | case '`': pfmt(f, "`%t", c0); 36 | break; 37 | case ANDAND: pfmt(f, "%t && %t", c0, c1); 38 | break; 39 | case BANG: pfmt(f, "! %t", c0); 40 | break; 41 | case BRACE: pfmt(f, "{%t}", c0); 42 | break; 43 | case COUNT: pfmt(f, "$#%t", c0); 44 | break; 45 | case FN: pfmt(f, "fn %t %t", c0, c1); 46 | break; 47 | case IF: pfmt(f, "if%t%t", c0, c1); 48 | break; 49 | case NOT: pfmt(f, "if not %t", c0); 50 | break; 51 | case OROR: pfmt(f, "%t || %t", c0, c1); 52 | break; 53 | case PCMD: 54 | case PAREN: pfmt(f, "(%t)", c0); 55 | break; 56 | case SUB: pfmt(f, "$%t(%t)", c0, c1); 57 | break; 58 | case SIMPLE: pfmt(f, "%t", c0); 59 | break; 60 | case SUBSHELL: pfmt(f, "@ %t", c0); 61 | break; 62 | case SWITCH: pfmt(f, "switch %t %t", c0, c1); 63 | break; 64 | case TWIDDLE: pfmt(f, "~ %t %t", c0, c1); 65 | break; 66 | case WHILE: pfmt(f, "while %t%t", c0, c1); 67 | break; 68 | case ARGLIST: 69 | if(c0==0) 70 | pfmt(f, "%t", c1); 71 | else if(c1==0) 72 | pfmt(f, "%t", c0); 73 | else 74 | pfmt(f, "%t %t", c0, c1); 75 | break; 76 | case ';': 77 | if(c0){ 78 | if(c1) 79 | pfmt(f, "%t%c%t", c0, nl, c1); 80 | else pfmt(f, "%t", c0); 81 | } 82 | else pfmt(f, "%t", c1); 83 | break; 84 | case WORDS: 85 | if(c0) 86 | pfmt(f, "%t ", c0); 87 | pfmt(f, "%t", c1); 88 | break; 89 | case FOR: 90 | pfmt(f, "for(%t", c0); 91 | if(c1) 92 | pfmt(f, " in %t", c1); 93 | pfmt(f, ")%t", c2); 94 | break; 95 | case WORD: 96 | if(t->quoted) 97 | pfmt(f, "%Q", t->str); 98 | else pdeglob(f, t->str); 99 | break; 100 | case DUP: 101 | if(t->rtype==DUPFD) 102 | pfmt(f, ">[%d=%d]", t->fd1, t->fd0); /* yes, fd1, then fd0; read lex.c */ 103 | else 104 | pfmt(f, ">[%d=]", t->fd0); 105 | pfmt(f, "%t", c1); 106 | break; 107 | case PIPEFD: 108 | case REDIR: 109 | switch(t->rtype){ 110 | case HERE: 111 | pchr(f, '<'); 112 | case READ: 113 | case RDWR: 114 | pchr(f, '<'); 115 | if(t->rtype==RDWR) 116 | pchr(f, '>'); 117 | if(t->fd0!=0) 118 | pfmt(f, "[%d]", t->fd0); 119 | break; 120 | case APPEND: 121 | pchr(f, '>'); 122 | case WRITE: 123 | pchr(f, '>'); 124 | if(t->fd0!=1) 125 | pfmt(f, "[%d]", t->fd0); 126 | break; 127 | } 128 | pfmt(f, "%t", c0); 129 | if(c1) 130 | pfmt(f, " %t", c1); 131 | break; 132 | case '=': 133 | pfmt(f, "%t=%t", c0, c1); 134 | if(c2) 135 | pfmt(f, " %t", c2); 136 | break; 137 | case PIPE: 138 | pfmt(f, "%t|", c0); 139 | if(t->fd1==0){ 140 | if(t->fd0!=1) 141 | pfmt(f, "[%d]", t->fd0); 142 | } 143 | else pfmt(f, "[%d=%d]", t->fd0, t->fd1); 144 | pfmt(f, "%t", c1); 145 | break; 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /sys/src/cmd/rc/syn.y: -------------------------------------------------------------------------------- 1 | %term FOR IN WHILE IF NOT TWIDDLE BANG SUBSHELL SWITCH FN 2 | %term WORD REDIR DUP PIPE SUB 3 | %term SIMPLE ARGLIST WORDS BRACE PAREN PCMD PIPEFD /* not used in syntax */ 4 | /* operator priorities -- lowest first */ 5 | %left IF WHILE FOR SWITCH ')' NOT 6 | %left ANDAND OROR 7 | %left BANG SUBSHELL 8 | %left PIPE 9 | %left '^' 10 | %right '$' COUNT '"' 11 | %left SUB 12 | %{ 13 | #include "rc.h" 14 | #include "fns.h" 15 | %} 16 | %union{ 17 | struct tree *tree; 18 | }; 19 | %type line paren brace body cmdsa cmdsan assign epilog redir 20 | %type cmd simple first word comword keyword words 21 | %type NOT FOR IN WHILE IF TWIDDLE BANG SUBSHELL SWITCH FN 22 | %type WORD REDIR DUP PIPE 23 | %% 24 | rc: { return 1;} 25 | | line '\n' {return !compile($1);} 26 | line: cmd 27 | | cmdsa line {$$=tree2(';', $1, $2);} 28 | body: cmd 29 | | cmdsan body {$$=tree2(';', $1, $2);} 30 | cmdsa: cmd ';' 31 | | cmd '&' {$$=tree1('&', $1);} 32 | cmdsan: cmdsa 33 | | cmd '\n' 34 | brace: '{' body '}' {$$=tree1(BRACE, $2);} 35 | paren: '(' body ')' {$$=tree1(PCMD, $2);} 36 | assign: first '=' word {$$=tree2('=', $1, $3);} 37 | epilog: {$$=0;} 38 | | redir epilog {$$=mung2($1, $1->child[0], $2);} 39 | redir: REDIR word {$$=mung1($1, $1->rtype==HERE?heredoc($2):$2);} 40 | | DUP 41 | cmd: {$$=0;} 42 | | brace epilog {$$=epimung($1, $2);} 43 | | IF paren {skipnl();} cmd 44 | {$$=mung2($1, $2, $4);} 45 | | IF NOT {skipnl();} cmd {$$=mung1($2, $4);} 46 | | FOR '(' word IN words ')' {skipnl();} cmd 47 | /* 48 | * if ``words'' is nil, we need a tree element to distinguish between 49 | * for(i in ) and for(i), the former being a loop over the empty set 50 | * and the latter being the implicit argument loop. so if $5 is nil 51 | * (the empty set), we represent it as "()". don't parenthesize non-nil 52 | * functions, to avoid growing parentheses every time we reread the 53 | * definition. 54 | */ 55 | {$$=mung3($1, $3, $5 ? $5 : tree1(PAREN, $5), $8);} 56 | | FOR '(' word ')' {skipnl();} cmd 57 | {$$=mung3($1, $3, (struct tree *)0, $6);} 58 | | WHILE paren {skipnl();} cmd 59 | {$$=mung2($1, $2, $4);} 60 | | SWITCH word {skipnl();} brace 61 | {$$=tree2(SWITCH, $2, $4);} 62 | | simple {$$=simplemung($1);} 63 | | TWIDDLE word words {$$=mung2($1, $2, $3);} 64 | | cmd ANDAND cmd {$$=tree2(ANDAND, $1, $3);} 65 | | cmd OROR cmd {$$=tree2(OROR, $1, $3);} 66 | | cmd PIPE cmd {$$=mung2($2, $1, $3);} 67 | | redir cmd %prec BANG {$$=mung2($1, $1->child[0], $2);} 68 | | assign cmd %prec BANG {$$=mung3($1, $1->child[0], $1->child[1], $2);} 69 | | BANG cmd {$$=mung1($1, $2);} 70 | | SUBSHELL cmd {$$=mung1($1, $2);} 71 | | FN words brace {$$=tree2(FN, $2, $3);} 72 | | FN words {$$=tree1(FN, $2);} 73 | simple: first 74 | | simple word {$$=tree2(ARGLIST, $1, $2);} 75 | | simple redir {$$=tree2(ARGLIST, $1, $2);} 76 | first: comword 77 | | first '^' word {$$=tree2('^', $1, $3);} 78 | word: keyword {lastword=1; $1->type=WORD;} 79 | | comword 80 | | word '^' word {$$=tree2('^', $1, $3);} 81 | comword: '$' word {$$=tree1('$', $2);} 82 | | '$' word SUB words ')' {$$=tree2(SUB, $2, $4);} 83 | | '"' word {$$=tree1('"', $2);} 84 | | COUNT word {$$=tree1(COUNT, $2);} 85 | | WORD 86 | | '`' brace {$$=tree1('`', $2);} 87 | | '(' words ')' {$$=tree1(PAREN, $2);} 88 | | REDIR brace {$$=mung1($1, $2); $$->type=PIPEFD;} 89 | keyword: FOR|IN|WHILE|IF|NOT|TWIDDLE|BANG|SUBSHELL|SWITCH|FN 90 | words: {$$=(struct tree*)0;} 91 | | words word {$$=tree2(WORDS, $1, $2);} 92 | -------------------------------------------------------------------------------- /sys/src/nix/ip/netdevmedium.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "../port/lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "../port/error.h" 7 | 8 | #include "ip.h" 9 | 10 | static void netdevbind(Ipifc *ifc, int argc, char **argv); 11 | static void netdevunbind(Ipifc *ifc); 12 | static void netdevbwrite(Ipifc *ifc, Block *bp, int version, uchar *ip); 13 | static void netdevread(void *a); 14 | 15 | typedef struct Netdevrock Netdevrock; 16 | struct Netdevrock 17 | { 18 | Fs *f; /* file system we belong to */ 19 | Proc *readp; /* reading process */ 20 | Chan *mchan; /* Data channel */ 21 | }; 22 | 23 | Medium netdevmedium = 24 | { 25 | .name= "netdev", 26 | .hsize= 0, 27 | .mintu= 0, 28 | .maxtu= 64000, 29 | .maclen= 0, 30 | .bind= netdevbind, 31 | .unbind= netdevunbind, 32 | .bwrite= netdevbwrite, 33 | .unbindonclose= 0, 34 | }; 35 | 36 | /* 37 | * called to bind an IP ifc to a generic network device 38 | * called with ifc qlock'd 39 | */ 40 | static void 41 | netdevbind(Ipifc *ifc, int argc, char **argv) 42 | { 43 | Chan *mchan; 44 | Netdevrock *er; 45 | 46 | if(argc < 2) 47 | error(Ebadarg); 48 | 49 | mchan = namec(argv[2], Aopen, ORDWR, 0); 50 | 51 | er = smalloc(sizeof(*er)); 52 | er->mchan = mchan; 53 | er->f = ifc->conv->p->f; 54 | 55 | ifc->arg = er; 56 | 57 | kproc("netdevread", netdevread, ifc); 58 | } 59 | 60 | /* 61 | * called with ifc wlock'd 62 | */ 63 | static void 64 | netdevunbind(Ipifc *ifc) 65 | { 66 | Netdevrock *er = ifc->arg; 67 | 68 | if(er->readp != nil) 69 | postnote(er->readp, 1, "unbind", NUser); 70 | 71 | /* wait for readers to die */ 72 | while(er->readp != nil) 73 | tsleep(&up->sleep, return0, 0, 300); 74 | 75 | if(er->mchan != nil) 76 | cclose(er->mchan); 77 | 78 | free(er); 79 | } 80 | 81 | /* 82 | * called by ipoput with a single block to write 83 | */ 84 | static void 85 | netdevbwrite(Ipifc *ifc, Block *bp, int, uchar*) 86 | { 87 | Netdevrock *er = ifc->arg; 88 | 89 | if(bp->next) 90 | bp = concatblock(bp); 91 | if(BLEN(bp) < ifc->mintu) 92 | bp = adjustblock(bp, ifc->mintu); 93 | 94 | er->mchan->dev->bwrite(er->mchan, bp, 0); 95 | ifc->out++; 96 | } 97 | 98 | /* 99 | * process to read from the device 100 | */ 101 | static void 102 | netdevread(void *a) 103 | { 104 | Ipifc *ifc; 105 | Block *bp; 106 | Netdevrock *er; 107 | char *argv[1]; 108 | 109 | ifc = a; 110 | er = ifc->arg; 111 | er->readp = up; /* hide identity under a rock for unbind */ 112 | if(waserror()){ 113 | er->readp = nil; 114 | pexit("hangup", 1); 115 | } 116 | for(;;){ 117 | bp = er->mchan->dev->bread(er->mchan, ifc->maxtu, 0); 118 | if(bp == nil){ 119 | /* 120 | * get here if mchan is a pipe and other side hangs up 121 | * clean up this interface & get out 122 | ZZZ is this a good idea? 123 | */ 124 | poperror(); 125 | er->readp = nil; 126 | argv[0] = "unbind"; 127 | if(!waserror()) 128 | ifc->conv->p->ctl(ifc->conv, argv, 1); 129 | pexit("hangup", 1); 130 | } 131 | if(!canrlock(ifc)){ 132 | freeb(bp); 133 | continue; 134 | } 135 | if(waserror()){ 136 | runlock(ifc); 137 | nexterror(); 138 | } 139 | ifc->in++; 140 | if(ifc->lifc == nil) 141 | freeb(bp); 142 | else 143 | ipiput4(er->f, ifc, bp); 144 | runlock(ifc); 145 | poperror(); 146 | } 147 | } 148 | 149 | void 150 | netdevmediumlink(void) 151 | { 152 | addipmedium(&netdevmedium); 153 | } 154 | -------------------------------------------------------------------------------- /sys/src/nix/w/pxeload/warp64.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "mem.h" 4 | #include "dat.h" 5 | #include "fns.h" 6 | #include "io.h" 7 | 8 | #include "mmu64.h" 9 | 10 | #define Pml4 0x00108000 11 | 12 | typedef unsigned long long u64intptr; 13 | 14 | #define u64ptr2int(p) ((u64intptr)(p)) 15 | #define u64int2ptr(i) ((void*)(i)) 16 | 17 | static u64intptr 18 | mach0ptalloc(int l) 19 | { 20 | static u64intptr table = Pml4; 21 | static int ntable = 6; 22 | 23 | if(ntable <= 0) 24 | return ~0ULL; 25 | 26 | table += PGSIZE64; 27 | memset(KADDR(table), 0, PGSIZE64); 28 | ntable--; 29 | if(vflag) 30 | print("table[%d] used 0x%llux\n", l, table); 31 | 32 | return table; 33 | } 34 | 35 | PTE* 36 | mmuwalk64(PTE* pml4, u64intptr va, int level, u64intptr (*alloc)(int)) 37 | { 38 | int l, idx; 39 | PTE *pte; 40 | u64intptr pa; 41 | 42 | idx = PTEX64(va, 4); 43 | pte = &pml4[idx]; 44 | for(l = 4; l > 0; l--){ 45 | if(vflag) 46 | print("mmuwalk64 0x%p 0x%llux %d: entry %d\n", 47 | pml4, va, l, idx); 48 | if(l == level) 49 | return pte; 50 | if(l == 2 && (*pte & PtePS)) 51 | break; 52 | if(!(*pte & PteP)){ 53 | if(alloc == nil) 54 | break; 55 | pa = alloc(l); 56 | if(pa == ~0ULL) 57 | break; 58 | *pte = pa|PteRW|PteP; 59 | if(vflag) 60 | print("mmuwalk64 0x%p 0x%llux %d: alloc 0x%llux\n", 61 | pml4, va, l, pa); 62 | } 63 | pte = u64int2ptr(KADDR(PPN64(*pte))); 64 | idx = PTEX64(va, l-1); 65 | pte += idx; 66 | } 67 | 68 | return nil; 69 | } 70 | 71 | void 72 | mkmach0pt(u64intptr kzero64) 73 | { 74 | //u32int r; 75 | u64intptr pa, va; 76 | PTE *pml4, *pte, *pte0; 77 | //uvlong uvlr; 78 | 79 | pml4 = u64int2ptr(KADDR(Pml4)); 80 | if(vflag) 81 | print("pml4 = %p\n", pml4); 82 | memset(pml4, 0, PGSIZE64); 83 | 84 | va = kzero64; 85 | for(pa = 0; pa < 4*MiB; pa += 2*MiB){ 86 | pte = mmuwalk64(pml4, va, 2, mach0ptalloc); 87 | *pte = (PPN64(pa))|PtePS|PteRW|PteP; 88 | if(vflag) 89 | print("va %#llux pte %#p *pte %#llux\n", va, pte, *pte); 90 | va += 2*MiB; 91 | } 92 | pte = mmuwalk64(pml4, kzero64, 4, 0); 93 | if(vflag) 94 | print("pte l4 %llux == 0x%llux\n", kzero64, *pte); 95 | 96 | pte0 = mmuwalk64(pml4, 0ULL, 2, mach0ptalloc); 97 | pte0 += PTEX64(0, 2); 98 | if(vflag) 99 | print("pte0 l2 @ 0x%p 0 == 0x%llux\n", pte0, *pte0); 100 | *pte0 = (PPN64(0))|PtePS|PteRW|PteP; 101 | if(vflag) 102 | print("pte0 l2 @ 0x%p 0 == 0x%llux\n", pte0, *pte0); 103 | 104 | /* 105 | * Have to do this with paging turned off. Bugger. 106 | r = getcr4(); 107 | r |= Pae; 108 | putcr4(r); 109 | 110 | r = getcr3(); 111 | putcr3(Pml4); 112 | 113 | rdmsr(Efer, &uvlr); 114 | uvlr |= Lme; 115 | wrmsr(Efer, uvlr); 116 | */ 117 | } 118 | 119 | void 120 | warp64(uvlong entry) 121 | { 122 | u64intptr kzero64; 123 | extern void _warp64(ulong); 124 | 125 | // kzero64 = KZERO64; 126 | // if(entry != 0xFFFFFFFF80110000ULL){ 127 | // print("bad entry address %#llux\n", entry); 128 | // return; 129 | // } 130 | kzero64 = entry & ~0x000000000fffffffull; 131 | print("warp64(%#llux) %#llux %d\n", entry, kzero64, nmmap); 132 | if(vflag) 133 | print("mkmultiboot\n"); 134 | mkmultiboot(); 135 | if(vflag) 136 | print("mkmach0pt\n"); 137 | mkmach0pt(kzero64); 138 | if(vflag) 139 | print("impulse\n"); 140 | 141 | /* 142 | * No output after impulse(). 143 | */ 144 | if(vflag) 145 | print("_warp64\n"); 146 | impulse(); 147 | _warp64(Pml4); 148 | } 149 | -------------------------------------------------------------------------------- /sys/src/libc/9syscall/mkfile: -------------------------------------------------------------------------------- 1 | NPROC=1 2 | $i.s 133 | $AS $i.s 134 | } 135 | ar vu /$objtype/lib/libc.a *.$O 136 | rm -f *.$O *.s 137 | 138 | nuke clean:V: 139 | rm -f *.[$OS] 140 | 141 | installall:V: 142 | for(objtype in $CPUS) mk install 143 | 144 | update:V: 145 | update $UPDATEFLAGS mkfile sys.h 146 | -------------------------------------------------------------------------------- /sys/src/nix/port/sd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Storage Device. 3 | */ 4 | typedef struct SDev SDev; 5 | typedef struct SDifc SDifc; 6 | typedef struct SDpart SDpart; 7 | typedef struct SDperm SDperm; 8 | typedef struct SDreq SDreq; 9 | typedef struct SDunit SDunit; 10 | 11 | struct SDperm { 12 | char* name; 13 | char* user; 14 | ulong perm; 15 | }; 16 | 17 | struct SDpart { 18 | uvlong start; 19 | uvlong end; 20 | SDperm; 21 | int valid; 22 | ulong vers; 23 | }; 24 | 25 | struct SDunit { 26 | SDev* dev; 27 | int subno; 28 | uchar inquiry[255]; /* format follows SCSI spec */ 29 | uchar sense[18]; /* format follows SCSI spec */ 30 | SDperm; 31 | 32 | QLock ctl; 33 | uvlong sectors; 34 | ulong secsize; 35 | SDpart* part; /* nil or array of size npart */ 36 | int npart; 37 | ulong vers; 38 | SDperm ctlperm; 39 | 40 | QLock raw; /* raw read or write in progress */ 41 | ulong rawinuse; /* really just a test-and-set */ 42 | int state; 43 | SDreq* req; 44 | SDperm rawperm; 45 | }; 46 | 47 | /* 48 | * Each controller is represented by a SDev. 49 | */ 50 | struct SDev { 51 | Ref r; /* Number of callers using device */ 52 | SDifc* ifc; /* pnp/legacy */ 53 | void* ctlr; 54 | int idno; 55 | char name[8]; 56 | SDev* next; 57 | 58 | QLock; /* enable/disable */ 59 | int enabled; 60 | int nunit; /* Number of units */ 61 | QLock unitlock; /* `Loading' of units */ 62 | int* unitflg; /* Unit flags */ 63 | SDunit**unit; 64 | }; 65 | 66 | struct SDifc { 67 | char* name; 68 | 69 | SDev* (*pnp)(void); 70 | SDev* (*legacy)(int, int); 71 | int (*enable)(SDev*); 72 | int (*disable)(SDev*); 73 | 74 | int (*verify)(SDunit*); 75 | int (*online)(SDunit*); 76 | int (*rio)(SDreq*); 77 | int (*rctl)(SDunit*, char*, int); 78 | int (*wctl)(SDunit*, Cmdbuf*); 79 | 80 | long (*bio)(SDunit*, int, int, void*, long, vlong); 81 | SDev* (*probe)(DevConf*); 82 | void (*clear)(SDev*); 83 | char* (*rtopctl)(SDev*, char*, char*); 84 | int (*wtopctl)(SDev*, Cmdbuf*); 85 | }; 86 | 87 | struct SDreq { 88 | SDunit* unit; 89 | int lun; 90 | int write; 91 | uchar cmd[16]; 92 | int clen; 93 | void* data; 94 | int dlen; 95 | 96 | int flags; 97 | 98 | int status; 99 | long rlen; 100 | uchar sense[256]; 101 | }; 102 | 103 | enum { 104 | SDnosense = 0x00000001, 105 | SDvalidsense = 0x00010000, 106 | }; 107 | 108 | enum { 109 | SDretry = -5, /* internal to controllers */ 110 | SDmalloc = -4, 111 | SDeio = -3, 112 | SDtimeout = -2, 113 | SDnostatus = -1, 114 | 115 | SDok = 0, 116 | 117 | SDcheck = 0x02, /* check condition */ 118 | SDbusy = 0x08, /* busy */ 119 | 120 | SDmaxio = 2048*1024, 121 | SDnpart = 16, 122 | }; 123 | 124 | #define sdmalloc(n) malloc(n) 125 | #define sdfree(p) free(p) 126 | 127 | /* devsd.c */ 128 | extern void sdadddevs(SDev*); 129 | extern int sdsetsense(SDreq*, int, int, int, int); 130 | extern int sdmodesense(SDreq*, uchar*, void*, int); 131 | extern int sdfakescsi(SDreq*, void*, int); 132 | 133 | /* sdscsi.c */ 134 | extern int scsiverify(SDunit*); 135 | extern int scsionline(SDunit*); 136 | extern long scsibio(SDunit*, int, int, void*, long, vlong); 137 | extern SDev* scsiid(SDev*, SDifc*); 138 | 139 | /* 140 | * hardware info about a device 141 | */ 142 | typedef struct { 143 | ulong port; 144 | int size; 145 | } Devport; 146 | 147 | struct DevConf 148 | { 149 | ulong intnum; /* interrupt number */ 150 | char *type; /* card type, malloced */ 151 | int nports; /* Number of ports */ 152 | Devport *ports; /* The ports themselves */ 153 | }; 154 | --------------------------------------------------------------------------------