From: Alan Cox Date: Tue, 27 Oct 2015 15:56:47 +0000 (+0000) Subject: syscall: overlay basics X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=f3fdbcef115838637e28ff26f0e6f64ec2217cbd;p=FUZIX.git syscall: overlay basics Split our syscall_fs2 into fs2/fs3 to get the sizes right Include syscall_fs3 in all the platforms New link rules for syscalls so we can overlay them Initial bits to build (but not yet run) overlaid on 64K Z80 This breaks the msp430 for the moment (sorry !) --- diff --git a/Kernel/Makefile b/Kernel/Makefile index 8049680e..06fee8b2 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -70,12 +70,17 @@ include cpu-$(CPU)/rules.mk CDSRCS = start.c C1SRCS = version.c filesys.c devio.c kdata.c C1SRCS += inode.c tty.c +C2SRCS = syscall_proc.c process.c malloc.c +C2SRCS += simple.c single.c bank16k.c bank16k_low.c bank32k.c bankfixed.c flat.c # -# Keep all of the syscalls in C2SRCS +# Usually we map sysalls into CODE2 but they can be overlaid +# +CS1SRCS = syscall_fs.c +CS2SRCS = syscall_fs2.c +CS3SRCS = syscall_fs3.c +CS4SRCS = syscall_other.c +CS5SRCS = syscall_exec$(BITS).c # -C2SRCS = syscall_proc.c syscall_fs.c -C2SRCS += syscall_fs2.c syscall_other.c syscall_exec$(BITS).c process.c malloc.c -C2SRCS += simple.c single.c bank16k.c bank16k_low.c bank32k.c bankfixed.c flat.c # # Drop some bits into CODE3 so the 6502 banks fit nicely. May well # need to do this on Z80 as well @@ -92,12 +97,22 @@ CDOBJS = $(CDSRCS:.c=$(BINEXT)) C1OBJS = $(C1SRCS:.c=$(BINEXT)) C2OBJS = $(C2SRCS:.c=$(BINEXT)) C3OBJS = $(C3SRCS:.c=$(BINEXT)) + +CS1OBJS = $(CS1SRCS:.c=$(BINEXT)) +CS2OBJS = $(CS2SRCS:.c=$(BINEXT)) +CS3OBJS = $(CS3SRCS:.c=$(BINEXT)) +CS4OBJS = $(CS4SRCS:.c=$(BINEXT)) +CS5OBJS = $(CS5SRCS:.c=$(BINEXT)) + CFONTOBJS = $(CFONTSRCS:.c=$(BINEXT)) CVIDEOOBJS = $(CVIDEOSRCS:.c=$(BINEXT)) AOBJS = $(ASRCS:$(ASMEXT)=$(BINEXT)) -CSRCS = $(CDSRCS) $(C1SRCS) $(C2SRCS) $(C3SRCS) $(CFONTSRCS) $(CVIDEOSRCS) -COBJS = $(CDOBJS) $(C1OBJS) $(C2OBJS) $(C3OBJS) $(CFONTOBJS) $(CVIDEOOBJS) +CSSRCS = $(CS1SRCS) $(CS2SRCS) $(CS3SRCS) $(CS4SRCS) $(CS5SRCS) +CSOBJS = $(CS1OBJS) $(CS2OBJS) $(CS3OBJS) $(CS4OBJS) $(CS5OBJS) + +CSRCS = $(CDSRCS) $(C1SRCS) $(C2SRCS) $(C3SRCS) $(CFONTSRCS) $(CVIDEOSRCS) $(CSSRCS) +COBJS = $(CDOBJS) $(C1OBJS) $(C2OBJS) $(C3OBJS) $(CFONTOBJS) $(CVIDEOOBJS) $(CSOBJS) OBJS = $(COBJS) $(AOBJS) @@ -133,6 +148,21 @@ $(CFONTOBJS): %$(BINEXT): %.c $(CVIDEOOBJS): %$(BINEXT): %.c $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_VIDEO) $< +$(CS1OBJS): %$(BINEXT): %.c + $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SYS1) $< + +$(CS2OBJS): %$(BINEXT): %.c + $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SYS2) $< + +$(CS3OBJS): %$(BINEXT): %.c + $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SYS3) $< + +$(CS4OBJS): %$(BINEXT): %.c + $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SYS4) $< + +$(CS5OBJS): %$(BINEXT): %.c + $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SYS5) $< + $(AOBJS): %$(BINEXT): %$(ASMEXT) $(CROSS_AS) $(ASOPTS) -o $*$(BINEXT) $< diff --git a/Kernel/cpu-6809/rules.mk b/Kernel/cpu-6809/rules.mk index bc6a3005..084b932f 100644 --- a/Kernel/cpu-6809/rules.mk +++ b/Kernel/cpu-6809/rules.mk @@ -9,6 +9,11 @@ export CROSS_CC_SEG2=-mcode-section=.text2 -mfar-code-page=2 export CROSS_CC_SEG3=-mcode-section=.text2 -mfar-code-page=2 export CROSS_CC_SEGDISC=-mcode-section=.discard -mdata-section=.discard -mfar-code-page=3 export CROSS_CC_VIDEO=-mcode-section=.video -mdata-section=.videodata -mfar-code-page=4 +export CROSS_CC_SYS1=-mcode-section=.text2 -mfar-code-page=2 +export CROSS_CC_SYS2=-mcode-section=.text2 -mfar-code-page=2 +export CROSS_CC_SYS3=-mcode-section=.text2 -mfar-code-page=2 +export CROSS_CC_SYS4=-mcode-section=.text2 -mfar-code-page=2 +export CROSS_CC_SYS5=-mcode-section=.text2 -mfar-code-page=2 export ASOPTS= export ASMEXT = .s export BINEXT = .o diff --git a/Kernel/cpu-z80/rules.mk b/Kernel/cpu-z80/rules.mk index 8de241ae..7345cc29 100644 --- a/Kernel/cpu-z80/rules.mk +++ b/Kernel/cpu-z80/rules.mk @@ -11,6 +11,11 @@ export CROSS_CC_SEG3=--codeseg CODE2 export CROSS_CC_SEGDISC=--codeseg DISCARD --constseg DISCARD export CROSS_CC_FONT=--constseg FONT export CROSS_CC_VIDEO=--codeseg VIDEO +export CROSS_CC_SYS1=--codeseg CODE2 +export CROSS_CC_SYS2=--codeseg CODE2 +export CROSS_CC_SYS3=--codeseg CODE2 +export CROSS_CC_SYS4=--codeseg CODE2 +export CROSS_CC_SYS5=--codeseg CODE2 export ASOPTS=-plosff export ASMEXT = .s export BINEXT = .rel diff --git a/Kernel/platform-coco2/Makefile b/Kernel/platform-coco2/Makefile index fb675dc2..f1c6ee73 100644 --- a/Kernel/platform-coco2/Makefile +++ b/Kernel/platform-coco2/Makefile @@ -55,7 +55,7 @@ image: bootfuz.bin ../devio.o ../filesys.o ../process.o ../inode.o ../syscall_fs.o \ ../syscall_proc.o ../syscall_other.o ../mm.o ../swap.o \ ../tty.o ../devsys.o ../usermem.o ../syscall_fs2.o ../syscall_exec16.o \ - devtty.o libc.o ../vt.o + devtty.o libc.o ../vt.o ../syscall_fs3.o ../tools/decb-image <../fuzix.bin fuzix.img # Repack the high 4K where the loader wants it dd if=fuzix.img of=fuzix.tmp bs=1024 skip=60 diff --git a/Kernel/platform-coco3/Makefile b/Kernel/platform-coco3/Makefile index 263944cf..0eefe8f2 100644 --- a/Kernel/platform-coco3/Makefile +++ b/Kernel/platform-coco3/Makefile @@ -46,6 +46,7 @@ image: ../devio.o ../filesys.o ../process.o ../inode.o ../syscall_fs.o \ ../syscall_proc.o ../syscall_other.o ../mm.o ../bank16k.o ../swap.o \ ../tty.o ../devsys.o ../usermem.o ../syscall_fs2.o ../syscall_exec16.o \ + ../syscall_fs3.o \ ../usermem_std-6809.o devtty.o libc.o ../vt.o usermem_gime.o video.o \ videoll.o diff --git a/Kernel/platform-dragon-nx32/Makefile b/Kernel/platform-dragon-nx32/Makefile index b8ba89b0..bbcb4b67 100644 --- a/Kernel/platform-dragon-nx32/Makefile +++ b/Kernel/platform-dragon-nx32/Makefile @@ -54,6 +54,7 @@ image: ../devio.o ../filesys.o ../process.o ../inode.o ../syscall_fs.o \ ../syscall_proc.o ../syscall_other.o ../mm.o ../swap.o \ ../tty.o ../devsys.o ../usermem.o ../syscall_fs2.o ../syscall_exec16.o \ + ../syscall_fs3.o \ devlpr.o devtty.o libc.o ../vt.o video.o ../font8x8.o \ devide.o blkdev.o ide.o devide_discard.o mbr.o \ devsd.o devsd_discard.o spi.o devscsi.o devscsi_discard.o \ diff --git a/Kernel/platform-micropack/config.h b/Kernel/platform-micropack/config.h index 23f5ca30..7b52f5cb 100644 --- a/Kernel/platform-micropack/config.h +++ b/Kernel/platform-micropack/config.h @@ -20,16 +20,17 @@ /* Banks as reported to user space */ #define CONFIG_BANKS 1 +#define PTABSIZE 8 #define TICKSPERSEC 100 /* Ticks per second */ #define PROGBASE 0x0000 /* also data base */ #define PROGLOAD 0x0100 -#define PROGTOP 0x6000 /* Top of program, base of U_DATA */ +#define PROGTOP 0x7E00 /* Top of program, base of U_DATA */ #define PROC_SIZE 32 /* Memory needed per process */ #define SWAP_SIZE 0x40 /* 32K in blocks (we actually don't need the low 256) */ #define SWAPBASE 0x0000 /* We swap the lot in one, include the */ #define SWAPTOP 0x8000 /* vectors so its a round number of sectors */ -#define MAX_SWAPS 64 /* The full drive would actually be 170! */ +#define MAX_SWAPS PTABSIZE /* The full drive would actually be 170! */ #define swap_map(x) ((uint8_t *)(x)) /* Simple zero based mapping */ #define BOOT_TTY (512 + 1)/* Set this to default device for stdio, stderr */ diff --git a/Kernel/platform-micropack/crt0.s b/Kernel/platform-micropack/crt0.s index 30dccdbb..e48761af 100644 --- a/Kernel/platform-micropack/crt0.s +++ b/Kernel/platform-micropack/crt0.s @@ -1,11 +1,8 @@ -; 2013-12-18 William R Sowerbutts - - .module crt0 - ; Ordering of segments for the linker. ; WRS: Note we list all our segments here, even though ; we don't use them all, because their ordering is set ; when they are first seen. + .area _CODE6 ; overlaid by 3 4 5 (which are smaller) .area _CODE .area _CODE2 .area _CONST @@ -24,6 +21,9 @@ .area _DISCARD .area _UDATA + .module crt0 + + ; imported symbols .globl _fuzix_main .globl init_early diff --git a/Kernel/platform-micropack/fuzix.lnk b/Kernel/platform-micropack/fuzix.lnk index 07a1f7a4..9bfe055c 100644 --- a/Kernel/platform-micropack/fuzix.lnk +++ b/Kernel/platform-micropack/fuzix.lnk @@ -1,8 +1,13 @@ -mwxuy -i fuzix.ihx +-b _CODE=0xC000 -b _DISCARD=0x5000 --b _UDATA=0x6000 --b _CODE=0x6300 +-b _UDATA=0x7E00 +-b _CODE6=0x8000 +-b _CODE3=0x8000 +-b _CODE4=0x8000 +-b _CODE5=0x8000 +-b _CODE7=0x8000 -l z80 platform-micropack/crt0.rel platform-micropack/commonmem.rel @@ -24,6 +29,7 @@ inode.rel syscall_exec16.rel syscall_fs.rel syscall_fs2.rel +syscall_fs3.rel syscall_proc.rel syscall_other.rel tty.rel diff --git a/Kernel/platform-micropack/kernel.def b/Kernel/platform-micropack/kernel.def index 11863f78..fb4364a3 100644 --- a/Kernel/platform-micropack/kernel.def +++ b/Kernel/platform-micropack/kernel.def @@ -1,6 +1,6 @@ ; UZI mnemonics for memory addresses etc -U_DATA .equ 0x6000 ; (this is struct u_data from kernel.h) +U_DATA .equ 0x8200 ; (this is struct u_data from kernel.h) U_DATA__TOTALSIZE .equ 0x300 ; 256+256+256 bytes. Z80_TYPE .equ 0 diff --git a/Kernel/platform-micropack/rules.mk b/Kernel/platform-micropack/rules.mk index 5b2f4a14..51797902 100644 --- a/Kernel/platform-micropack/rules.mk +++ b/Kernel/platform-micropack/rules.mk @@ -2,4 +2,8 @@ # Use RST8 for call preamble # CROSS_CCOPTS += --peep-file $(ROOT_DIR)/cpu-z80/rst8.peep - +export CROSS_CC_SYS1=--codeseg CODE3 +export CROSS_CC_SYS2=--codeseg CODE4 +export CROSS_CC_SYS3=--codeseg CODE5 +export CROSS_CC_SYS4=--codeseg CODE6 +export CROSS_CC_SYS5=--codeseg CODE7 diff --git a/Kernel/platform-msx1/fuzix.lnk b/Kernel/platform-msx1/fuzix.lnk index f537240c..b98ed4bb 100644 --- a/Kernel/platform-msx1/fuzix.lnk +++ b/Kernel/platform-msx1/fuzix.lnk @@ -28,6 +28,7 @@ inode.rel syscall_exec16.rel syscall_fs.rel syscall_fs2.rel +syscall_fs3.rel syscall_proc.rel syscall_other.rel mm.rel diff --git a/Kernel/platform-msx2/fuzix.lnk b/Kernel/platform-msx2/fuzix.lnk index fec52a01..aff19cdc 100644 --- a/Kernel/platform-msx2/fuzix.lnk +++ b/Kernel/platform-msx2/fuzix.lnk @@ -26,6 +26,7 @@ inode.rel syscall_exec16.rel syscall_fs.rel syscall_fs2.rel +syscall_fs3.rel syscall_proc.rel syscall_other.rel mm.rel diff --git a/Kernel/platform-mtx/fuzix.lnk b/Kernel/platform-mtx/fuzix.lnk index 9acede46..979f41e1 100644 --- a/Kernel/platform-mtx/fuzix.lnk +++ b/Kernel/platform-mtx/fuzix.lnk @@ -27,6 +27,7 @@ inode.rel syscall_exec16.rel syscall_fs.rel syscall_fs2.rel +syscall_fs3.rel syscall_proc.rel syscall_other.rel tty.rel diff --git a/Kernel/platform-n8vem-mark4/fuzix.lnk b/Kernel/platform-n8vem-mark4/fuzix.lnk index 477f2557..847a672f 100644 --- a/Kernel/platform-n8vem-mark4/fuzix.lnk +++ b/Kernel/platform-n8vem-mark4/fuzix.lnk @@ -24,6 +24,7 @@ inode.rel syscall_exec16.rel syscall_fs.rel syscall_fs2.rel +syscall_fs3.rel syscall_proc.rel syscall_other.rel tty.rel diff --git a/Kernel/platform-nc100/fuzix.lnk b/Kernel/platform-nc100/fuzix.lnk index 1c929852..5a1d6ae9 100644 --- a/Kernel/platform-nc100/fuzix.lnk +++ b/Kernel/platform-nc100/fuzix.lnk @@ -24,6 +24,7 @@ syscall_exec16.rel syscall_fs.rel syscall_proc.rel syscall_fs2.rel +syscall_fs3.rel syscall_other.rel mm.rel swap.rel diff --git a/Kernel/platform-p112/fuzix.lnk b/Kernel/platform-p112/fuzix.lnk index 8b726543..0db62414 100644 --- a/Kernel/platform-p112/fuzix.lnk +++ b/Kernel/platform-p112/fuzix.lnk @@ -24,6 +24,7 @@ inode.rel syscall_exec16.rel syscall_fs.rel syscall_fs2.rel +syscall_fs3.rel syscall_proc.rel syscall_other.rel tty.rel diff --git a/Kernel/platform-pcw8256/fuzix.lnk b/Kernel/platform-pcw8256/fuzix.lnk index 19267789..d47043da 100644 --- a/Kernel/platform-pcw8256/fuzix.lnk +++ b/Kernel/platform-pcw8256/fuzix.lnk @@ -26,6 +26,7 @@ inode.rel syscall_exec16.rel syscall_fs.rel syscall_fs2.rel +syscall_fs3.rel syscall_proc.rel syscall_other.rel tty.rel diff --git a/Kernel/platform-plus3/fuzix.lnk b/Kernel/platform-plus3/fuzix.lnk index 0430d962..e4f6246b 100644 --- a/Kernel/platform-plus3/fuzix.lnk +++ b/Kernel/platform-plus3/fuzix.lnk @@ -28,6 +28,7 @@ inode.rel syscall_exec16.rel syscall_fs.rel syscall_fs2.rel +syscall_fs3.rel syscall_proc.rel syscall_other.rel tty.rel diff --git a/Kernel/platform-px4plus/fuzix.lnk b/Kernel/platform-px4plus/fuzix.lnk index 9bee7b38..14458fe8 100644 --- a/Kernel/platform-px4plus/fuzix.lnk +++ b/Kernel/platform-px4plus/fuzix.lnk @@ -32,6 +32,7 @@ inode.rel syscall_exec16.rel syscall_fs.rel syscall_fs2.rel +syscall_fs3.rel syscall_proc.rel syscall_other.rel tty.rel diff --git a/Kernel/platform-socz80/fuzix.lnk b/Kernel/platform-socz80/fuzix.lnk index d9fcb3d1..e5ac2424 100644 --- a/Kernel/platform-socz80/fuzix.lnk +++ b/Kernel/platform-socz80/fuzix.lnk @@ -27,6 +27,7 @@ inode.rel syscall_exec16.rel syscall_fs.rel syscall_fs2.rel +syscall_fs3.rel syscall_proc.rel syscall_other.rel tty.rel diff --git a/Kernel/platform-trs80/fuzix.lnk b/Kernel/platform-trs80/fuzix.lnk index fe00fa3a..2c139279 100644 --- a/Kernel/platform-trs80/fuzix.lnk +++ b/Kernel/platform-trs80/fuzix.lnk @@ -29,6 +29,7 @@ inode.rel syscall_exec16.rel syscall_fs.rel syscall_fs2.rel +syscall_fs3.rel syscall_proc.rel syscall_other.rel tty.rel diff --git a/Kernel/platform-ubee/fuzix.lnk b/Kernel/platform-ubee/fuzix.lnk index 0ecd3069..746fb241 100644 --- a/Kernel/platform-ubee/fuzix.lnk +++ b/Kernel/platform-ubee/fuzix.lnk @@ -27,6 +27,7 @@ inode.rel syscall_exec16.rel syscall_fs.rel syscall_fs2.rel +syscall_fs3.rel syscall_proc.rel syscall_other.rel tty.rel diff --git a/Kernel/platform-z80pack-lite/fuzix.lnk b/Kernel/platform-z80pack-lite/fuzix.lnk index 204f1c98..a731642d 100644 --- a/Kernel/platform-z80pack-lite/fuzix.lnk +++ b/Kernel/platform-z80pack-lite/fuzix.lnk @@ -25,6 +25,7 @@ inode.rel syscall_exec16.rel syscall_fs.rel syscall_fs2.rel +syscall_fs3.rel syscall_proc.rel syscall_other.rel tty.rel diff --git a/Kernel/platform-z80pack/fuzix.lnk b/Kernel/platform-z80pack/fuzix.lnk index 367e29f1..41961f66 100644 --- a/Kernel/platform-z80pack/fuzix.lnk +++ b/Kernel/platform-z80pack/fuzix.lnk @@ -25,6 +25,7 @@ inode.rel syscall_exec16.rel syscall_fs.rel syscall_fs2.rel +syscall_fs3.rel syscall_proc.rel syscall_other.rel tty.rel diff --git a/Kernel/platform-zeta-v2/fuzix.lnk b/Kernel/platform-zeta-v2/fuzix.lnk index 885f22f4..07628427 100644 --- a/Kernel/platform-zeta-v2/fuzix.lnk +++ b/Kernel/platform-zeta-v2/fuzix.lnk @@ -27,6 +27,7 @@ syscall_exec16.rel syscall_fs.rel syscall_proc.rel syscall_fs2.rel +syscall_fs3.rel syscall_other.rel mm.rel swap.rel diff --git a/Kernel/platform-zx128/fuzix.lnk b/Kernel/platform-zx128/fuzix.lnk index d3f1363c..77e4ab6b 100644 --- a/Kernel/platform-zx128/fuzix.lnk +++ b/Kernel/platform-zx128/fuzix.lnk @@ -31,6 +31,7 @@ inode.rel syscall_exec16.rel syscall_fs.rel syscall_fs2.rel +syscall_fs3.rel syscall_proc.rel syscall_other.rel tty.rel diff --git a/Kernel/syscall_fs2.c b/Kernel/syscall_fs2.c index 7cda01fe..3754958c 100644 --- a/Kernel/syscall_fs2.c +++ b/Kernel/syscall_fs2.c @@ -415,389 +415,3 @@ arg_t _getfsys(void) #undef dev #undef buf - -/******************************************* -open (name, flag, mode) Function 1 -char *name; -int16_t flag; -int16_t mode; -********************************************/ -#define name (char *)udata.u_argn -#define flag (uint16_t)udata.u_argn1 -#define mode (uint16_t)udata.u_argn2 - -arg_t _open(void) -{ - int8_t uindex; - int8_t oftindex; - staticfast inoptr ino; - int16_t perm; - staticfast inoptr parent; - char fname[FILENAME_LEN + 1]; - int trunc; - int r; - int w; - int j; - - parent = NULLINODE; - - trunc = flag & O_TRUNC; - r = (flag + 1) & 1; - w = (flag + 1) & 2; - - if (O_ACCMODE(flag) == 3 || (flag & O_BADBITS)) { - udata.u_error = EINVAL; - return (-1); - } - if ((uindex = uf_alloc()) == -1) - return (-1); - - if ((oftindex = oft_alloc()) == -1) - goto nooft; - - ino = n_open(name, &parent); - if (ino) { - i_deref(parent); - /* O_EXCL test */ - if ((flag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) { - udata.u_error = EEXIST; - goto idrop; - } - } else { - /* The n_open failed */ - if (udata.u_error == EFAULT) - goto cantopen; - /* New file */ - if (!(flag & O_CREAT)) { - udata.u_error = ENOENT; - goto cantopen; - } - filename(name, fname); - /* newfile drops parent for us */ - if (parent && (ino = newfile(parent, fname))) { - ino->c_node.i_mode = - (F_REG | (mode & MODE_MASK & ~udata.u_mask)); - setftime(ino, A_TIME | M_TIME | C_TIME); - wr_inode(ino); - } else { - udata.u_error = ENFILE; /* FIXME, should be set in newfile - not bodged to a guessed code */ - goto cantopen; - } - } - /* Book our slot in case we block opening a device */ - of_tab[oftindex].o_inode = ino; - - perm = getperm(ino); - if ((r && !(perm & OTH_RD)) || (w && !(perm & OTH_WR))) { - udata.u_error = EACCES; - goto cantopen; - } - if (w) { - if (getmode(ino) == F_DIR ) { - udata.u_error = EISDIR; - goto cantopen; - } - if (ino->c_flags & CRDONLY) { - udata.u_error = EROFS; - goto cantopen; - } - } - - if (isdevice(ino)) { - inoptr *iptr = &of_tab[oftindex].o_inode; - /* d_open may block and thus ino may become invalid as may - parent (but we don't need it again). It may also be changed - by the call to dev_openi */ - - if (dev_openi(iptr, flag) != 0) - goto cantopen; - - /* May have changed */ - /* get the static pointer back in case it changed via dev - usage or just because we blocked */ - ino = *iptr; - } - - if (trunc && getmode(ino) == F_REG) { - if (f_trunc(ino)) - goto idrop; - for (j = 0; j < OFTSIZE; ++j) - /* Arguably should fix at read/write */ - if (of_tab[j].o_inode == ino) - of_tab[j].o_ptr = 0; - } - - udata.u_files[uindex] = oftindex; - - of_tab[oftindex].o_ptr = 0; - of_tab[oftindex].o_access = flag; /* Save the low bits only */ - if (flag & O_CLOEXEC) - udata.u_cloexec |= (1 << oftindex); - /* FIXME: ATIME ? */ - -/* - * Sleep process if no writer or reader - */ - if (getmode(ino) == F_PIPE && of_tab[oftindex].o_refs == 1 - && !(flag & O_NDELAY)) - psleep(ino); - - /* From the moment of the psleep ino is invalid */ - - return (uindex); - idrop: - i_deref(ino); - cantopen: - oft_deref(oftindex); /* This will call i_deref() */ - nooft: - udata.u_files[uindex] = NO_FILE; - return (-1); -} - -#undef name -#undef flag -#undef mode - - - -/******************************************* -link (name1, name2) Function 5 -char *name1; -char *name2; -********************************************/ -#define name1 (char *)udata.u_argn -#define name2 (char *)udata.u_argn1 - -arg_t _link(void) -{ - inoptr ino; - inoptr ino2; - inoptr parent2; - char fname[FILENAME_LEN + 1]; - - if (!(ino = n_open(name1, NULLINOPTR))) - return (-1); - - if (getmode(ino) == F_DIR && esuper()) - goto nogood; - - if (ino->c_node.i_nlink == 0xFFFF) { - udata.u_error = EMLINK; - goto nogood; - } - - /* Make sure file2 doesn't exist, and get its parent */ - if ((ino2 = n_open(name2, &parent2)) != NULL) { - i_deref(ino2); - i_deref(parent2); - udata.u_error = EEXIST; - goto nogood; - } - - if (!parent2) - goto nogood; - - if (ino->c_dev != parent2->c_dev) { - i_deref(parent2); - udata.u_error = EXDEV; - goto nogood; - } - - filename(name2, fname); - - if (!ch_link(parent2, "", fname, ino)) { - i_deref(parent2); - goto nogood; - } - - /* Update the link count. */ - ++ino->c_node.i_nlink; - wr_inode(ino); - setftime(ino, C_TIME); - - i_deref(parent2); - i_deref(ino); - return 0; - - nogood: - i_deref(ino); - return -1; -} - -#undef name1 -#undef name2 - - -/******************************************* - fcntl (fd, request, data) Function 47 - int fd; - int request; - char *data; - ********************************************/ -#define fd (int)udata.u_argn -#define request (int)udata.u_argn1 -#define data (int)udata.u_argn2 - -arg_t _fcntl(void) -{ - uint8_t *acc; - int newd; - - if (getinode(fd) == NULLINODE) - return (-1); - - acc = &of_tab[udata.u_files[fd]].o_access; - switch (request) { - case F_SETFL: - *acc = - (*acc & ~(O_APPEND | O_NDELAY)) | (data & - (O_APPEND | - O_NDELAY)); - return 0; - case F_GETFL: - return data; - case F_GETFD: - return udata.u_cloexec & (1 << fd) ? O_CLOEXEC : 0; - case F_SETFD: - if (data & O_CLOEXEC) - udata.u_cloexec |= (1 << fd); - else - udata.u_cloexec &= (1 << fd); - return 0; - case F_DUPFD: - if ((newd = uf_alloc_n(data)) == -1) - return (-1); - udata.u_files[newd] = udata.u_files[fd]; - ++of_tab[udata.u_files[fd]].o_refs; - return 0; - default: - udata.u_error = EINVAL; - return -1; - } -} - -#undef fd -#undef request -#undef data - -/******************************************* -uname (buf, len) Function 54 -char *buf; -uint16_t len; - -We pass a set of \0 terminated strings, don't bother -with node name. Rest is up to the libc. -********************************************/ - -#define buf (char *)udata.u_argn -#define len (uint16_t)udata.u_argn1 - -arg_t _uname(void) -{ - uint16_t size = sizeof(sysinfo) + uname_len; - if (size > len) - size = len; - sysinfo.memk = procmem; - sysinfo.usedk = pagemap_mem_used(); - sysinfo.nproc = PTABSIZE; - sysinfo.ticks = ticks_per_dsecond * 10; - sysinfo.loadavg[0] = loadavg[0].average; - sysinfo.loadavg[1] = loadavg[1].average; - sysinfo.loadavg[2] = loadavg[2].average; - uput(&sysinfo, buf, size); - return size; -} - -#undef buf - -/************************************** -flock(fd, lockop) Function 60 -int file; -int lockop; - -Perform locking upon a file. -**************************************/ - -#define file (uint16_t)udata.u_argn -#define lockop (uint16_t)udata.u_argn1 - -arg_t _flock(void) -{ - inoptr ino; - struct oft *o; - staticfast uint8_t c; - staticfast uint8_t lock; - staticfast int self; - - lock = lockop & ~LOCK_NB; - self = 0; - - if (lock > LOCK_UN) { - udata.u_error = EINVAL; - return -1; - } - - if ((ino = getinode(file)) == NULLINODE) - return -1; - o = &of_tab[udata.u_files[file]]; - - c = ino->c_flags & CFLOCK; - - /* Upgrades and downgrades. Check if we are in fact doing a no-op */ - if (o->o_access & O_FLOCK) { - self = 1; - /* Shared or exclusive to shared can't block and is easy */ - if (lock == LOCK_SH) { - if (c == CFLEX) - c = 1; - goto done; - } - /* Exclusive to exclusive - no op */ - if (c == CFLEX && lock == LOCK_EX) - return 0; - /* Shared to exclusive - handle via the loop */ - } - - - /* Unlock - drop the locks, mark us not a lock holder. Doesn't block */ - if (lockop == LOCK_UN) { - o->o_access &= ~O_FLOCK; - deflock(o); - return 0; - } - - do { - /* Exclusive lock must have no holders */ - if (c == self && lock == LOCK_EX) { - c = CFLEX; - goto done; - } - if (c < CFMAX) { - c++; - goto done; - } - if (c == CFMAX) { - udata.u_error = ENOLCK; - return -1; - } - /* LOCK_NB is defined as O_NDELAY... */ - if (psleep_flags(&ino->c_flags, (lockop & LOCK_NB))) - return -1; - /* locks will hopefully have changed .. */ - c = ino->c_flags & CFLOCK; - } while (1); - -done: - if (o->o_access & O_FLOCK) - deflock(o); - ino->c_flags &= ~CFLOCK; - ino->c_flags |= c; - o->o_access |= O_FLOCK; - wakeup(&ino->c_flags); - return 0; -} - - -#undef file -#undef lockop diff --git a/Kernel/syscall_fs3.c b/Kernel/syscall_fs3.c new file mode 100644 index 00000000..aaa574f3 --- /dev/null +++ b/Kernel/syscall_fs3.c @@ -0,0 +1,391 @@ +#include +#include +#include +#include + + +/******************************************* +open (name, flag, mode) Function 1 +char *name; +int16_t flag; +int16_t mode; +********************************************/ +#define name (char *)udata.u_argn +#define flag (uint16_t)udata.u_argn1 +#define mode (uint16_t)udata.u_argn2 + +arg_t _open(void) +{ + int8_t uindex; + int8_t oftindex; + staticfast inoptr ino; + int16_t perm; + staticfast inoptr parent; + char fname[FILENAME_LEN + 1]; + int trunc; + int r; + int w; + int j; + + parent = NULLINODE; + + trunc = flag & O_TRUNC; + r = (flag + 1) & 1; + w = (flag + 1) & 2; + + if (O_ACCMODE(flag) == 3 || (flag & O_BADBITS)) { + udata.u_error = EINVAL; + return (-1); + } + if ((uindex = uf_alloc()) == -1) + return (-1); + + if ((oftindex = oft_alloc()) == -1) + goto nooft; + + ino = n_open(name, &parent); + if (ino) { + i_deref(parent); + /* O_EXCL test */ + if ((flag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) { + udata.u_error = EEXIST; + goto idrop; + } + } else { + /* The n_open failed */ + if (udata.u_error == EFAULT) + goto cantopen; + /* New file */ + if (!(flag & O_CREAT)) { + udata.u_error = ENOENT; + goto cantopen; + } + filename(name, fname); + /* newfile drops parent for us */ + if (parent && (ino = newfile(parent, fname))) { + ino->c_node.i_mode = + (F_REG | (mode & MODE_MASK & ~udata.u_mask)); + setftime(ino, A_TIME | M_TIME | C_TIME); + wr_inode(ino); + } else { + udata.u_error = ENFILE; /* FIXME, should be set in newfile + not bodged to a guessed code */ + goto cantopen; + } + } + /* Book our slot in case we block opening a device */ + of_tab[oftindex].o_inode = ino; + + perm = getperm(ino); + if ((r && !(perm & OTH_RD)) || (w && !(perm & OTH_WR))) { + udata.u_error = EACCES; + goto cantopen; + } + if (w) { + if (getmode(ino) == F_DIR ) { + udata.u_error = EISDIR; + goto cantopen; + } + if (ino->c_flags & CRDONLY) { + udata.u_error = EROFS; + goto cantopen; + } + } + + if (isdevice(ino)) { + inoptr *iptr = &of_tab[oftindex].o_inode; + /* d_open may block and thus ino may become invalid as may + parent (but we don't need it again). It may also be changed + by the call to dev_openi */ + + if (dev_openi(iptr, flag) != 0) + goto cantopen; + + /* May have changed */ + /* get the static pointer back in case it changed via dev + usage or just because we blocked */ + ino = *iptr; + } + + if (trunc && getmode(ino) == F_REG) { + if (f_trunc(ino)) + goto idrop; + for (j = 0; j < OFTSIZE; ++j) + /* Arguably should fix at read/write */ + if (of_tab[j].o_inode == ino) + of_tab[j].o_ptr = 0; + } + + udata.u_files[uindex] = oftindex; + + of_tab[oftindex].o_ptr = 0; + of_tab[oftindex].o_access = flag; /* Save the low bits only */ + if (flag & O_CLOEXEC) + udata.u_cloexec |= (1 << oftindex); + /* FIXME: ATIME ? */ + +/* + * Sleep process if no writer or reader + */ + if (getmode(ino) == F_PIPE && of_tab[oftindex].o_refs == 1 + && !(flag & O_NDELAY)) + psleep(ino); + + /* From the moment of the psleep ino is invalid */ + + return (uindex); + idrop: + i_deref(ino); + cantopen: + oft_deref(oftindex); /* This will call i_deref() */ + nooft: + udata.u_files[uindex] = NO_FILE; + return (-1); +} + +#undef name +#undef flag +#undef mode + + + +/******************************************* +link (name1, name2) Function 5 +char *name1; +char *name2; +********************************************/ +#define name1 (char *)udata.u_argn +#define name2 (char *)udata.u_argn1 + +arg_t _link(void) +{ + inoptr ino; + inoptr ino2; + inoptr parent2; + char fname[FILENAME_LEN + 1]; + + if (!(ino = n_open(name1, NULLINOPTR))) + return (-1); + + if (getmode(ino) == F_DIR && esuper()) + goto nogood; + + if (ino->c_node.i_nlink == 0xFFFF) { + udata.u_error = EMLINK; + goto nogood; + } + + /* Make sure file2 doesn't exist, and get its parent */ + if ((ino2 = n_open(name2, &parent2)) != NULL) { + i_deref(ino2); + i_deref(parent2); + udata.u_error = EEXIST; + goto nogood; + } + + if (!parent2) + goto nogood; + + if (ino->c_dev != parent2->c_dev) { + i_deref(parent2); + udata.u_error = EXDEV; + goto nogood; + } + + filename(name2, fname); + + if (!ch_link(parent2, "", fname, ino)) { + i_deref(parent2); + goto nogood; + } + + /* Update the link count. */ + ++ino->c_node.i_nlink; + wr_inode(ino); + setftime(ino, C_TIME); + + i_deref(parent2); + i_deref(ino); + return 0; + + nogood: + i_deref(ino); + return -1; +} + +#undef name1 +#undef name2 + + +/******************************************* + fcntl (fd, request, data) Function 47 + int fd; + int request; + char *data; + ********************************************/ +#define fd (int)udata.u_argn +#define request (int)udata.u_argn1 +#define data (int)udata.u_argn2 + +arg_t _fcntl(void) +{ + uint8_t *acc; + int newd; + + if (getinode(fd) == NULLINODE) + return (-1); + + acc = &of_tab[udata.u_files[fd]].o_access; + switch (request) { + case F_SETFL: + *acc = + (*acc & ~(O_APPEND | O_NDELAY)) | (data & + (O_APPEND | + O_NDELAY)); + return 0; + case F_GETFL: + return data; + case F_GETFD: + return udata.u_cloexec & (1 << fd) ? O_CLOEXEC : 0; + case F_SETFD: + if (data & O_CLOEXEC) + udata.u_cloexec |= (1 << fd); + else + udata.u_cloexec &= (1 << fd); + return 0; + case F_DUPFD: + if ((newd = uf_alloc_n(data)) == -1) + return (-1); + udata.u_files[newd] = udata.u_files[fd]; + ++of_tab[udata.u_files[fd]].o_refs; + return 0; + default: + udata.u_error = EINVAL; + return -1; + } +} + +#undef fd +#undef request +#undef data + +/******************************************* +uname (buf, len) Function 54 +char *buf; +uint16_t len; + +We pass a set of \0 terminated strings, don't bother +with node name. Rest is up to the libc. +********************************************/ + +#define buf (char *)udata.u_argn +#define len (uint16_t)udata.u_argn1 + +arg_t _uname(void) +{ + uint16_t size = sizeof(sysinfo) + uname_len; + if (size > len) + size = len; + sysinfo.memk = procmem; + sysinfo.usedk = pagemap_mem_used(); + sysinfo.nproc = PTABSIZE; + sysinfo.ticks = ticks_per_dsecond * 10; + sysinfo.loadavg[0] = loadavg[0].average; + sysinfo.loadavg[1] = loadavg[1].average; + sysinfo.loadavg[2] = loadavg[2].average; + uput(&sysinfo, buf, size); + return size; +} + +#undef buf + +/************************************** +flock(fd, lockop) Function 60 +int file; +int lockop; + +Perform locking upon a file. +**************************************/ + +#define file (uint16_t)udata.u_argn +#define lockop (uint16_t)udata.u_argn1 + +arg_t _flock(void) +{ + inoptr ino; + struct oft *o; + staticfast uint8_t c; + staticfast uint8_t lock; + staticfast int self; + + lock = lockop & ~LOCK_NB; + self = 0; + + if (lock > LOCK_UN) { + udata.u_error = EINVAL; + return -1; + } + + if ((ino = getinode(file)) == NULLINODE) + return -1; + o = &of_tab[udata.u_files[file]]; + + c = ino->c_flags & CFLOCK; + + /* Upgrades and downgrades. Check if we are in fact doing a no-op */ + if (o->o_access & O_FLOCK) { + self = 1; + /* Shared or exclusive to shared can't block and is easy */ + if (lock == LOCK_SH) { + if (c == CFLEX) + c = 1; + goto done; + } + /* Exclusive to exclusive - no op */ + if (c == CFLEX && lock == LOCK_EX) + return 0; + /* Shared to exclusive - handle via the loop */ + } + + + /* Unlock - drop the locks, mark us not a lock holder. Doesn't block */ + if (lockop == LOCK_UN) { + o->o_access &= ~O_FLOCK; + deflock(o); + return 0; + } + + do { + /* Exclusive lock must have no holders */ + if (c == self && lock == LOCK_EX) { + c = CFLEX; + goto done; + } + if (c < CFMAX) { + c++; + goto done; + } + if (c == CFMAX) { + udata.u_error = ENOLCK; + return -1; + } + /* LOCK_NB is defined as O_NDELAY... */ + if (psleep_flags(&ino->c_flags, (lockop & LOCK_NB))) + return -1; + /* locks will hopefully have changed .. */ + c = ino->c_flags & CFLOCK; + } while (1); + +done: + if (o->o_access & O_FLOCK) + deflock(o); + ino->c_flags &= ~CFLOCK; + ino->c_flags |= c; + o->o_access |= O_FLOCK; + wakeup(&ino->c_flags); + return 0; +} + + +#undef file +#undef lockop diff --git a/Kernel/syscall_net.c b/Kernel/syscall_net.c index 8caf1413..61f70d16 100644 --- a/Kernel/syscall_net.c +++ b/Kernel/syscall_net.c @@ -488,6 +488,7 @@ arg_t _recvfrom(void) struct socket *s = sock_get(d, NULL); int ret; + /* FIXME: will need _read redone for banked syscalls */ if (s == NULL) return -1; ret = _read(); diff --git a/Kernel/tty.c b/Kernel/tty.c index 1fd39725..cade538e 100644 --- a/Kernel/tty.c +++ b/Kernel/tty.c @@ -6,6 +6,12 @@ #undef DEBUG /* UNdefine to delete debug code sequences */ +/* + * On some 8bit systems it makes a huge difference if we avoid all the + * t-> pointer dereferences at link time, so for a single tty we abuse + * the preprocessor slightly + */ + /* * Minimal Terminal Interface * @@ -271,12 +277,11 @@ int tty_ioctl(uint8_t minor, uarg_t request, char *data) int tty_inproc(uint8_t minor, unsigned char c) { unsigned char oc; - struct tty *t; - struct s_queue *q = &ttyinq[minor]; int canon; uint8_t wr; + struct tty *t = &ttydata[minor]; + struct s_queue *q = &ttyinq[minor]; - t = &ttydata[minor]; canon = t->termios.c_lflag & ICANON; if (t->termios.c_iflag & ISTRIP)