]> Zhao Yanbai Git Server - minix.git/commitdiff
Reorganized system call library; uses separate file per call now.
authorJorrit Herder <jnherder@minix3.org>
Thu, 14 Jul 2005 15:12:12 +0000 (15:12 +0000)
committerJorrit Herder <jnherder@minix3.org>
Thu, 14 Jul 2005 15:12:12 +0000 (15:12 +0000)
New configuration header file to include/ exclude functionality.
Extracted privileged features from struct proc and create new struct priv.
Renamed various system calls for readability.

53 files changed:
kernel/Makefile
kernel/clock.c
kernel/const.h
kernel/debug.c [moved from kernel/system/debugging.c with 87% similarity]
kernel/debug.h
kernel/exception.c
kernel/glo.h
kernel/i8259.c
kernel/ipc.h
kernel/kernel.h
kernel/klibc.c
kernel/main.c
kernel/proc.c
kernel/proc.h
kernel/protect.c
kernel/proto.h
kernel/system.c
kernel/system.h
kernel/system/Makefile
kernel/system/clock.c [deleted file]
kernel/system/copying.c [deleted file]
kernel/system/do_abort.c [new file with mode: 0644]
kernel/system/do_alarm.c [new file with mode: 0644]
kernel/system/do_copy.c [new file with mode: 0644]
kernel/system/do_devio.c [new file with mode: 0644]
kernel/system/do_endksig.c [new file with mode: 0644]
kernel/system/do_exec.c [new file with mode: 0644]
kernel/system/do_exit.c [new file with mode: 0644]
kernel/system/do_fork.c [new file with mode: 0644]
kernel/system/do_getinfo.c [moved from kernel/system/misc.c with 63% similarity]
kernel/system/do_getksig.c [new file with mode: 0644]
kernel/system/do_irqctl.c [moved from kernel/system/irqctl.c with 98% similarity]
kernel/system/do_kill.c [new file with mode: 0644]
kernel/system/do_memset.c [new file with mode: 0644]
kernel/system/do_newmap.c [new file with mode: 0644]
kernel/system/do_schedctl.c [new file with mode: 0644]
kernel/system/do_sdevio.c [new file with mode: 0644]
kernel/system/do_segctl.c [new file with mode: 0644]
kernel/system/do_sigreturn.c [new file with mode: 0644]
kernel/system/do_sigsend.c [new file with mode: 0644]
kernel/system/do_svrctl.c [new file with mode: 0644]
kernel/system/do_times.c [new file with mode: 0644]
kernel/system/do_trace.c [moved from kernel/system/tracing.c with 99% similarity]
kernel/system/do_umap.c [new file with mode: 0644]
kernel/system/do_unused.c [new file with mode: 0644]
kernel/system/do_vcopy.c [new file with mode: 0644]
kernel/system/do_vdevio.c [moved from kernel/system/devio.c with 62% similarity]
kernel/system/priority.c [deleted file]
kernel/system/proctl.c [deleted file]
kernel/system/sigctl.c [deleted file]
kernel/system/sysctl.c [deleted file]
kernel/table.c
kernel/type.h

index e973641f0555dea0ad82e1e83415022a7b0299d0..259e6a1b4284798220ae41fb4dc39efc785884ab 100755 (executable)
@@ -15,27 +15,23 @@ LDFLAGS = -i
 
 HEAD = mpx.o
 OBJS = start.o protect.o klibc.o klib.o table.o main.o proc.o \
-       i8259.o exception.o system.o clock.o misc.o 
-SYS_OBJS = $s/proctl.o $s/copying.o $s/devio.o $s/sysctl.o $s/misc.o \
-           $s/sigctl.o $s/tracing.o $s/clock.o $s/irqctl.o $s/debugging.o \
-           $s/priority.o
-LIBS = -ltimers
+       i8259.o exception.o system.o clock.o utility.o debug.o
+SYSTEM = system.a
+LIBS = -ltimers 
 
 
 # What to make.
-kernel build: $(HEAD) $(OBJS) $(SYS_OBJS) 
-       $(LD) $(CFLAGS) $(LDFLAGS) -o kernel $(HEAD) $(OBJS) $(SYS_OBJS) $(LIBS)
-       install -S 0 kernel
-
-$(SYS_OBJS):
-       cd system && $(MAKE)
-
-all install:
+all: build 
+kernel build install: $(HEAD) $(OBJS) 
        cd system && $(MAKE) -$(MAKEFLAGS) $@
+       $(LD) $(CFLAGS) $(LDFLAGS) -o kernel \
+       $(HEAD) $(OBJS) \
+       $(SYSTEM) $(LIBS)
+       install -S 0 kernel
 
 clean:
        cd system && $(MAKE) -$(MAKEFLAGS) $@
-       rm -f *.o *.bak kernel
+       rm -f *.a *.o *.bak kernel
 
 depend: 
        cd system && $(MAKE) -$(MAKEFLAGS) $@
index 3cb3c697e5f5be8952bce127e6fa6e8344b69ae2..3cfb62394c7ccb0d52018afbf41a9954377f468f 100755 (executable)
@@ -2,8 +2,8 @@
  * Important events that are handled by the CLOCK include alarm timers and
  * (re)scheduling user processes. 
  * The CLOCK offers a direct interface to kernel processes. System services 
- * can access its services through system calls, such as sys_syncalrm(). The
- * CLOCK task thus is hidden for the outside.  
+ * can access its services through system calls, such as sys_setalarm(). The
+ * CLOCK task thus is hidden for the outside world.  
  *
  * Changes:
  *   Mar 18, 2004   clock interface moved to SYSTEM task (Jorrit N. Herder) 
  * The watchdog functions of expired timers are executed in do_clocktick(). 
  * It is crucial that watchdog functions cannot block, or the CLOCK task may
  * be blocked. Do not send() a message when the receiver is not expecting it.
- * The use of notify(), which always returns, is strictly preferred! 
+ * Instead, notify(), which always returns, should be used. 
  */
 
 #include "kernel.h"
-#include "debug.h"
 #include "proc.h"
 #include <signal.h>
 #include <minix/com.h>
@@ -159,46 +158,31 @@ message *m_ptr;                           /* pointer to request message */
 PRIVATE int clock_handler(hook)
 irq_hook_t *hook;
 {
-/* This executes on every clock tick (i.e., every time the timer chip
- * generates an interrupt). It does a little bit of work so the clock
- * task does not have to be called on every tick.
+/* This executes on each clock tick (i.e., every time the timer chip generates 
+ * an interrupt). It does a little bit of work so the clock task does not have 
+ * to be called on every tick.  The clock task is called when:
  *
- * Switch context to do_clocktick() if an alarm has gone off.
- * Also switch there to reschedule if the reschedule will do something.
- * This happens when
- *     (1) quantum has expired
- *     (2) current process received full quantum (as clock sampled it!)
- *     (3) something else is ready to run.
+ *     (1) the scheduling quantum of the running process has expired, or
+ *     (2) a timer has expired and the watchdog function should be run.
  *
- * Many global global and static variables are accessed here.  The safety
- * of this must be justified.  Most of them are not changed here:
+ * Many global global and static variables are accessed here.  The safety of
+ * this must be justified. All scheduling and message passing code acquires a 
+ * lock by temporarily disabling interrupts, so no conflicts with calls from 
+ * the task level can occur. Furthermore, interrupts are not reentrant, the 
+ * interrupt handler cannot be bothered by other interrupts.
+ * 
+ * Variables that are updated in the clock's interrupt handler:
+ *     lost_ticks:
+ *             Clock ticks counted outside the clock task. This for example
+ *             is used when the boot monitor processes a real mode interrupt.
+ *     realtime:
+ *             The current uptime is incremented with all outstanding ticks.
  *     proc_ptr, bill_ptr:
  *             These are used for accounting.  It does not matter if proc.c
  *             is changing them, provided they are always valid pointers,
  *             since at worst the previous process would be billed.
- *     next_timeout, realtime, sched_ticks, bill_ptr, prev_ptr,
- *             These are tested to decide whether to call notify().  It
- *             does not matter if the test is sometimes (rarely) backwards
- *             due to a race, since this will only delay the high-level
- *             processing by one tick, or call the high level unnecessarily.
- * The variables which are changed require more care:
- *     rp->p_user_time, rp->p_sys_time:
- *             These are protected by explicit locks in system.c.
- *     lost_ticks:
- *             Clock ticks counted outside the clock task.
- *     sched_ticks, prev_ptr:
- *             Updating these competes with similar code in do_clocktick().
- *             No lock is necessary, because if bad things happen here
- *             (like sched_ticks going negative), the code in do_clocktick()
- *             will restore the variables to reasonable values, and an
- *             occasional missed or extra sched() is harmless.
- *
- * Are these complications worth the trouble?  Well, they make the system 15%
- * faster on a 5MHz 8088, and make task debugging much easier since there are
- * no task switches on an inactive system.
  */
   register unsigned ticks;
-  message m;
 
   /* Acknowledge the PS/2 clock interrupt. */
   if (machine.ps_mca) outb(PORT_B, inb(PORT_B) | CLOCK_ACK_BIT);
@@ -215,17 +199,16 @@ irq_hook_t *hook;
    */
   proc_ptr->p_user_time += ticks;
   if (proc_ptr != bill_ptr) bill_ptr->p_sys_time += ticks;
-  if (proc_ptr->p_flags & PREEMPTIBLE) proc_ptr->p_sched_ticks -= ticks;
+  if (priv(proc_ptr)->s_flags & PREEMPTIBLE) proc_ptr->p_sched_ticks -= ticks;
 
   /* Check if do_clocktick() must be called. Done for alarms and scheduling.
    * Some processes, such as the kernel tasks, cannot be preempted. 
    */ 
   if ((next_timeout <= realtime) || (proc_ptr->p_sched_ticks <= 0)) {
       prev_ptr = proc_ptr;                     /* store running process */
-      m.NOTIFY_TYPE = HARD_INT;
-      lock_notify(CLOCK, &m);                  /* send event notification */
+      lock_alert(HARDWARE, CLOCK);             /* send notification */
   } 
-  return(1);                           /* reenable clock interrupts */
+  return(1);                                   /* reenable interrupts */
 }
 
 
@@ -289,6 +272,7 @@ PRIVATE void init_clock()
   enable_irq(&clock_hook);             /* ready for clock interrupts */
 }
 
+
 /*===========================================================================*
  *                             clock_stop                                   *
  *===========================================================================*/
index 23463571abbf1b1370edaf568534d3fd81d9e9cb..e640a205872c28f5eb029ac1c6d4b29ecfd86168 100755 (executable)
@@ -1,22 +1,21 @@
-/* General constants used by the kernel. */
+/* General macros and constants used by the kernel. */
+#ifndef CONST_H
+#define CONST_H
 
 #include <ibm/interrupt.h>     /* interrupt numbers and hardware vectors */
 #include <ibm/ports.h>         /* port addresses and magic numbers */
 #include <ibm/bios.h>          /* BIOS addresses, sizes and magic numbers */
 #include <ibm/cpu.h>           /* BIOS addresses, sizes and magic numbers */
 #include <minix/config.h>
+#include "config.h"
 
 /* To translate an address in kernel space to a physical address.  This is
  * the same as umap_local(proc_ptr, D, vir, sizeof(*vir)), but less costly.
  */
 #define vir2phys(vir)  (kinfo.data_base + (vir_bytes) (vir))
 
-/* Constants used in virtual_copy(). Values must be 0 and 1, respectively! */
-#define _SRC_  0
-#define _DST_  1
-
 /* Translate a pointer to a field in a structure to a pointer to the structure
- * itself.  So it translates '&struct_ptr->field' back to 'struct_ptr'.
+ * itself. So it translates '&struct_ptr->field' back to 'struct_ptr'.
  */
 #define structof(type, field, ptr) \
        ((type *) (((char *) (ptr)) - offsetof(type, field)))
 /* How many bytes for the kernel stack. Space allocated in mpx.s. */
 #define K_STACK_BYTES   1024   
 
-/* How long should the process names be in the kernel? */
-#define P_NAME_LEN     8
-
-/* Scheduling quantum. Number of ticks before preemption. */
-#define SCHED_MILLISEC         100             /* rate to call scheduler */
-#define SCHED_TICKS  (SCHED_MILLISEC*HZ/1000)  /* ticks per schedule */
-
-/* How many bytes should the circular buffer for kernel diagnostics. */
-#define KMESS_BUF_SIZE   256           
-
-/* Maximum size in bytes for (port,value)-pairs vector to copy in. */
-#define VDEVIO_BUF_SIZE   64
-
-/* How many elements in vector of virtual copy requests. */
-#define VCOPY_VEC_SIZE    16
-
-/* How many IRQ hooks are there in total. */
-#define NR_IRQ_HOOKS     16
-
-/* How many buffers for notification messages should there be? */
-#define NR_NOTIFY_BUFS   32
-
-/* Buffer to gather randomness. How many entries before wrapping? */
-#define RANDOM_ELEMENTS   32
+/* Constants used in virtual_copy(). Values must be 0 and 1, respectively. */
+#define _SRC_  0
+#define _DST_  1
 
 /* Constants and macros for bit map manipulation. */
 #define BITCHUNK_BITS   (sizeof(bitchunk_t) * CHAR_BIT)
 #define SET_BIT(map,bit) ( MAP_CHUNK(map,bit) |= (1 << CHUNK_OFFSET(bit) )
 #define UNSET_BIT(map,bit) ( MAP_CHUNK(map,bit) &= ~(1 << CHUNK_OFFSET(bit) )
 
+#define get_sys_bit(map,bit) \
+       ( MAP_CHUNK(map.chunk,bit) & (1 << CHUNK_OFFSET(bit) )
+#define set_sys_bit(map,bit) \
+       ( MAP_CHUNK(map.chunk,bit) |= (1 << CHUNK_OFFSET(bit) )
+#define unset_sys_bit(map,bit) \
+       ( MAP_CHUNK(map.chunk,bit) &= ~(1 << CHUNK_OFFSET(bit) )
+#define NR_SYS_CHUNKS  BITMAP_CHUNKS(NR_SYS_PROCS)
+
 
 #if (CHIP == INTEL)
 
 #define IF_MASK 0x00000200
 #define IOPL_MASK 0x003000
 
-#if ENABLE_LOCK_TIMING
-#define locktimestart(c, v) timer_start(c, v)
-#define locktimeend(c) timer_end(c)
-#else
-#define locktimestart(c, v)
-#define locktimeend(c)
-#endif
-
-#if ENABLE_K_LOCKCHECK
-#define lockcheck if(!(read_cpu_flags() & X86_FLAG_I)) kinfo.relocking++;
-#else
-#define lockcheck
-#endif
-
-/* Disable/Enable hardware interrupts. */
-#define lock(c, v)     do { lockcheck; intr_disable(); locktimestart(c, v); } while(0)
-#define unlock(c)      do { locktimeend(c); intr_enable(); } while(0)
+/* Disable/ enable hardware interrupts. The parameters of lock() and unlock()
+ * are used when debugging is enabled. See debug.h for more information.
+ */
+#define lock(c, v)     intr_disable(); 
+#define unlock(c)      intr_enable(); 
 
 /* Sizes of memory tables. The boot monitor distinguishes three memory areas, 
  * namely low mem below 1M, 1M-16M, and mem after 16M. More chunks are needed
  * for DOS MINIX.
  */
-#define NR_MEMS            8   /* number of chunks of memory */
+#define NR_MEMS            8   
+
 
 #endif /* (CHIP == INTEL) */
 
 /* M68000 specific constants go here. */
 #endif /* (CHIP == M68000) */
 
-#if ENABLE_INT_TIMING
-#define INT_TIMING_BITS                12
-#define INT_TIMING_ELEMENTS    (1L << 12)
-#endif
+#endif /* CONST_H */
similarity index 87%
rename from kernel/system/debugging.c
rename to kernel/debug.c
index 5c15f916264c3e75b87bb17b85eb75b4eea16a2e..05ad2716b71a3b59286795adc55c1119688bfa3e 100644 (file)
@@ -1,17 +1,17 @@
-/* The system call implemented in this file:
- *   m_type:   SYS_DEBUG
- *
- * The parameters for this system call are:
+/* This file implements kernel debugging functionality that is not included
+ * in the standard kernel. Available functionality includes timing of lock
+ * functions and sanity checking of the scheduling queues.
  */
 
-#include "../kernel.h"
-#include "../system.h"
-#include "../proc.h"
-#include "../glo.h"
+#include "kernel.h"
+#include "proc.h"
+#include "debug.h"
 #include <limits.h>
 
-#if ENABLE_LOCK_TIMING
+#if DEBUG_TIME_LOCKS           /* only include code if enabled */
 
+/* Data structures to store lock() timing data. */
+struct lock_timingdata timingdata[TIMING_CATEGORIES];
 static unsigned long starttimes[TIMING_CATEGORIES][2];
 
 #define HIGHCOUNT      0
@@ -42,8 +42,6 @@ void timer_start(int cat, char *name)
        }
 
        read_tsc(&starttimes[cat][HIGHCOUNT], &starttimes[cat][LOWCOUNT]);
-
-       return;
 }
 
 void timer_end(int cat)
@@ -102,9 +100,10 @@ void timer_end(int cat)
        return;
 }
 
-#endif
+#endif /* DEBUG_TIME_LOCKS */
 
-#if ENABLE_K_DEBUGGING         /* only include code if enabled */
+
+#if DEBUG_SCHED_CHECK          /* only include code if enabled */
 
 #define PROCLIMIT 10000
 
@@ -157,7 +156,7 @@ check_runqueues(char *when)
   }    
 
   for (xp = BEG_PROC_ADDR; xp < END_PROC_ADDR; ++xp) {
-       if(! isempty(xp) && xp->p_ready && ! xp->p_found) {
+       if(! isemptyp(xp) && xp->p_ready && ! xp->p_found) {
                kprintf("scheduling error: ready not on queue: %s\n", (karg_t) when);
                panic("ready proc not on scheduling queue", NO_NUM);
                if(l++ > PROCLIMIT) { panic("loop in proc.t?", NO_NUM); }
@@ -165,8 +164,4 @@ check_runqueues(char *when)
   }
 }
 
-/*==========================================================================*
- *                             do_debug                                    *
- *==========================================================================*/
-
-#endif /* ENABLE_K_DEBUGGING */
+#endif /* DEBUG_SCHED_CHECK */
index 259c29484d70919434cd4dd3617c92b1daf388a3..5b80995ef4266bac8181bc3cd141337210924c32 100644 (file)
@@ -1,15 +1,74 @@
 #ifndef DEBUG_H
 #define DEBUG_H
 
-#include <minix/config.h>
+/* This header file defines all debugging constants and macros, and declares
+ * some variables. Certain debugging features redefine standard constants
+ * and macros. Therefore, this header file should be included after the
+ * other kernel headers.
+ */
 
-#if ENABLE_LOCK_TIMING
+#include "config.h"
+
+/* It's interesting to measure the time spent withing locked regions, because
+ * this is the time that the system is deaf to interrupts.
+ */
+#if DEBUG_TIME_LOCKS
+
+#define TIMING_POINTS          20      /* timing resolution */
+#define TIMING_CATEGORIES      20
+#define TIMING_NAME            10
+
+/* Definition of the data structure to store lock() timing data. */ 
+struct lock_timingdata {
+       char names[TIMING_NAME];
+       unsigned long lock_timings[TIMING_POINTS];
+       unsigned long lock_timings_range[2];
+       unsigned long binsize, resets, misses, measurements;
+};
+
+/* The data is declared here, but allocated in debug.c. */
+extern struct lock_timingdata timingdata[TIMING_CATEGORIES];
+
+/* Prototypes for the timing functionality. */
 _PROTOTYPE( void timer_start, (int cat, char *name) );
 _PROTOTYPE( void timer_end, (int cat) );
-#endif
 
-#if ENABLE_K_DEBUGGING                                         /* debugging */
+#define locktimestart(c, v) timer_start(c, v)
+#define locktimeend(c) timer_end(c)
+#else
+#define locktimestart(c, v)
+#define locktimeend(c)
+#endif /* DEBUG_TIME_LOCKS */
+
+
+/* The locking checks counts relocking situation, which are dangerous because
+ * the inner lock may unlock the outer one.
+ */
+#if DEBUG_LOCK_CHECK
+#define lockcheck if (!(read_cpu_flags() & X86_FLAG_I)) kinfo.relocking++;
+#else
+#define lockcheck
+#endif /* DEBUG_LOCK_CHECK */
+
+
+/* This check makes sure that the scheduling queues are in a consistent state.
+ * The check is run when the queues are updated with ready() and unready().
+ */ 
+#if DEBUG_SCHED_CHECK                                  
 _PROTOTYPE( void check_runqueues, (char *when) );
+#endif /* DEBUG_SCHED_CHECK */
+
+
+/* The timing and checking of kernel locking requires a redefine of the lock()
+ * and unlock() macros. That's done here. This redefine requires that this 
+ * header is included after the other kernel headers.
+ */
+#if (DEBUG_TIME_LOCKS || DEBUG_LOCK_CHECK)
+#  undef lock
+#  define lock(c, v)   do { lockcheck; intr_disable(); locktimestart(c, v); } while(0)
+#  undef unlock
+#  define unlock(c)    do { locktimeend(c); intr_enable(); } while(0)
 #endif
 
-#endif /* DEBUG_H */
+
+#endif /* DEBUG_H */
index d6af1298e491d72e8eb9cef3b7c24eddadf4aaf8..6e19ed645318fc55ed0041c3ca1003cf2a8a2797 100755 (executable)
@@ -1,12 +1,11 @@
 /* This file contains a simple exception handler.  Exceptions in user
- * processes are converted to signals.  Exceptions in the kernel, MM and
- * FS cause a panic.
+ * processes are converted to signals. Exceptions in a kernel task cause
+ * a panic.
  */
 
 #include "kernel.h"
 #include <signal.h>
 #include "proc.h"
-#include "debug.h"
 
 /*==========================================================================*
  *                             exception                                   *
index 492e20e2c6373ad6cf9d45b16461ee2b07a9de7c..a8711d0f5716c6187e7677444d0a06d5542a446d 100755 (executable)
@@ -1,7 +1,10 @@
+#ifndef GLO_H
+#define GLO_H
+
 /* Global variables used in the kernel. This file contains the declarations;
  * storage space for the variables is allocated in table.c, because EXTERN is
  * defined as extern unless the _TABLE definition is seen. We rely on the 
- * compiler's default initialization (0) for several global variables.
+ * compiler's default initialization (0) for several global variables. 
  */
 #ifdef _TABLE
 #undef EXTERN
@@ -9,6 +12,7 @@
 #endif
 
 #include <minix/config.h>
+#include "config.h"
 
 /* Variables relating to shutting down MINIX. */
 EXTERN char kernel_exception;          /* TRUE after system exceptions */
@@ -42,11 +46,6 @@ EXTERN irq_hook_t *irq_handlers[NR_IRQ_VECTORS];/* list of IRQ handlers */
 EXTERN int irq_actids[NR_IRQ_VECTORS];         /* IRQ ID bits active */
 EXTERN int irq_use;                            /* map of all in-use irq's */
 
-/* Data structure to store lock() timing data. */
-#if ENABLE_LOCK_TIMING
-EXTERN struct lock_timedata timingdata[TIMING_CATEGORIES];
-#endif
-
 /* Miscellaneous. */
 EXTERN reg_t mon_ss, mon_sp;           /* boot monitor stack */
 EXTERN int mon_return;                 /* true if we can return to monitor */
@@ -63,3 +62,4 @@ EXTERN _PROTOTYPE( void (*level0_func), (void) );
 /* M68000 specific variables go here. */
 #endif
 
+#endif /* GLO_H */
index 64f5041b0a77e3bc3218ab0d8eaadefea4ce412c..04f96f74df6e4c15eb9d2f3e24bc649e44b811f4 100755 (executable)
@@ -7,7 +7,6 @@
 
 #include "kernel.h"
 #include "proc.h"
-#include "debug.h"
 #include <minix/com.h>
 
 #define ICW1_AT         0x11   /* edge triggered, cascade, need ICW4 */
@@ -49,7 +48,8 @@ int mine;
  */
   int i;
 
-  lock(6, "intr_init");
+  intr_disable();
+
   if (machine.protected) {
        /* The AT and newer PS/2 have two interrupt controllers, one master,
         * one slaved at IRQ 2.  (We don't have to deal with the PC that
index e9bab8d6d9a313f9adf8f1a48f94c923f403fb12..cb9d8f7b3feed0770a6c4a3358b5e3ddd1ed23cb 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef IPC_H
+#define IPC_H
+
 /* Masks and flags for system calls. */
 #define SYSCALL_FUNC   0x0F    /* mask for system call function */
 #define SYSCALL_FLAGS   0xF0    /* mask for system call flags */
 #define RECEIVE                 2      /* function code for receiving messages */
 #define SENDREC                 3      /* function code for SEND + RECEIVE */
 #define NOTIFY          4      /* function code for notifications */
+#define ALERT           5      /* function code for alerting */
 
 /* Call masks indicating which system calls a process can make. */
 #define EMPTY_CALL_MASK        (0)
-#define USER_CALL_MASK         (1 << SENDREC)
+#define _USER_CALL_MASK                ((1 << SENDREC) | (1 << ALERT))
 #define SYSTEM_CALL_MASK       (~0)
+#define USER_CALL_MASK         (~0)
 
 
+#endif /* IPC_H */
index 780ff8e26400b32aed1f2a4f07307fe328deb3f8..37838801ba2757e2a236f874c191d339425bbb3c 100755 (executable)
@@ -1,3 +1,6 @@
+#ifndef KERNEL_H
+#define KERNEL_H
+
 /* This is the master header for the kernel.  It includes some other files
  * and defines the principal constants.
  */
 #include <ibm/portio.h>                /* device I/O and toggle interrupts */ 
 #endif
 
-#include "const.h"             /* kernel constants */
-#include "type.h"              /* kernel type definitions */
-#include "proto.h"             /* kernel function prototypes */
-#include "glo.h"               /* kernel global variables */
+/* Important kernel header files. */
+#include "config.h"            /* configuration, MUST be first */
+#include "const.h"             /* constants, MUST be second */
+#include "type.h"              /* type definitions, MUST be third */
+#include "proto.h"             /* function prototypes */
+#include "glo.h"               /* global variables */
+#include "ipc.h"               /* IPC constants */
+#include "debug.h"             /* debugging, MUST be last kernel header */
 
+#endif /* KERNEL_H */
index e960b8534d440bdffeb9c224aebac15b990014ef..1c3cbd2d7f8ca5b441d6abd93f7a7d026e3170e6 100644 (file)
@@ -9,14 +9,13 @@
  *     kmemset:                set n bytes to c starting at pointer p
  *     kprintf:                printf for the kernel (see working below) 
  *     kstrcmp:                lexicographical comparison of two strings
- *     kstrlen:                get number of non-null characters in string
  *     kstrncpy:       copy string and pad or copy up to n chars 
  *
  * This file contains the routines that take care of kernel messages, i.e.,
  * diagnostic output within the kernel. Kernel messages are not directly
  * displayed on the console, because this must be done by the PRINT driver. 
  * Instead, the kernel accumulates characters in a buffer and notifies the
- * PRINT driver when a new message is ready. 
+ * output driver when a new message is ready. 
  */
 
 #include "kernel.h"
@@ -154,63 +153,31 @@ int c;                                    /* character to append */
 /* Accumulate a single character for a kernel message. Send a notification
  * the to PRINTF_PROC driver if an END_OF_KMESS is encountered. 
  */
-  message m;
   if (c != END_OF_KMESS) {
       kmess.km_buf[kmess.km_next] = c; /* put normal char in buffer */
       if (kmess.km_size < KMESS_BUF_SIZE)
           kmess.km_size += 1;          
       kmess.km_next = (kmess.km_next + 1) % KMESS_BUF_SIZE;
   } else {
-      m.NOTIFY_TYPE = NEW_KMESS;
-      lock_notify(PRINTF_PROC, &m);
+      lock_alert(SYSTEM, PRINTF_PROC);
   }
 }
 
 
-/*=========================================================================*
- *                             kstrlen                                    *
- *=========================================================================*/
-PUBLIC size_t kstrlen(const char *org)
-{
-  register const char *s = org;
-  while (*s++)
-       /* EMPTY */ ;
-  return --s - org;
-}
-
 
 /*=========================================================================*
  *                             kstrcmp                                    *
  *=========================================================================*/
 int kstrcmp(register const char *s1, register const char *s2) 
 {
-  while (*s1 == *s2++) {
+  while (*s1 == *s2++)
       if (*s1++ == '\0') return 0;
-  }
   if (*s1 == '\0') return -1;
   if (*--s2 == '\0') return 1;
   return (unsigned char) *s1 - (unsigned char) *s2;
 }
 
 
-/*=========================================================================*
- *                             kstrncmp                                   *
- *=========================================================================*/
-PUBLIC int kstrncmp(register const char *s1, register const char *s2, register size_t n)
-{
-  while (n > 0  &&  *s1 == *s2++) {
-      if (*s1++ == '\0') return 0;
-      n--;
-  } 
-  if (n > 0) {
-      if (*s1 == '\0') return -1;
-      if (*--s2 == '\0') return 1;
-      return (unsigned char) *s1 - (unsigned char) *s2;
-  }
-  return 0;
-}
-
-
 /*=========================================================================*
  *                             kstrncpy                                   *
  *=========================================================================*/
index 50641470cb51a010b984ef8ada0edd0a66454bed..13c3602f69419a6e18884a79feccc5accf548c65 100755 (executable)
@@ -19,7 +19,6 @@
 #include <minix/callnr.h>
 #include <minix/com.h>
 #include "proc.h"
-#include "sendmask.h"
 
 /* Prototype declarations for PRIVATE functions. */
 FORWARD _PROTOTYPE( void announce, (void));    
@@ -33,7 +32,8 @@ PUBLIC void main()
 {
 /* Start the ball rolling. */
   register struct proc *rp;
-  register int i;
+  register struct priv *sp;
+  register int i,s;
   int hdrindex;                        /* index to array of a.out headers */
   phys_clicks text_base;
   vir_clicks text_clicks;
@@ -46,13 +46,19 @@ PUBLIC void main()
   intr_init(1);
 
   /* Clear the process table. Anounce each slot as empty and set up mappings 
-   * for proc_addr() and proc_nr() macros.
+   * for proc_addr() and proc_nr() macros. Do the same for the table with 
+   * system properties structures. 
    */
   for (rp = BEG_PROC_ADDR, i = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++i) {
        rp->p_rts_flags = SLOT_FREE;            /* initialize free slot */
        rp->p_nr = i;                           /* proc number from ptr */
         (pproc_addr + NR_TASKS)[i] = rp;        /* proc ptr from number */
   }
+  for (sp = BEG_PRIV_ADDR, i = 0; sp < END_PRIV_ADDR; ++sp, ++i) {
+       sp->s_proc_nr = NONE;                   /* initialize as free */
+       sp->s_id = i;                           /* priv structure index */
+       ppriv_addr[i] = sp;                     /* priv ptr from number */
+  }
 
   /* Set up proc table entries for tasks and servers.  The stacks of the
    * kernel tasks are initialized to an array in data space.  The stacks
@@ -65,23 +71,23 @@ PUBLIC void main()
   /* Task stacks. */
   ktsb = (reg_t) t_stack;
 
-  for (i=0; i < IMAGE_SIZE; ++i) {
-       ip = &image[i];                         /* t's task attributes */
-       rp = proc_addr(ip->proc_nr);            /* t's process slot */
+  for (i=0; i < NR_BOOT_PROCS; ++i) {
+       ip = &image[i];                         /* process' attributes */
+       (void) init_proc(ip->proc_nr, NONE);    /* initialize new process */
+       rp = proc_addr(ip->proc_nr);            /* get process pointer */
        kstrncpy(rp->p_name, ip->proc_name, P_NAME_LEN);  /* set name */
        rp->p_name[P_NAME_LEN-1] = '\0';        /* just for safety */
-       rp->p_flags = ip->flags;                /* process flags */
        rp->p_max_priority = ip->priority;      /* max scheduling priority */
        rp->p_priority = ip->priority;          /* current priority */
        rp->p_quantum_size = ip->quantum;       /* quantum size in ticks */
        rp->p_sched_ticks = ip->quantum;        /* current credit */
        rp->p_full_quantums = QUANTUMS(ip->priority);  /* quantums left */
-       rp->p_call_mask = ip->call_mask;        /* allowed system calls */
-       rp->p_sendmask = ip->sendmask;          /* sendmask protection */
+       rp->p_priv->s_flags = ip->flags;        /* process flags */
+       rp->p_priv->s_call_mask = ip->call_mask;/* allowed system calls */
        if (i-NR_TASKS < 0) {                   /* part of the kernel? */ 
                if (ip->stksize > 0) {          /* HARDWARE stack size is 0 */
-                       rp->p_stguard = (reg_t *) ktsb;
-                       *rp->p_stguard = STACK_GUARD;
+                       rp->p_priv->s_stack_guard = (reg_t *) ktsb;
+                       *rp->p_priv->s_stack_guard = STACK_GUARD;
                }
                ktsb += ip->stksize;    /* point to high end of stack */
                rp->p_reg.sp = ktsb;    /* this task's initial stack ptr */
@@ -126,9 +132,6 @@ PUBLIC void main()
        }
        
        /* Set ready. The HARDWARE task is never ready. */
-#if ENABLE_K_DEBUGGING
-       rp->p_ready = 0;
-#endif
        if (rp->p_nr != HARDWARE) lock_ready(rp);       
        rp->p_rts_flags = 0;
 
@@ -198,12 +201,6 @@ int how;                           /* reason to shut down */
           return;                      /* await sys_abort() from TTY */
   }
 
-  /* The TTY expects two HARD_STOP notifications. One to switch to the 
-   * primary console for stop sequence output, and one to actually exit.
-   */
-  m.NOTIFY_TYPE = HARD_STOP;
-  lock_notify(TTY, &m);
-
   /* Allow processes to be scheduled to clean up, unless a CPU exception 
    * occurred. This is done by setting a timer. The timer argument passes
    * the shutdown status.
index 24399048f242725ae6b9b877437a505f1a5b40a1..4f3c53418bf61051b3b2632552777efaf837d906 100755 (executable)
  * nonempty lists. As shown above, this is not required with pointer pointers.
  */
 
-#include "kernel.h"
-#include <minix/callnr.h>
 #include <minix/com.h>
+#include <minix/callnr.h>
+#include "kernel.h"
 #include "proc.h"
-#include "const.h"
-#include "debug.h"
-#include "ipc.h"
-#include "sendmask.h"
 
 
 /* Scheduling and message passing functions. The functions are available to 
@@ -56,6 +52,7 @@ FORWARD _PROTOTYPE( int mini_send, (struct proc *caller_ptr, int dst,
                message *m_ptr, unsigned flags) );
 FORWARD _PROTOTYPE( int mini_receive, (struct proc *caller_ptr, int src,
                message *m_ptr, unsigned flags) );
+FORWARD _PROTOTYPE( int mini_alert, (struct proc *caller_ptr, int dst) );
 FORWARD _PROTOTYPE( int mini_notify, (struct proc *caller_ptr, int dst,
                message *m_ptr ) );
 
@@ -64,12 +61,22 @@ FORWARD _PROTOTYPE( void unready, (struct proc *rp) );
 FORWARD _PROTOTYPE( void sched, (struct proc *rp) );
 FORWARD _PROTOTYPE( void pick_proc, (void) );
 
-#define BuildMess(m,n) \
+
+#define BuildOldMess(m,n) \
        (m).NOTIFY_SOURCE = (n)->n_source, \
        (m).NOTIFY_TYPE = (n)->n_type, \
        (m).NOTIFY_FLAGS = (n)->n_flags, \
        (m).NOTIFY_ARG = (n)->n_arg;
 
+#define BuildMess(m_ptr, src, dst_ptr) \
+       (m_ptr)->m_source = (src);                                      \
+       (m_ptr)->m_type = NOTIFY_FROM(src);                             \
+       (m_ptr)->NOTIFY_TIMESTAMP = get_uptime();                       \
+       if ((src) == HARDWARE) {                                        \
+               (m_ptr)->NOTIFY_ARG = priv(dst_ptr)->s_int_pending;     \
+               priv(dst_ptr)->s_int_pending = 0;                       \
+       }
+
 #if (CHIP == INTEL)
 #define CopyMess(s,sp,sm,dp,dm) \
        cp_mess(s, (sp)->p_memmap[D].mem_phys, (vir_bytes)sm, (dp)->p_memmap[D].mem_phys, (vir_bytes)dm)
@@ -107,7 +114,7 @@ message *m_ptr;                     /* pointer to message in the caller's space */
    * kernel may only be SENDREC, because tasks always reply and may not block 
    * if the caller doesn't do receive(). 
    */
-  if (! (caller_ptr->p_call_mask & (1 << function)) || 
+  if (! (priv(caller_ptr)->s_call_mask & (1 << function)) || 
           (iskerneln(src_dst) && function != SENDREC))  
       return(ECALLDENIED);     
   
@@ -115,6 +122,7 @@ message *m_ptr;                     /* pointer to message in the caller's space */
   if (! (isokprocn(src_dst) || src_dst == ANY || function == ECHO))  
       return(EBADSRCDST);
 
+#if DEAD_CODE          /* temporarily disabled for testing ALERT */
   /* Check validity of message pointer. */
   vb = (vir_bytes) m_ptr;
   vlo = vb >> CLICK_SHIFT;     /* vir click for bottom of message */
@@ -132,6 +140,7 @@ message *m_ptr;                     /* pointer to message in the caller's space */
   if (vhi < vlo ||
       vhi - caller_ptr->p_memmap[D].mem_vir >= caller_ptr->p_memmap[D].mem_len) 
         return(EFAULT); 
+#endif
 #endif
 
   /* Now check if the call is known and try to perform the request. The only
@@ -169,6 +178,9 @@ message *m_ptr;                     /* pointer to message in the caller's space */
   case RECEIVE:                        
       result = mini_receive(caller_ptr, src_dst, m_ptr, flags);
       break;
+  case ALERT:
+      result = mini_alert(caller_ptr, src_dst);
+      break;
   case NOTIFY:
       result = mini_notify(caller_ptr, src_dst, m_ptr);
       break;
@@ -182,14 +194,16 @@ message *m_ptr;                   /* pointer to message in the caller's space */
   }
   
   /* If the caller made a successfull, blocking system call it's priority may
-   * be raised. The priority have been lowered if a process consumed to many 
-   * full quantums in a row to prevent damage from infinite loops 
+   * be raised. The priority may have been lowered if a process consumed too 
+   * many full quantums in a row to prevent damage from infinite loops 
    */
+#if DEAD_CODE          /* temporarily disabled for testing ALERT */
   if ((caller_ptr->p_priority > caller_ptr->p_max_priority) && 
          ! (flags & NON_BLOCKING) && (result == OK)) {
       caller_ptr->p_priority = caller_ptr->p_max_priority;
       caller_ptr->p_full_quantums = QUANTUMS(caller_ptr->p_priority);
   }
+#endif
 
   /* Now, return the result of the system call to the caller. */
   return(result);
@@ -264,6 +278,9 @@ unsigned flags;                             /* system call flags */
   register struct notification **ntf_q_pp;
   message m;
   int bit_nr;
+  sys_map_t *map;
+  bitchunk_t *chunk;
+  int i, src_id, src_proc_nr;
 
   /* Check to see if a message from desired source is already available.
    * The caller's SENDING flag may be set if SENDREC couldn't send. If it is
@@ -271,27 +288,36 @@ unsigned flags;                           /* system call flags */
    */
   if (!(caller_ptr->p_rts_flags & SENDING)) {
 
-    /* Check caller queue. Use pointer pointers to keep code simple. */
-    xpp = &caller_ptr->p_caller_q;
-    while (*xpp != NIL_PROC) {
-       if (src == ANY || src == proc_nr(*xpp)) {
-           /* Found acceptable message. Copy it and update status. */
-           CopyMess((*xpp)->p_nr, *xpp, (*xpp)->p_messbuf, caller_ptr, m_ptr);
-            if (((*xpp)->p_rts_flags &= ~SENDING) == 0) ready(*xpp);
-            *xpp = (*xpp)->p_q_link;           /* remove from queue */
-            return(OK);                                /* report success */
-       }
-       xpp = &(*xpp)->p_q_link;                /* proceed to next */
-    }
-
     /* Check if there are pending notifications, except for SENDREC. */
     if (! (flags & FRESH_ANSWER)) {
 
+        map = &priv(caller_ptr)->s_notify_pending;
+        for (chunk=&map->chunk[0]; chunk<&map->chunk[NR_SYS_CHUNKS]; chunk++) {
+
+            /* Find a pending notification from the requested source. */ 
+            if (! *chunk) continue;                    /* no bits in chunk */
+            for (i=0; ! (*chunk & (1<<i)); ++i) {}     /* look up the bit */
+            src_id = (chunk - &map->chunk[0]) * BITCHUNK_BITS + i;
+            if (src_id >= NR_SYS_PROCS) break;         /* out of range */
+            src_proc_nr = id_to_nr(src_id);            /* get source proc */
+            if (src!=ANY && src!=src_proc_nr) continue;        /* source not ok */
+            *chunk &= ~(1 << i);                       /* no longer pending */
+
+            /* Found a suitable source, deliver the notification message. */
+           BuildMess(&m, src_proc_nr, caller_ptr);     /* assemble message */
+            CopyMess(src_proc_nr, proc_addr(HARDWARE), &m, caller_ptr, m_ptr);
+            return(OK);                                        /* report success */
+        }
+
         ntf_q_pp = &caller_ptr->p_ntf_q;       /* get pointer pointer */
         while (*ntf_q_pp != NULL) {
             if (src == ANY || src == (*ntf_q_pp)->n_source) {
                /* Found notification. Assemble and copy message. */
-               BuildMess(m, *ntf_q_pp);
+               BuildOldMess(m, *ntf_q_pp);
+               if (m.m_source == HARDWARE) {
+                       m.NOTIFY_ARG = caller_ptr->p_priv->s_int_pending;
+                       caller_ptr->p_priv->s_int_pending = 0;
+               }
                 CopyMess((*ntf_q_pp)->n_source, proc_addr(HARDWARE), &m, 
                        caller_ptr, m_ptr);
                 /* Remove notification from queue and bit map. */
@@ -303,6 +329,20 @@ unsigned flags;                            /* system call flags */
            ntf_q_pp = &(*ntf_q_pp)->n_next;    /* proceed to next */
         }
     }
+
+    /* Check caller queue. Use pointer pointers to keep code simple. */
+    xpp = &caller_ptr->p_caller_q;
+    while (*xpp != NIL_PROC) {
+       if (src == ANY || src == proc_nr(*xpp)) {
+           /* Found acceptable message. Copy it and update status. */
+           CopyMess((*xpp)->p_nr, *xpp, (*xpp)->p_messbuf, caller_ptr, m_ptr);
+            if (((*xpp)->p_rts_flags &= ~SENDING) == 0) ready(*xpp);
+            *xpp = (*xpp)->p_q_link;           /* remove from queue */
+            return(OK);                                /* report success */
+       }
+       xpp = &(*xpp)->p_q_link;                /* proceed to next */
+    }
+
   }
 
   /* No suitable message is available or the caller couldn't send in SENDREC. 
@@ -320,6 +360,45 @@ unsigned flags;                            /* system call flags */
 }
 
 
+/*===========================================================================*
+ *                             mini_alert                                   * 
+ *===========================================================================*/
+PRIVATE int mini_alert(caller_ptr, dst)
+register struct proc *caller_ptr;      /* sender of the notification */
+int dst;                               /* which process to notify */
+{
+  register struct proc *dst_ptr = proc_addr(dst);
+  int src_id;                          /* source id for late delivery */
+  message m;                           /* the notification message */
+
+  /* Check to see if target is blocked waiting for this message. A process 
+   * can be both sending and receiving during a SENDREC system call.
+   */
+  if ((dst_ptr->p_rts_flags & (RECEIVING|SENDING)) == RECEIVING &&
+      (dst_ptr->p_getfrom == ANY || dst_ptr->p_getfrom == caller_ptr->p_nr)) {
+
+      /* Destination is indeed waiting for a message. Assemble a notification 
+       * message and deliver it. Copy from pseudo-source HARDWARE, since the
+       * message is in the kernel's address space.
+       */ 
+      BuildMess(&m, proc_nr(caller_ptr), dst_ptr);
+      CopyMess(proc_nr(caller_ptr), proc_addr(HARDWARE), &m, 
+          dst_ptr, dst_ptr->p_messbuf);
+      dst_ptr->p_rts_flags &= ~RECEIVING;      /* deblock destination */
+      if (dst_ptr->p_rts_flags == 0) ready(dst_ptr);
+      return(OK);
+  } 
+
+  /* Destination is not ready to receive the notification. Add it to the 
+   * bit map with pending notifications. Note the indirectness: the system id 
+   * instead of the process number is used in the pending bit map.
+   */ 
+  src_id = priv(caller_ptr)->s_id;
+  set_sys_bit(priv(dst_ptr)->s_notify_pending, src_id); 
+  return(OK);
+}
+
+
 /*===========================================================================*
  *                             mini_notify                                  * 
  *===========================================================================*/
@@ -337,15 +416,22 @@ message *m_ptr;                           /* pointer to message buffer */
   /* Check to see if target is blocked waiting for this message. A process 
    * can be both sending and receiving during a SENDREC system call.
    */
-  if ( (dst_ptr->p_rts_flags & (RECEIVING|SENDING)) == RECEIVING &&
-       (dst_ptr->p_getfrom == ANY || dst_ptr->p_getfrom == caller_ptr->p_nr)) {
+  if ((dst_ptr->p_rts_flags & (RECEIVING|SENDING)) == RECEIVING &&
+      (dst_ptr->p_getfrom == ANY || dst_ptr->p_getfrom == caller_ptr->p_nr)) {
+
+      /* Destination is indeed waiting for this message. Check if the source
+       * is HARDWARE; this is a special case that gets the map of pending
+       * interrupts as an argument. Then deliver the notification message. 
+       */
+      if (proc_nr(caller_ptr) == HARDWARE) {
+          m_ptr->NOTIFY_ARG = priv(dst_ptr)->s_int_pending;
+          priv(dst_ptr)->s_int_pending = 0;
+      }
 
-       /* Destination is indeed waiting for this message. */
-       CopyMess(proc_nr(caller_ptr), caller_ptr, m_ptr, 
-               dst_ptr, dst_ptr->p_messbuf);
-       dst_ptr->p_rts_flags &= ~RECEIVING;     /* deblock destination */
-       if (dst_ptr->p_rts_flags == 0) ready(dst_ptr);
-       return(OK);
+      CopyMess(proc_nr(caller_ptr), caller_ptr, m_ptr, dst_ptr, dst_ptr->p_messbuf);
+      dst_ptr->p_rts_flags &= ~RECEIVING;      /* deblock destination */
+      if (dst_ptr->p_rts_flags == 0) ready(dst_ptr);
+      return(OK);
   } 
 
   /* Destination is not ready. Add the notification to the pending queue. 
@@ -389,26 +475,27 @@ message *m_ptr;                           /* pointer to message buffer */
 /*==========================================================================*
  *                             lock_notify                                 *
  *==========================================================================*/
-PUBLIC int lock_notify(dst, m_ptr)
-int dst;                       /* to whom is message being sent? */
-message *m_ptr;                        /* pointer to message buffer */
+PUBLIC int lock_alert(src, dst)
+int src;                       /* sender of the notification */
+int dst;                       /* who is to be notified */
 {
-/* Safe gateway to mini_notify() for tasks and interrupt handlers. MINIX 
+/* Safe gateway to mini_notify() for tasks and interrupt handlers. The sender
+ * is explicitely given to prevent confusion where the call comes from. MINIX 
  * kernel is not reentrant, which means to interrupts are disabled after 
  * the first kernel entry (hardware interrupt, trap, or exception). Locking
- * work is done by temporarily disabling interrupts. 
+ * is done by temporarily disabling interrupts. 
  */
   int result;
 
   /* Exception or interrupt occurred, thus already locked. */
   if (k_reenter >= 0) {
-      result = mini_notify(proc_addr(HARDWARE), dst, m_ptr); 
+      result = mini_alert(proc_addr(src), dst); 
   }
 
   /* Call from task level, locking is required. */
   else {
-      lock(0, "notify");
-      result = mini_notify(proc_ptr, dst, m_ptr); 
+      lock(0, "alert");
+      result = mini_alert(proc_addr(src), dst); 
       unlock(0);
   }
   return(result);
@@ -424,11 +511,9 @@ register struct proc *rp;  /* this process is now runnable */
 /* Add 'rp' to one of the queues of runnable processes.  */
   register int q = rp->p_priority;             /* scheduling queue to use */
 
-#if ENABLE_K_DEBUGGING
-  if(rp->p_ready) {
-       kprintf("ready() already ready process\n", NO_NUM);
-  }
-  rp->p_ready = 1;
+#if DEBUG_SCHED_CHECK
+  check_runqueues("ready");
+  if(rp->p_ready) kprintf("ready() already ready process\n", NO_NUM);
 #endif
 
   /* Processes, in principle, are added to the end of the queue. However, 
@@ -439,7 +524,7 @@ register struct proc *rp;   /* this process is now runnable */
       rdy_head[q] = rdy_tail[q] = rp;          /* create a new queue */
       rp->p_nextready = NIL_PROC;              /* mark new end */
   } 
-  else if (rp->p_flags & SCHED_Q_HEAD) {       /* add to head of queue */
+  else if (priv(rp)->s_flags & RDY_Q_HEAD) {    /* add to head of queue */
       rp->p_nextready = rdy_head[q];           /* chain head of queue */
       rdy_head[q] = rp;                                /* set new queue head */
   } 
@@ -449,6 +534,11 @@ register struct proc *rp;  /* this process is now runnable */
       rp->p_nextready = NIL_PROC;              /* mark new end */
   }
   pick_proc();                                 /* select next to run */
+
+#if DEBUG_SCHED_CHECK
+  rp->p_ready = 1;
+  check_runqueues("ready");
+#endif
 }
 
 /*===========================================================================*
@@ -463,19 +553,17 @@ register struct proc *rp; /* this process is no longer runnable */
   register struct proc **xpp;                  /* iterate over queue */
   register struct proc *prev_xp;
 
-#if ENABLE_K_DEBUGGING
-  if(!rp->p_ready) {
-       kprintf("unready() already unready process\n", NO_NUM);
-  }
-  rp->p_ready = 0;
-#endif
-
   /* Side-effect for kernel: check if the task's stack still is ok? */
   if (iskernelp(rp)) {                                 
-       if (*rp->p_stguard != STACK_GUARD)
+       if (*priv(rp)->s_stack_guard != STACK_GUARD)
                panic("stack overrun by task", proc_nr(rp));
   }
 
+#if DEBUG_SCHED_CHECK
+  check_runqueues("unready");
+  if (! rp->p_ready) kprintf("unready() already unready process\n", NO_NUM);
+#endif
+
   /* Now make sure that the process is not in its ready queue. Remove the 
    * process if it is found. A process can be made unready even if it is not 
    * running by being sent a signal that kills it.
@@ -493,6 +581,11 @@ register struct proc *rp;  /* this process is no longer runnable */
       }
       prev_xp = *xpp;                          /* save previous in chain */
   }
+
+#if DEBUG_SCHED_CHECK
+  rp->p_ready = 0;
+  check_runqueues("unready");
+#endif
 }
 
 /*===========================================================================*
@@ -504,16 +597,19 @@ struct proc *sched_ptr;                           /* quantum eating process */
   int q;
 
   /* Check if this process is preemptible, otherwise leave it as is. */
-  if (! (sched_ptr->p_flags & PREEMPTIBLE)) { 
+  if (! (priv(sched_ptr)->s_flags & PREEMPTIBLE)) { 
+#if DEAD_CODE
       kprintf("Warning, sched for nonpreemptible proc %d\n", sched_ptr->p_nr);
+#endif
       return;
   }
 
+#if DEAD_CODE
   if (sched_ptr->p_nr == IS_PROC_NR) {
       kprintf("Scheduling IS: pri: %d, ", sched_ptr->p_priority);
       kprintf("qua %d", sched_ptr->p_full_quantums);
   }
-
+#endif
   /* Process exceeded the maximum number of full quantums it is allowed
    * to use in a row. Lower the process' priority, but make sure we don't 
    * end up in the IDLE queue. This helps to limit the damage caused by 
@@ -525,8 +621,10 @@ struct proc *sched_ptr;                            /* quantum eating process */
           unready(sched_ptr);                  /* remove from queues */
           sched_ptr->p_priority ++;            /* lower priority */
           ready(sched_ptr);                    /* add to new queue */
+#if DEAD_CODE
 kprintf("Warning, proc %d got lower priority: ", sched_ptr->p_nr);
 kprintf("%d\n", sched_ptr->p_priority);
+#endif
       }
       sched_ptr->p_full_quantums = QUANTUMS(sched_ptr->p_priority);
   }
@@ -548,12 +646,13 @@ kprintf("%d\n", sched_ptr->p_priority);
   sched_ptr->p_sched_ticks = sched_ptr->p_quantum_size;
   pick_proc();                                 
 
+#if DEAD_CODE
   if (sched_ptr->p_nr == IS_PROC_NR) {
       kprintf("Next proc: %d, ", next_ptr->p_nr); 
       kprintf("pri: %d, ", next_ptr->p_priority); 
       kprintf("qua: %d\n", next_ptr->p_full_quantums); 
-
   }
+#endif
 }
 
 
@@ -576,7 +675,7 @@ PRIVATE void pick_proc()
   for (q=0; q < NR_SCHED_QUEUES; q++) {        
       if ( (rp = rdy_head[q]) != NIL_PROC) {
           next_ptr = rp;                       /* run process 'rp' next */
-          if (rp->p_flags & BILLABLE)          
+          if (priv(rp)->s_flags & BILLABLE)            
               bill_ptr = rp;                   /* bill for system time */
           return;                               
       }
index eb7d8e74cca49b114792dc712d01371f9832ec58..dc5c7f096577cb736f75a8cf774ec956a5780091 100755 (executable)
@@ -12,6 +12,7 @@
 #include <minix/com.h>
 #include "protect.h"
 #include "const.h"
+#include "priv.h"
  
 struct proc {
   struct stackframe_s p_reg;   /* process' registers saved in stack frame */
@@ -25,9 +26,8 @@ struct proc {
 /* M68000 specific registers and FPU details go here. */
 #endif 
 
-  reg_t *p_stguard;            /* stack guard word */
   proc_nr_t p_nr;              /* number of this process (for fast access) */
-  char p_flags;                        /* PREEMTIBLE, BILLABLE, etc. */
+  struct priv *p_priv;         /* system privileges structure */
   char p_rts_flags;            /* SENDING, RECEIVING, etc. */
 
   char p_priority;             /* current scheduling priority */
@@ -36,11 +36,7 @@ struct proc {
   char p_sched_ticks;          /* number of scheduling ticks left */
   char p_full_quantums;                /* number of full quantums left */
 
-  char p_call_mask;            /* bit map with allowed system call traps */
-  send_mask_t p_sendmask;      /* mask indicating to whom proc may send */
-
-  struct mem_map p_memmap[NR_LOCAL_SEGS];   /* local memory map (T, D, S) */
-  struct far_mem p_farmem[NR_REMOTE_SEGS];  /* remote memory map */
+  struct mem_map p_memmap[NR_LOCAL_SEGS];   /* memory map (T, D, S) */
 
   clock_t p_user_time;         /* user time in ticks */
   clock_t p_sys_time;          /* sys time in ticks */
@@ -53,19 +49,15 @@ struct proc {
   proc_nr_t p_getfrom;         /* from whom does process want to receive? */
   proc_nr_t p_sendto;          /* to whom does process want to send? */
 
-  timer_t p_alarm_timer;       /* timer shared by different alarm types */ 
   sigset_t p_pending;          /* bit map for pending kernel signals */
 
   char p_name[P_NAME_LEN];     /* name of the process, including \0 */
 
-#if ENABLE_K_DEBUGGING
+#if DEBUG_SCHED_CHECK
   int p_ready, p_found;
 #endif
 };
 
-/* Guard word for task stacks. */
-#define STACK_GUARD    ((reg_t) (sizeof(reg_t) == 2 ? 0xBEEF : 0xDEADBEEF))
-
 /* Bits for the runtime flags. A process is runnable iff p_rts_flags == 0. */
 #define SLOT_FREE      0x01    /* process slot is free */
 #define NO_MAP         0x02    /* keeps unmapped forked child from running */
@@ -74,11 +66,7 @@ struct proc {
 #define SIGNALED       0x10    /* set when new kernel signal arrives */
 #define SIG_PENDING    0x20    /* unready while signal being processed */
 #define P_STOP         0x40    /* set when process is being traced */
-
-/* Bits for the other process flags. */
-#define PREEMPTIBLE    0x01    /* kernel tasks are not preemptible */
-#define SCHED_Q_HEAD    0x02   /* add to queue head instead of tail */
-#define BILLABLE       0x04    /* system services are not billable */
+#define NO_PRIV                0x80    /* privilege structure not yet initialized */
 
 /* Scheduling priorities for p_priority. Values must start at zero (highest
  * priority) and increment. Priorities of the processes in the boot image can 
index 4b8acead1da459f2ce44208de63674d48a18b063..a7f7ca15bf652f02bd3f85849193e1ed28585a6a 100755 (executable)
@@ -215,7 +215,6 @@ vir_bytes size;
 int privilege;
 {
 /* Build descriptor for a data segment. */
-
   sdesc(segdp, base, size);
   segdp->access = (privilege << DPL_SHIFT) | (PRESENT | SEGMENT | WRITEABLE);
                /* EXECUTABLE = 0, EXPAND_DOWN = 0, ACCESSED = 0 */
index b26a21a0e74173d8b4eeea4610013089e40bd555..ef25c46c0feefdd605eb89c545c35464b32cd1bc 100755 (executable)
@@ -13,16 +13,13 @@ _PROTOTYPE( void clock_stop, (void)                                 );
 _PROTOTYPE( clock_t get_uptime, (void)                                 );
 _PROTOTYPE( unsigned long read_clock, (void)                           );
 _PROTOTYPE( void set_timer, (struct timer *tp, clock_t t, tmr_func_t f)        );
-_PROTOTYPE( void reset_timer, (struct timer *tp)                               );
+_PROTOTYPE( void reset_timer, (struct timer *tp)                       );
 
 /* klibc.c */
 _PROTOTYPE( int katoi, (register const char *s));
 _PROTOTYPE( void *kmemcpy, (void *s1, const void *s2, register size_t n));
 _PROTOTYPE( void *kmemset, (void *s, register int c, register size_t n));
 _PROTOTYPE( int kstrcmp, (register const char *s1, register const char *s2));
-_PROTOTYPE( size_t kstrlen, (const char *s));
-_PROTOTYPE( int kstrncmp,
-       (register const char *s1, register const char *s2, register size_t n));
 _PROTOTYPE( char *kstrncpy, 
        (char *s1, register const char *s2, register const ssize_t n));
 #define karg(arg) (karg_t) (arg)
@@ -33,14 +30,16 @@ _PROTOTYPE( void main, (void)                                               );
 _PROTOTYPE( void prepare_shutdown, (int how)                           );
 _PROTOTYPE( void stop_sequence, (struct timer *tp)                     );
 
-/* misc.c */
+/* utility.c */
 _PROTOTYPE( void panic, (_CONST char *s, int n)                                );
+_PROTOTYPE( void safe_lock, (int c, char *v)                           );
+_PROTOTYPE( void safe_unlock, (void)                                   );
 _PROTOTYPE( int alloc_bit, (bitchunk_t *map, bit_t nr_bits)            ); 
 _PROTOTYPE( void free_bit, (bit_t nr, bitchunk_t *map, bit_t nr_bits)  ); 
 
 /* proc.c */
 _PROTOTYPE( int sys_call, (int function, int src_dest, message *m_ptr) );
-_PROTOTYPE( int lock_notify, (int dst, message *m_ptr)                 );
+_PROTOTYPE( int lock_alert, (int src, int dst)                                 );
 _PROTOTYPE( int lock_send, (int dst, message *m_ptr)                   );
 _PROTOTYPE( void lock_ready, (struct proc *rp)                         );
 _PROTOTYPE( void lock_sched, (struct proc *rp)                         );
@@ -52,6 +51,7 @@ _PROTOTYPE( void cstart, (U16_t cs, U16_t ds, U16_t mds,
 
 /* system.c */
 _PROTOTYPE( void cause_sig, (int proc_nr, int sig_nr)                  );
+_PROTOTYPE( int init_proc, (int proc_nr, int proto_nr)                 );
 _PROTOTYPE( void clear_proc, (int proc_nr)                             );
 _PROTOTYPE( phys_bytes numap_local, (int proc_nr, vir_bytes vir_addr, 
                vir_bytes bytes)                                        );
index d5db29770ddc7465a269203a473ad30c0721bac8..6b56917d5ad76d0766205fb4618e6ce96567b714 100755 (executable)
@@ -22,6 +22,7 @@
  *   generic_handler:  interrupt handler for user-level device drivers
  *
  * Changes:
+ *   Apr 25, 2005   new init_proc() function  (Jorrit N. Herder)
  *   Apr 25, 2005   made mapping of call vector explicit  (Jorrit N. Herder)
  *   Oct 29, 2004   new clear_proc() function  (Jorrit N. Herder)
  *   Oct 17, 2004   generic handler and IRQ policies  (Jorrit N. Herder)
@@ -38,8 +39,6 @@
 #include <unistd.h>
 #include <sys/sigcontext.h>
 #include <sys/svrctl.h>
-#include <minix/callnr.h>
-#include "sendmask.h"
 #if (CHIP == INTEL)
 #include <ibm/memory.h>
 #include "protect.h"
@@ -55,7 +54,7 @@ PUBLIC int (*call_vec[NR_SYS_CALLS])(message *m_ptr);
 
 #define map(call_nr, handler) \
        {extern int dummy[NR_SYS_CALLS > (unsigned) (call_nr) ? 1 : -1];} \
-       call_vec[(call_nr)] = (handler) 
+       call_vec[(call_nr)] = (handler)  
 
 FORWARD _PROTOTYPE( void initialize, (void));
 
@@ -78,11 +77,9 @@ PUBLIC void sys_task()
 
       /* Handle the request. */
       if ((unsigned) m.m_type < NR_SYS_CALLS) {
-          result = (*call_vec[m.m_type])(&m);  /* do system call */
-      } else if(m.NOTIFY_TYPE == KSIG_PENDING) {
-         message pmm;
-          pmm.NOTIFY_TYPE = KSIG_PENDING;
-          lock_notify(PM_PROC_NR, &pmm);
+          result = (*call_vec[m.m_type])(&m);  /* handle the kernel call */
+      } else if (m.m_type == NEW_KSIG) {       
+          lock_alert(SYSTEM, PM_PROC_NR);      /* tell PM about signal */
           continue;
       } else {
          kprintf("Warning, illegal SYSTASK request from %d.\n", m.m_source);
@@ -94,7 +91,7 @@ PUBLIC void sys_task()
        * is known to be blocked waiting for a message.
        */
       if (result != EDONTREPLY) {
-         m.m_type = result;    /* report status of call */
+         m.m_type = result;                    /* report status of call */
           if (OK != lock_send(m.m_source, &m)) {
               kprintf("Warning, SYSTASK couldn't reply to request from %d\n", 
                    m.m_source);
@@ -109,7 +106,7 @@ PUBLIC void sys_task()
  *===========================================================================*/
 PRIVATE void initialize(void)
 {
-  register struct proc *rp;
+  register struct priv *sp;
   int i;
 
   /* Initialize IRQ handler hooks. Mark all hooks available. */
@@ -118,8 +115,8 @@ PRIVATE void initialize(void)
   }
 
   /* Initialize all alarm timers for all processes. */
-  for (rp=BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) {
-    tmr_inittimer(&(rp->p_alarm_timer));
+  for (sp=BEG_PRIV_ADDR; sp < END_PRIV_ADDR; sp++) {
+    tmr_inittimer(&(sp->s_alarm_timer));
   }
 
   /* Initialize the call vector to a safe default handler. Some system calls 
@@ -132,23 +129,22 @@ PRIVATE void initialize(void)
   }
 
   /* Process management. */
-  map(SYS_FORK, do_fork);      /* informs kernel that a process has forked */
-  map(SYS_XIT, do_xit);                /* informs kernel that a process has exited */
-  map(SYS_NEWMAP, do_newmap);  /* allows PM to set up a process memory map */
-  map(SYS_EXEC, do_exec);      /* sets program counter and stack pointer after EXEC */
-  map(SYS_TRACE, do_trace);    /* request a trace operation */
+  map(SYS_FORK, do_fork);              /* a process forked a new process */
+  map(SYS_NEWMAP, do_newmap);          /* set up a process memory map */
+  map(SYS_EXEC, do_exec);              /* update process after execute */
+  map(SYS_EXIT, do_exit);              /* clean up after process exit */
+  map(SYS_TRACE, do_trace);            /* request a trace operation */
 
   /* Signal handling. */
   map(SYS_KILL, do_kill);              /* cause a process to be signaled */
-  map(SYS_GETSIG, do_getsig);          /* PM checks for pending signals */
-  map(SYS_ENDSIG, do_endsig);          /* PM finished processing signal */
+  map(SYS_GETKSIG, do_getksig);                /* PM checks for pending signals */
+  map(SYS_ENDKSIG, do_endksig);                /* PM finished processing signal */
   map(SYS_SIGSEND, do_sigsend);                /* start POSIX-style signal */
   map(SYS_SIGRETURN, do_sigreturn);    /* return from POSIX-style signal */
 
   /* Clock functionality. */
   map(SYS_TIMES, do_times);            /* get uptime and process times */
-  map(SYS_SIGNALRM, do_signalrm);      /* causes an alarm signal */
-  map(SYS_SYNCALRM, do_syncalrm);      /* send a notification message */
+  map(SYS_SETALARM, do_setalarm);      /* schedule a synchronous alarm */
 
   /* Device I/O. */
   map(SYS_IRQCTL, do_irqctl);                  /* interrupt control operations */ 
@@ -156,25 +152,60 @@ PRIVATE void initialize(void)
   map(SYS_SDEVIO, do_sdevio);          /* phys_insb, _insw, _outsb, _outsw */
   map(SYS_VDEVIO, do_vdevio);                  /* vector with devio requests */ 
 
-  /* Server and driver control. */
+  /* System control. */
+  map(SYS_SETPRIORITY, do_schedctl);   /* set scheduling priority */
   map(SYS_SEGCTL, do_segctl);          /* add segment and get selector */
-  map(SYS_IOPENABLE, do_iopenable);    /* enable CPU I/O protection bits */
   map(SYS_SVRCTL, do_svrctl);          /* kernel control functions */
 
   /* Copying. */
   map(SYS_UMAP, do_umap);              /* map virtual to physical address */
   map(SYS_VIRCOPY, do_vircopy);        /* use pure virtual addressing */
   map(SYS_PHYSCOPY, do_physcopy);      /* use physical addressing */
-  map(SYS_PHYSZERO, do_physzero);      /* zero physical memory region */
   map(SYS_VIRVCOPY, do_virvcopy);      /* vector with copy requests */
   map(SYS_PHYSVCOPY, do_physvcopy);    /* vector with copy requests */
-  map(SYS_SETPRIORITY, do_setpriority);        /* set scheduling priority */
+  map(SYS_MEMSET, do_memset);          /* write char to memory area */
 
   /* Miscellaneous. */
   map(SYS_ABORT, do_abort);            /* abort MINIX */
   map(SYS_GETINFO, do_getinfo);        /* request system information */ 
 }
 
+
+/*===========================================================================*
+ *                              init_proc                                   *
+ *===========================================================================*/
+PUBLIC int init_proc(proc_nr, proto_nr)
+int proc_nr;                           /* slot of process to initialize */
+int proto_nr;                          /* prototype process to copy from */
+{
+  register struct proc *rc, *rp;
+  register struct priv *sp;
+  int i;
+
+  /* Get a pointer to the process to initialize. */
+  rc = proc_addr(proc_nr);
+  
+  /* If there is a prototype process to initialize from, use it. Otherwise,
+   * assume the caller will take care of initialization, but make sure that 
+   * the new process gets a pointer to a system properties structure.
+   */
+  if (isokprocn(proto_nr)) {
+      kprintf("INIT proc from prototype %d\n", proto_nr);
+
+  } else {
+      for (sp = BEG_PRIV_ADDR, i = 0; sp < END_PRIV_ADDR; ++sp, ++i) {
+          if (sp->s_proc_nr == NONE) {         /* found free slot */
+              sp->s_proc_nr = proc_nr;         /* set association */
+              rc->p_priv = sp;                 /* assign to process */
+              return(OK);
+          }
+      }
+      kprintf("No free PRIV structure!\n", NO_NUM);
+      return(ENOSPC);                          /* out of resources */
+  }
+}
+
+
 /*===========================================================================*
  *                              clear_proc                                  *
  *===========================================================================*/
@@ -189,7 +220,7 @@ int proc_nr;                                /* slot of process to clean up */
   rc = proc_addr(proc_nr);
 
   /* Turn off any alarm timers at the clock. */   
-  reset_timer(&rc->p_alarm_timer);
+  reset_timer(&rc->p_priv->s_alarm_timer);
 
   /* Make sure the exiting process is no longer scheduled. */
   if (rc->p_rts_flags == 0) lock_unready(rc);
@@ -232,7 +263,6 @@ int proc_nr;                                /* slot of process to clean up */
   kstrncpy(rc->p_name, "<none>", P_NAME_LEN);  /* unset name */
   sigemptyset(&rc->p_pending);         /* remove pending signals */
   rc->p_rts_flags = SLOT_FREE;         /* announce slot empty */
-  rc->p_sendmask = DENY_ALL_MASK;      /* set most restrictive mask */
 
 #if (CHIP == M68000)
   pmmu_delete(rc);                     /* we're done, remove tables */
@@ -260,7 +290,7 @@ PUBLIC void get_randomness()
    * On machines without RDTSC, we use the get_uptime() - read_clock()
    * has a higher resolution, but would involve I/O calls.
    */
-  if(machine.processor > 486)
+  if (machine.processor > 486)
          read_tsc(&tsc_high, &krandom.r_buf[krandom.r_next]);
   else
          krandom.r_buf[krandom.r_next] = get_uptime();
@@ -278,18 +308,21 @@ irq_hook_t *hook;
 /* This function handles hardware interrupt in a simple and generic way. All
  * interrupts are transformed into messages to a driver. The IRQ line will be
  * reenabled if the policy says so.
- * In addition, the interrupt handler gathers random information in a buffer
- * by timestamping the interrupts.
  */
-  message m;
 
-  /* Gather random information. */ 
+  /* As a side-effect, the interrupt handler gathers random information by 
+   * timestamping the interrupt events. This is used for /dev/random.
+   */
   get_randomness();
 
+  /* Add a bit for this interrupt to the process' pending interrupts. When 
+   * sending the notification message, this bit map will be magically set
+   * as an argument. 
+   */
+  priv(proc_addr(hook->proc_nr))->s_int_pending |= (1 << hook->irq);
+
   /* Build notification message and return. */
-  m.NOTIFY_TYPE = HARD_INT;
-  m.NOTIFY_ARG = hook->irq;
-  lock_notify(hook->proc_nr, &m);
+  lock_alert(HARDWARE, hook->proc_nr);
   return(hook->policy & IRQ_REENABLE);
 }
 
@@ -302,9 +335,9 @@ int proc_nr;                        /* process to be signalled */
 int sig_nr;                    /* signal to be sent, 1 to _NSIG */
 {
 /* A system process wants to send a signal to a process.  Examples are:
- *   TTY wanting to cause SIGINT upon getting a DEL
- *   CLOCK wanting to cause SIGALRM when timer expires
- *   FS wanting to cause SIGPIPE for a broken pipe 
+ *  - HARDWARE wanting to cause a SIGSEGV after a CPU exception
+ *  - TTY wanting to cause SIGINT upon getting a DEL
+ *  - FS wanting to cause SIGPIPE for a broken pipe 
  * Signals are handled by sending a message to PM.  This function handles the 
  * signals and makes sure the PM gets them by sending a notification. The 
  * process being signaled is blocked while PM has not finished all signals 
@@ -313,7 +346,6 @@ int sig_nr;                 /* signal to be sent, 1 to _NSIG */
  * PM can block waiting for FS to do a core dump.
  */
   register struct proc *rp;
-  message m;
 
   /* Check if the signal is already pending. Process it otherwise. */
   rp = proc_addr(proc_nr);
@@ -322,8 +354,7 @@ int sig_nr;                 /* signal to be sent, 1 to _NSIG */
       if (! (rp->p_rts_flags & SIGNALED)) {            /* other pending */
           if (rp->p_rts_flags == 0) lock_unready(rp);  /* make not ready */
           rp->p_rts_flags |= SIGNALED | SIG_PENDING;   /* update flags */
-          m.NOTIFY_TYPE = KSIG_PENDING;
-          lock_notify(SYSTASK, &m);
+          lock_alert(HARDWARE, SYSTEM);
       }
   }
 }
@@ -370,7 +401,6 @@ vir_bytes vir_addr;         /* virtual address in bytes within the seg */
 vir_bytes bytes;               /* # of bytes to be copied */
 {
 /* Calculate the physical memory address for a given virtual address. */
-
   vir_clicks vc;               /* the virtual address in clicks */
   phys_bytes pa;               /* intermediate variables as phys_bytes */
 #if (CHIP == INTEL)
@@ -451,7 +481,7 @@ vir_bytes bytes;            /* # of bytes to be copied */
   if (bytes <= 0) return( (phys_bytes) 0);
   if (seg < 0 || seg >= NR_REMOTE_SEGS) return( (phys_bytes) 0);
 
-  fm = &rp->p_farmem[seg];
+  fm = &rp->p_priv->s_farmem[seg];
   if (! fm->in_use) return( (phys_bytes) 0);
   if (vir_addr + bytes > fm->mem_len) return( (phys_bytes) 0);
 
index 3faeed6b1c7ecb51c3698351ed81eaa770ed5ddb..c787f5683d5f9ff36683fb4722111083e89e55ea 100644 (file)
-/* Function prototypes for the system library. The implementation is contained
- * in src/kernel/system/. The system library allows to access system services
- * by doing a system call. System calls are  transformed into request messages
- * to the SYS task that is responsible for handling the call. By convention, a
- * sys_call() is transformed into a message with type SYS_CALL that is handled
- * in a function named do_call(). 
+/* Function prototypes for the system library.  The prototypes in this file 
+ * are undefined to do_unused if the kernel call is not enabled in config.h. 
+ * The implementation is contained in src/kernel/system/.  
+ *
+ * The system library allows to access system services by doing a system call.
+ * System calls are transformed into request messages to the SYS task that is 
+ * responsible for handling the call. By convention, sys_call() is transformed 
+ * into a message with type SYS_CALL that is handled in a function do_call(). 
  */ 
 
 #ifndef SYSTEM_H
 #define SYSTEM_H
 
 /* Common includes for the system library. */
-#include <minix/com.h>
-#include <minix/config.h>
+#include "kernel.h"
 #include "proc.h"
 
-_PROTOTYPE( int do_exec, (message *m_ptr) );           /* process control */
+/* Default handler for unused kernel calls. */
+_PROTOTYPE( int do_unused, (message *m_ptr) );
+
+_PROTOTYPE( int do_exec, (message *m_ptr) );           
+#if ! USE_EXEC
+#define do_exec do_unused
+#endif
+
 _PROTOTYPE( int do_fork, (message *m_ptr) );
+#if ! USE_FORK
+#define do_fork do_unused
+#endif
+
 _PROTOTYPE( int do_newmap, (message *m_ptr) );
-_PROTOTYPE( int do_xit, (message *m_ptr) );
+#if ! USE_NEWMAP
+#define do_newmap do_unused
+#endif
+
+_PROTOTYPE( int do_exit, (message *m_ptr) );
+#if ! USE_EXIT
+#define do_exit do_unused
+#endif
+
+_PROTOTYPE( int do_trace, (message *m_ptr) );  
+#if ! USE_TRACE
+#define do_trace do_unused
+#endif
+
+_PROTOTYPE( int do_schedctl, (message *m_ptr) );
+#if ! USE_SCHEDCTL
+#define do_schedctl do_unused
+#endif
 
-_PROTOTYPE( int do_copy, (message *m_ptr) );           /* copying */
+_PROTOTYPE( int do_copy, (message *m_ptr) );   
 #define do_vircopy     do_copy
 #define do_physcopy    do_copy
+#if ! (USE_VIRCOPY || USE_PHYSCOPY)
+#define do_copy do_unused
+#endif
+
 _PROTOTYPE( int do_vcopy, (message *m_ptr) );          
 #define do_virvcopy    do_vcopy
 #define do_physvcopy   do_vcopy
+#if ! (USE_VIRVCOPY || USE_PHYSVCOPY)
+#define do_vcopy do_unused
+#endif
+
 _PROTOTYPE( int do_umap, (message *m_ptr) );
-_PROTOTYPE( int do_physzero, (message *m_ptr) );
+#if ! USE_UMAP
+#define do_umap do_unused
+#endif
+
+_PROTOTYPE( int do_memset, (message *m_ptr) );
+#if ! USE_MEMSET
+#define do_memset do_unused
+#endif
 
-_PROTOTYPE( int do_unused, (message *m_ptr) );         /* miscellaneous */
 _PROTOTYPE( int do_abort, (message *m_ptr) );
+#if ! USE_ABORT
+#define do_abort do_unused
+#endif
+
 _PROTOTYPE( int do_getinfo, (message *m_ptr) );
+#if ! USE_GETINFO
+#define do_getinfo do_unused
+#endif
+
+_PROTOTYPE( int do_svrctl, (message *m_ptr) ); 
+#if ! USE_SVRCTL
+#define do_svrctl do_unused
+#endif
 
-_PROTOTYPE( int do_svrctl, (message *m_ptr) );         /* system control */
-_PROTOTYPE( int do_iopenable, (message *m_ptr) );
 _PROTOTYPE( int do_segctl, (message *m_ptr) );
+#if ! USE_SEGCTL
+#define do_segctl do_unused
+#endif
+
+_PROTOTYPE( int do_irqctl, (message *m_ptr) );
+#if ! USE_IRQCTL
+#define do_irqctl do_unused
+#endif
 
-_PROTOTYPE( int do_irqctl, (message *m_ptr) );         /* device I/O */
 _PROTOTYPE( int do_devio, (message *m_ptr) );
+#if ! USE_DEVIO
+#define do_devio do_unused
+#endif
+
 _PROTOTYPE( int do_vdevio, (message *m_ptr) );
+#if ! USE_VDEVIO
+#define do_vdevio do_unused
+#endif
+
 _PROTOTYPE( int do_sdevio, (message *m_ptr) );
+#if ! USE_SDEVIO
+#define do_sdevio do_unused
+#endif
+
+_PROTOTYPE( int do_kill, (message *m_ptr) );
+#if ! USE_KILL
+#define do_kill do_unused
+#endif
+
+_PROTOTYPE( int do_getksig, (message *m_ptr) );
+#if ! USE_GETKSIG
+#define do_getksig do_unused
+#endif
+
+_PROTOTYPE( int do_endksig, (message *m_ptr) );
+#if ! USE_ENDKSIG
+#define do_endksig do_unused
+#endif
 
-_PROTOTYPE( int do_kill, (message *m_ptr) );           /* signal handling */
-_PROTOTYPE( int do_getsig, (message *m_ptr) );
-_PROTOTYPE( int do_endsig, (message *m_ptr) );
 _PROTOTYPE( int do_sigsend, (message *m_ptr) );
-_PROTOTYPE( int do_sigreturn, (message *m_ptr) );
-_PROTOTYPE( int do_setpriority, (message *m_ptr) );
+#if ! USE_SIGSEND
+#define do_sigsend do_unused
+#endif
 
-_PROTOTYPE( int do_times, (message *m_ptr) );          /* clock functions */
-_PROTOTYPE( int do_setalarm, (message *m_ptr) );       
-#define         do_flagalrm    do_setalarm
-#define         do_signalrm    do_setalarm
-#define         do_syncalrm    do_setalarm
+_PROTOTYPE( int do_sigreturn, (message *m_ptr) );
+#if ! USE_SIGRETURN
+#define do_sigreturn do_unused
+#endif
 
-_PROTOTYPE( int do_trace, (message *m_ptr) );          /* process tracing */
+_PROTOTYPE( int do_times, (message *m_ptr) );          
+#if ! USE_TIMES
+#define do_times do_unused
+#endif
 
+_PROTOTYPE( int do_setalarm, (message *m_ptr) );       
+#if ! USE_SETALARM
+#define do_setalarm do_unused
+#endif
 
 #endif /* SYSTEM_H */
+
index 498fe26aa6468a1beee5e4ec150e7c21731a0263..d81ad887af0ebaa9a3da73cb0cd351bee8ff624c 100644 (file)
@@ -5,20 +5,50 @@ u = /usr
 i = $u/include
 
 # Programs, flags, etc.
-CC =   exec cc
+CC =   exec cc $(CFLAGS) -c
 CPP =  $l/cpp
 LD =   $(CC) -.o
 CFLAGS = -I$i
 LDFLAGS = -i
 
-SYS =  clock.o copying.o debugging.o devio.o irqctl.o proctl.o \
-       sysctl.o misc.o sigctl.o tracing.o  priority.o
+SYSTEM = ../system.a
 
 # What to make.
-all build: $(SYS)
+all build install: $(SYSTEM)
+
+OBJECTS        = \
+       $(SYSTEM)(do_unused.o) \
+       $(SYSTEM)(do_fork.o) \
+       $(SYSTEM)(do_exec.o) \
+       $(SYSTEM)(do_newmap.o) \
+       $(SYSTEM)(do_exit.o) \
+       $(SYSTEM)(do_trace.o) \
+       $(SYSTEM)(do_schedctl.o) \
+       $(SYSTEM)(do_times.o) \
+       $(SYSTEM)(do_alarm.o) \
+       $(SYSTEM)(do_irqctl.o) \
+       $(SYSTEM)(do_devio.o) \
+       $(SYSTEM)(do_vdevio.o) \
+       $(SYSTEM)(do_sdevio.o) \
+       $(SYSTEM)(do_copy.o) \
+       $(SYSTEM)(do_vcopy.o) \
+       $(SYSTEM)(do_umap.o) \
+       $(SYSTEM)(do_memset.o) \
+       $(SYSTEM)(do_svrctl.o) \
+       $(SYSTEM)(do_segctl.o) \
+       $(SYSTEM)(do_getksig.o) \
+       $(SYSTEM)(do_endksig.o) \
+       $(SYSTEM)(do_kill.o) \
+       $(SYSTEM)(do_sigsend.o) \
+       $(SYSTEM)(do_sigreturn.o) \
+       $(SYSTEM)(do_abort.o) \
+       $(SYSTEM)(do_getinfo.o) \
+
+$(SYSTEM):     $(OBJECTS)
+       aal cr $@ *.o
 
 clean:
-       rm -f *.a *.o *.bak 
+       rm -f $(SYSTEM) *.o *.bak 
 
 depend: 
        /usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c > .depend
@@ -27,4 +57,81 @@ depend:
 include .depend
 
 
+$(SYSTEM)(do_unused.o):        do_unused.c
+       $(CC) do_unused.c
+
+$(SYSTEM)(do_fork.o):  do_fork.c
+       $(CC) do_fork.c
+
+$(SYSTEM)(do_exec.o):  do_exec.c
+       $(CC) do_exec.c
+
+$(SYSTEM)(do_newmap.o):        do_newmap.c
+       $(CC) do_newmap.c
+
+$(SYSTEM)(do_exit.o):  do_exit.c
+       $(CC) do_exit.c
+
+$(SYSTEM)(do_trace.o): do_trace.c
+       $(CC) do_trace.c
+
+$(SYSTEM)(do_schedctl.o):      do_schedctl.c
+       $(CC) do_schedctl.c
+
+$(SYSTEM)(do_times.o): do_times.c
+       $(CC) do_times.c
+
+$(SYSTEM)(do_alarm.o): do_alarm.c
+       $(CC) do_alarm.c
+
+$(SYSTEM)(do_irqctl.o):        do_irqctl.c
+       $(CC) do_irqctl.c
+
+$(SYSTEM)(do_devio.o): do_devio.c
+       $(CC) do_devio.c
+
+$(SYSTEM)(do_sdevio.o):        do_sdevio.c
+       $(CC) do_sdevio.c
+
+$(SYSTEM)(do_vdevio.o):        do_vdevio.c
+       $(CC) do_vdevio.c
+
+$(SYSTEM)(do_copy.o):  do_copy.c
+       $(CC) do_copy.c
+
+$(SYSTEM)(do_vcopy.o): do_vcopy.c
+       $(CC) do_vcopy.c
+
+$(SYSTEM)(do_umap.o):  do_umap.c
+       $(CC) do_umap.c
+
+$(SYSTEM)(do_memset.o):        do_memset.c
+       $(CC) do_memset.c
+
+$(SYSTEM)(do_getksig.o):       do_getksig.c
+       $(CC) do_getksig.c
+
+$(SYSTEM)(do_endksig.o):       do_endksig.c
+       $(CC) do_endksig.c
+
+$(SYSTEM)(do_kill.o):  do_kill.c
+       $(CC) do_kill.c
+
+$(SYSTEM)(do_sigsend.o):       do_sigsend.c
+       $(CC) do_sigsend.c
+
+$(SYSTEM)(do_sigreturn.o):     do_sigreturn.c
+       $(CC) do_sigreturn.c
+
+$(SYSTEM)(do_getinfo.o):       do_getinfo.c
+       $(CC) do_getinfo.c
+
+$(SYSTEM)(do_abort.o): do_abort.c
+       $(CC) do_abort.c
+
+$(SYSTEM)(do_svrctl.o):        do_svrctl.c
+       $(CC) do_svrctl.c
+
+$(SYSTEM)(do_segctl.o):        do_segctl.c
+       $(CC) do_segctl.c
 
diff --git a/kernel/system/clock.c b/kernel/system/clock.c
deleted file mode 100644 (file)
index 9a52232..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/* The system call implemented in this file:
- *   m_type:   SYS_TIMES
- *
- * The parameters for this system call are:
- *    m4_l1:   T_PROC_NR               (get info for this process)     
- *    m4_l1:   T_USER_TIME             (return values ...)     
- *    m4_l2:   T_SYSTEM_TIME   
- *    m4_l5:   T_BOOT_TICKS    
- */
-
-#include "../kernel.h"
-#include "../system.h"
-#include "../debug.h"
-#include <signal.h>
-
-/*===========================================================================*
- *                             do_times                                     *
- *===========================================================================*/
-PUBLIC int do_times(m_ptr)
-register message *m_ptr;       /* pointer to request message */
-{
-/* Handle sys_times().  Retrieve the accounting information. */
-
-  register struct proc *rp;
-  int proc_nr;
-
-  /* Insert the times needed by the SYS_TIMES system call in the message. */
-  proc_nr = (m_ptr->T_PROC_NR == SELF) ? m_ptr->m_source : m_ptr->T_PROC_NR;
-  if (isokprocn(proc_nr)) {
-      rp = proc_addr(m_ptr->T_PROC_NR);
-      lock(11, "do_times");                    /* halt the volatile time counters in rp */
-      m_ptr->T_USER_TIME   = rp->p_user_time;
-      m_ptr->T_SYSTEM_TIME = rp->p_sys_time;
-      unlock(11);
-  }
-  m_ptr->T_BOOT_TICKS = get_uptime();  
-  return(OK);
-}
-
-
-/* The system call implemented in this file:
- *   m_type:   SYS_SIGNALRM, SYS_SYNCALRM 
- *
- * The parameters for this system call are:
- *    m2_i1:   ALRM_PROC_NR            (set alarm for this process)    
- *    m2_l1:   ALRM_EXP_TIME           (alarm's expiration time)
- *    m2_i2:   ALRM_ABS_TIME           (expiration time is absolute?)
- *    m2_l1:   ALRM_SEC_LEFT           (return seconds left of previous)
- *
- * Changes:
- *    Aug 25, 2004   fully rewritten to clean up code  (Jorrit N. Herder)  
- */
-
-FORWARD _PROTOTYPE( void cause_syncalrm, (timer_t *tp) );
-FORWARD _PROTOTYPE( void cause_signalrm, (timer_t *tp) );
-
-/*===========================================================================*
- *                             do_setalarm                                  *
- *===========================================================================*/
-PUBLIC int do_setalarm(m_ptr)
-message *m_ptr;                        /* pointer to request message */
-{
-/* A process requests an alarm, or wants to cancel its alarm. This function
- * is shared used for both the SYS_SIGNALRM and SYS_SYNCALRM.
- */
-  int proc_nr;                 /* which process wants the alarm */
-  long exp_time;               /* expiration time for this alarm */
-  int use_abs_time;            /* use absolute or relative time */
-  timer_t *tp;                 /* the process' timer structure */
-  clock_t uptime;              /* placeholder for current uptime */
-
-  /* Extract shared parameters from the request message. */
-  proc_nr = m_ptr->ALRM_PROC_NR;       /* process to interrupt later */
-  if (SELF == proc_nr) proc_nr = m_ptr->m_source;
-  if (! isokprocn(proc_nr)) return(EINVAL);
-  exp_time = m_ptr->ALRM_EXP_TIME;     /* alarm's expiration time */
-  use_abs_time = m_ptr->ALRM_ABS_TIME; /* flag for absolute time */
-
-  /* Get the timer structure and set the parameters for this alarm. */
-  tp = &(proc_addr(proc_nr)->p_alarm_timer);   
-  tmr_arg(tp)->ta_int = proc_nr;       
-  switch (m_ptr->m_type) {
-  case SYS_SYNCALRM:   tp->tmr_func = cause_syncalrm;          break;
-  case SYS_SIGNALRM:   tp->tmr_func = cause_signalrm;          break;
-  default:             return(EINVAL);         /* invalid alarm type */
-  }
-
-  /* Return the ticks left on the previous alarm. */
-  uptime = get_uptime();  
-  if ((tp->tmr_exp_time == TMR_NEVER) || (tp->tmr_exp_time < uptime) ) {
-      m_ptr->ALRM_TIME_LEFT = 0;
-  } else {
-      m_ptr->ALRM_TIME_LEFT = (tp->tmr_exp_time - uptime);
-  }
-
-  /* Finally, (re)set the timer depending on 'exp_time'. */
-  if (exp_time == 0) {
-    reset_timer(tp);
-  } else {
-    tp->tmr_exp_time = (use_abs_time) ? exp_time : exp_time + get_uptime();
-    set_timer(tp, tp->tmr_exp_time, tp->tmr_func);
-  }
-  return(OK);
-}
-
-
-/*===========================================================================*
- *                             cause_signalrm                               *
- *===========================================================================*/
-PRIVATE void cause_signalrm(tp)
-timer_t *tp;
-{
-/* Routine called if a timer goes off for a process that requested an SIGALRM
- * signal using the alarm(2) system call. The timer argument 'ta_int' contains
- * the process number of the process to signal.
- */
-  cause_sig(tmr_arg(tp)->ta_int, SIGALRM);
-}
-
-
-/*===========================================================================*
- *                             cause_syncalrm                               *
- *===========================================================================*/
-PRIVATE void cause_syncalrm(tp)
-timer_t *tp;
-{
-/* Routine called if a timer goes off and the process requested a synchronous
- * alarm. The process number is stored in timer argument 'ta_int'. Notify that
- * process given with a SYN_ALARM message.
- */
-  message m;
-  m.NOTIFY_TYPE = SYN_ALARM;
-  m.NOTIFY_ARG = get_uptime();
-  m.NOTIFY_FLAGS = 0;
-  lock_notify(tmr_arg(tp)->ta_int, &m);
-}
-
-
diff --git a/kernel/system/copying.c b/kernel/system/copying.c
deleted file mode 100644 (file)
index 1f34ccb..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/* The system call implemented in this file:
- *   m_type:   SYS_VIRCOPY, SYS_PHYSCOPY, SYS_PHYSZERO
- *
- * The parameters for this system call are:
- *    m5_c1:   CP_SRC_SPACE
- *    m5_l1:   CP_SRC_ADDR
- *    m5_i1:   CP_SRC_PROC_NR  
- *    m5_c2:   CP_DST_SPACE
- *    m5_l2:   CP_DST_ADDR     
- *    m5_i2:   CP_DST_PROC_NR  
- *    m5_l3:   CP_NR_BYTES
- */
-
-#include "../kernel.h"
-#include "../system.h"
-#include <minix/type.h>
-
-/*===========================================================================*
- *                             do_copy                                      *
- *===========================================================================*/
-PUBLIC int do_copy(m_ptr)
-register message *m_ptr;       /* pointer to request message */
-{
-/* Handle sys_vircopy() and sys_physcopy().  Copy data using virtual or
- * physical addressing. 
- */
-  struct vir_addr vir_addr[2]; /* virtual source and destination address */
-  vir_bytes bytes;             /* number of bytes to copy */
-  int i;
-
-  /* Dismember the command message. */
-  vir_addr[_SRC_].proc_nr = m_ptr->CP_SRC_PROC_NR;
-  vir_addr[_SRC_].segment = m_ptr->CP_SRC_SPACE;
-  vir_addr[_SRC_].offset = (vir_bytes) m_ptr->CP_SRC_ADDR;
-  vir_addr[_DST_].proc_nr = m_ptr->CP_DST_PROC_NR;
-  vir_addr[_DST_].segment = m_ptr->CP_DST_SPACE;
-  vir_addr[_DST_].offset = (vir_bytes) m_ptr->CP_DST_ADDR;
-  bytes = (phys_bytes) m_ptr->CP_NR_BYTES;
-
-  /* Now do some checks for both the source and destination virtual address.
-   * This is done once for _SRC_, then once for _DST_. 
-   */
-  for (i=_SRC_; i<=_DST_; i++) {
-
-      /* Check if process number was given implictly with SELF and is valid. */
-      if (vir_addr[i].proc_nr == SELF) vir_addr[i].proc_nr = m_ptr->m_source;
-      if (! isokprocn(vir_addr[i].proc_nr) && vir_addr[i].segment != PHYS_SEG) {
-          kprintf("do_vircopy: illegal proc nr, while not phys addr\n",NO_NUM);
-          return(EINVAL); 
-      }
-
-      /* Check if physical addressing is used without SYS_PHYSCOPY. */
-      if ((vir_addr[i].segment & PHYS_SEG) &&
-          m_ptr->m_type != SYS_PHYSCOPY) return(EPERM);
-  }
-
-  /* Check for overflow. This would happen for 64K segments and 16-bit 
-   * vir_bytes. Especially copying by the PM on do_fork() is affected. 
-   */
-  if (bytes != (vir_bytes) bytes) {
-       kprintf("do_vircopy: overflow\n", NO_NUM);
-       return(E2BIG);
-  }
-
-  /* Now try to make the actual virtual copy. */
-  return( virtual_copy(&vir_addr[_SRC_], &vir_addr[_DST_], bytes) );
-}
-
-
-/* Buffer to hold copy request vector from user. */
-PRIVATE struct vir_cp_req vir_cp_req[VCOPY_VEC_SIZE];
-
-/*===========================================================================*
- *                             do_vcopy                                             *
- *===========================================================================*/
-PUBLIC int do_vcopy(m_ptr)
-register message *m_ptr;       /* pointer to request message */
-{
-/* Handle sys_virvcopy(). Handle virtual copy requests from vector. */
-  int nr_req;
-  int caller_pid;
-  vir_bytes caller_vir;
-  phys_bytes caller_phys;
-  phys_bytes kernel_phys;
-  phys_bytes bytes;
-  int i,s;
-  struct vir_cp_req *req;
-
-  /* Check if request vector size is ok. */
-  nr_req = (unsigned) m_ptr->VCP_VEC_SIZE;
-  if (nr_req > VCOPY_VEC_SIZE) return(EINVAL);
-  bytes = nr_req * sizeof(struct vir_cp_req);
-
-  /* Calculate physical addresses and copy (port,value)-pairs from user. */
-  caller_pid = (int) m_ptr->m_source; 
-  caller_vir = (vir_bytes) m_ptr->VCP_VEC_ADDR;
-  caller_phys = umap_local(proc_addr(caller_pid), D, caller_vir, bytes);
-  if (0 == caller_phys) return(EFAULT);
-  kernel_phys = vir2phys(vir_cp_req);
-  phys_copy(caller_phys, kernel_phys, (phys_bytes) bytes);
-
-  /* Assume vector with requests is correct. Try to copy everything. */
-  for (i=0; i<nr_req; i++) {
-
-      req = &vir_cp_req[i];
-
-      /* Check if physical addressing is used without SYS_PHYSVCOPY. */
-      if (((req->src.segment | req->dst.segment) & PHYS_SEG) &&
-              m_ptr->m_type != SYS_PHYSVCOPY) 
-          return(EPERM);
-      if ((s=virtual_copy(&req->src, &req->dst, req->count)) != OK) 
-          return(s);
-  }
-  return(OK);
-}
-
-/*===========================================================================*
- *                             do_physzero                                  *
- *===========================================================================*/
-PUBLIC int do_physzero(m_ptr)
-register message *m_ptr;
-{
-/* Handle sys_physzero(). */
-  phys_zero((phys_bytes) m_ptr->PZ_MEM_PTR, (phys_bytes) m_ptr->PZ_COUNT);
-  return(OK);
-}
-
-
-/* The system call implemented in this file:
- *   m_type:   SYS_UMAP
- *
- * The parameters for this system call are:
- *    m5_i1:   CP_SRC_PROC_NR  (process number)        
- *    m5_c1:   CP_SRC_SPACE    (segment where address is: T, D, or S)
- *    m5_l1:   CP_SRC_ADDR     (virtual address)       
- *    m5_l2:   CP_DST_ADDR     (returns physical address)      
- *    m5_l3:   CP_NR_BYTES     (size of datastructure)         
- */
-
-/*==========================================================================*
- *                             do_umap                                     *
- *==========================================================================*/
-PUBLIC int do_umap(m_ptr)
-register message *m_ptr;       /* pointer to request message */
-{
-/* Map virtual address to physical, for non-kernel processes. */
-  int seg_type = m_ptr->CP_SRC_SPACE & SEGMENT_TYPE;
-  int seg_index = m_ptr->CP_SRC_SPACE & SEGMENT_INDEX;
-  vir_bytes offset = m_ptr->CP_SRC_ADDR;
-  int count = m_ptr->CP_NR_BYTES;
-  int proc_nr = (int) m_ptr->CP_SRC_PROC_NR;
-  phys_bytes phys_addr;
-
-  /* Verify process number. */
-  if (proc_nr == SELF) proc_nr = m_ptr->m_source;
-  if (! isokprocn(proc_nr)) return(EINVAL);
-
-  /* See which mapping should be made. */
-  switch(seg_type) {
-  case LOCAL_SEG:
-      phys_addr = umap_local(proc_addr(proc_nr), seg_index, offset, count); 
-      break;
-  case REMOTE_SEG:
-      phys_addr = umap_remote(proc_addr(proc_nr), seg_index, offset, count); 
-      break;
-  case BIOS_SEG:
-      phys_addr = umap_bios(proc_addr(proc_nr), offset, count); 
-      break;
-  default:
-      return(EINVAL);
-  }
-  m_ptr->CP_DST_ADDR = phys_addr;
-  return (phys_addr == 0) ? EFAULT: OK;
-}
-
-
diff --git a/kernel/system/do_abort.c b/kernel/system/do_abort.c
new file mode 100644 (file)
index 0000000..3a68bc8
--- /dev/null
@@ -0,0 +1,46 @@
+#include "../system.h"
+#include <unistd.h>
+
+
+/* The system call implemented in this file:
+ *   m_type:   SYS_ABORT
+ *
+ * The parameters for this system call are:
+ *    m1_i1:   ABRT_HOW        (how to abort, possibly fetch monitor params)   
+ *    m1_i2:   ABRT_MON_PROC   (proc nr to get monitor params from)    
+ *    m1_i3:   ABRT_MON_LEN    (length of monitor params)
+ *    m1_p1:   ABRT_MON_ADDR   (virtual address of params)     
+ */
+#if USE_ABORT
+
+/*===========================================================================*
+ *                             do_abort                                     *
+ *===========================================================================*/
+PUBLIC int do_abort(m_ptr)
+message *m_ptr;                        /* pointer to request message */
+{
+/* Handle sys_abort. MINIX is unable to continue. This can originate in the
+ * PM (normal abort or panic) or FS (panic), or TTY (user issued CTRL-ALT-DEL 
+ * or ESC after debugging dumps).
+ */
+  int how = m_ptr->ABRT_HOW;
+  
+  if (how == RBT_MONITOR) {
+      /* The monitor is to run the specified instructions. */
+      int proc_nr = m_ptr->ABRT_MON_PROC;
+      int length = m_ptr->ABRT_MON_LEN + 1;
+      vir_bytes src_vir = (vir_bytes) m_ptr->ABRT_MON_ADDR;
+      phys_bytes src_phys = numap_local(proc_nr, src_vir, length);
+
+      /* Validate length and address of shutdown code before copying. */
+      if (length > kinfo.params_size || src_phys == 0) 
+         phys_copy(vir2phys("delay;boot"), kinfo.params_base, 11);
+      else
+          phys_copy(src_phys, kinfo.params_base, (phys_bytes) length);
+  }
+  prepare_shutdown(how);
+  return(OK);                          /* pro-forma (really EDISASTER) */
+}
+
+#endif /* USE_ABORT */
+
diff --git a/kernel/system/do_alarm.c b/kernel/system/do_alarm.c
new file mode 100644 (file)
index 0000000..a1d6c4e
--- /dev/null
@@ -0,0 +1,77 @@
+/* The system call implemented in this file:
+ *   m_type:   SYS_SETALARM 
+ *
+ * The parameters for this system call are:
+ *    m2_i1:   ALRM_PROC_NR            (set alarm for this process)    
+ *    m2_l1:   ALRM_EXP_TIME           (alarm's expiration time)
+ *    m2_i2:   ALRM_ABS_TIME           (expiration time is absolute?)
+ *    m2_l1:   ALRM_SEC_LEFT           (return seconds left of previous)
+ *
+ * Changes:
+ *    Aug 25, 2004   fully rewritten to clean up code  (Jorrit N. Herder)  
+ */
+
+#include "../system.h"
+
+#if USE_SETALARM
+
+FORWARD _PROTOTYPE( void cause_alarm, (timer_t *tp) );
+
+/*===========================================================================*
+ *                             do_setalarm                                  *
+ *===========================================================================*/
+PUBLIC int do_setalarm(m_ptr)
+message *m_ptr;                        /* pointer to request message */
+{
+/* A process requests a synchronous alarm, or wants to cancel its alarm. */
+  int proc_nr;                 /* which process wants the alarm */
+  long exp_time;               /* expiration time for this alarm */
+  int use_abs_time;            /* use absolute or relative time */
+  timer_t *tp;                 /* the process' timer structure */
+  clock_t uptime;              /* placeholder for current uptime */
+
+  /* Extract shared parameters from the request message. */
+  proc_nr = m_ptr->ALRM_PROC_NR;       /* process to interrupt later */
+  if (SELF == proc_nr) proc_nr = m_ptr->m_source;
+  if (! isokprocn(proc_nr)) return(EINVAL);
+  exp_time = m_ptr->ALRM_EXP_TIME;     /* alarm's expiration time */
+  use_abs_time = m_ptr->ALRM_ABS_TIME; /* flag for absolute time */
+
+  /* Get the timer structure and set the parameters for this alarm. */
+  tp = &(proc_addr(proc_nr)->p_priv->s_alarm_timer);   
+  tmr_arg(tp)->ta_int = proc_nr;       
+  tp->tmr_func = cause_alarm;  
+
+  /* Return the ticks left on the previous alarm. */
+  uptime = get_uptime();  
+  if ((tp->tmr_exp_time == TMR_NEVER) || (tp->tmr_exp_time < uptime) ) {
+      m_ptr->ALRM_TIME_LEFT = 0;
+  } else {
+      m_ptr->ALRM_TIME_LEFT = (tp->tmr_exp_time - uptime);
+  }
+
+  /* Finally, (re)set the timer depending on 'exp_time'. */
+  if (exp_time == 0) {
+      reset_timer(tp);
+  } else {
+      tp->tmr_exp_time = (use_abs_time) ? exp_time : exp_time + get_uptime();
+      set_timer(tp, tp->tmr_exp_time, tp->tmr_func);
+  }
+  return(OK);
+}
+
+
+/*===========================================================================*
+ *                             cause_alarm                                  *
+ *===========================================================================*/
+PRIVATE void cause_alarm(tp)
+timer_t *tp;
+{
+/* Routine called if a timer goes off and the process requested a synchronous
+ * alarm. The process number is stored in timer argument 'ta_int'. Notify that
+ * process given with a SYN_ALARM message.
+ */
+  lock_alert(CLOCK, tmr_arg(tp)->ta_int);
+}
+
+#endif /* USE_SETALARM */
diff --git a/kernel/system/do_copy.c b/kernel/system/do_copy.c
new file mode 100644 (file)
index 0000000..d697501
--- /dev/null
@@ -0,0 +1,71 @@
+/* The system call implemented in this file:
+ *   m_type:   SYS_VIRCOPY, SYS_PHYSCOPY
+ *
+ * The parameters for this system call are:
+ *    m5_c1:   CP_SRC_SPACE
+ *    m5_l1:   CP_SRC_ADDR
+ *    m5_i1:   CP_SRC_PROC_NR  
+ *    m5_c2:   CP_DST_SPACE
+ *    m5_l2:   CP_DST_ADDR     
+ *    m5_i2:   CP_DST_PROC_NR  
+ *    m5_l3:   CP_NR_BYTES
+ */
+
+#include "../system.h"
+#include <minix/type.h>
+
+#if (USE_VIRCOPY || USE_PHYSCOPY)
+
+/*===========================================================================*
+ *                             do_copy                                      *
+ *===========================================================================*/
+PUBLIC int do_copy(m_ptr)
+register message *m_ptr;       /* pointer to request message */
+{
+/* Handle sys_vircopy() and sys_physcopy().  Copy data using virtual or
+ * physical addressing. 
+ */
+  struct vir_addr vir_addr[2]; /* virtual source and destination address */
+  vir_bytes bytes;             /* number of bytes to copy */
+  int i;
+
+  /* Dismember the command message. */
+  vir_addr[_SRC_].proc_nr = m_ptr->CP_SRC_PROC_NR;
+  vir_addr[_SRC_].segment = m_ptr->CP_SRC_SPACE;
+  vir_addr[_SRC_].offset = (vir_bytes) m_ptr->CP_SRC_ADDR;
+  vir_addr[_DST_].proc_nr = m_ptr->CP_DST_PROC_NR;
+  vir_addr[_DST_].segment = m_ptr->CP_DST_SPACE;
+  vir_addr[_DST_].offset = (vir_bytes) m_ptr->CP_DST_ADDR;
+  bytes = (phys_bytes) m_ptr->CP_NR_BYTES;
+
+  /* Now do some checks for both the source and destination virtual address.
+   * This is done once for _SRC_, then once for _DST_. 
+   */
+  for (i=_SRC_; i<=_DST_; i++) {
+
+      /* Check if process number was given implictly with SELF and is valid. */
+      if (vir_addr[i].proc_nr == SELF) vir_addr[i].proc_nr = m_ptr->m_source;
+      if (! isokprocn(vir_addr[i].proc_nr) && vir_addr[i].segment != PHYS_SEG) {
+          kprintf("do_vircopy: illegal proc nr, while not phys addr\n",NO_NUM);
+          return(EINVAL); 
+      }
+
+      /* Check if physical addressing is used without SYS_PHYSCOPY. */
+      if ((vir_addr[i].segment & PHYS_SEG) &&
+          m_ptr->m_type != SYS_PHYSCOPY) return(EPERM);
+  }
+
+  /* Check for overflow. This would happen for 64K segments and 16-bit 
+   * vir_bytes. Especially copying by the PM on do_fork() is affected. 
+   */
+  if (bytes != (vir_bytes) bytes) {
+       kprintf("do_vircopy: overflow\n", NO_NUM);
+       return(E2BIG);
+  }
+
+  /* Now try to make the actual virtual copy. */
+  return( virtual_copy(&vir_addr[_SRC_], &vir_addr[_DST_], bytes) );
+}
+#endif /* (USE_VIRCOPY || USE_PHYSCOPY) */
+
+
diff --git a/kernel/system/do_devio.c b/kernel/system/do_devio.c
new file mode 100644 (file)
index 0000000..26bf87a
--- /dev/null
@@ -0,0 +1,44 @@
+/* The system call implemented in this file:
+ *   m_type:   SYS_DEVIO
+ *
+ * The parameters for this system call are:
+ *    m2_i3:   DIO_REQUEST     (request input or output)       
+ *    m2_i1:   DIO_TYPE        (flag indicating byte, word, or long)
+ *    m2_l1:   DIO_PORT        (port to read/ write)   
+ *    m2_l2:   DIO_VALUE       (value to write/ return value read)     
+ *
+ * Author:
+ *    Jorrit N. Herder <jnherder@cs.vu.nl>
+ */
+
+#include "../system.h"
+#include <minix/devio.h>
+
+#if USE_DEVIO
+
+/*===========================================================================*
+ *                             do_devio                                     *
+ *===========================================================================*/
+PUBLIC int do_devio(m_ptr)
+register message *m_ptr;       /* pointer to request message */
+{
+    /* Perform actual device I/O for byte, word, and long values. */
+    if (m_ptr->DIO_REQUEST == DIO_INPUT) { 
+      switch (m_ptr->DIO_TYPE) {
+        case DIO_BYTE: m_ptr->DIO_VALUE = inb(m_ptr->DIO_PORT); break; 
+        case DIO_WORD: m_ptr->DIO_VALUE = inw(m_ptr->DIO_PORT); break; 
+        case DIO_LONG: m_ptr->DIO_VALUE = inl(m_ptr->DIO_PORT); break; 
+       default: return(EINVAL);
+      } 
+    } else { 
+      switch (m_ptr->DIO_TYPE) {
+        case DIO_BYTE: outb(m_ptr->DIO_PORT, m_ptr->DIO_VALUE); break;  
+        case DIO_WORD: outw(m_ptr->DIO_PORT, m_ptr->DIO_VALUE); break;  
+        case DIO_LONG: outl(m_ptr->DIO_PORT, m_ptr->DIO_VALUE); break;  
+       default: return(EINVAL);
+      } 
+    }
+    return(OK);
+}
+
+#endif /* USE_DEVIO */
diff --git a/kernel/system/do_endksig.c b/kernel/system/do_endksig.c
new file mode 100644 (file)
index 0000000..e2babbf
--- /dev/null
@@ -0,0 +1,49 @@
+/* The system call that is implemented in this file:
+ *     SYS_SIGCTL      # signal handling functionality 
+ *
+ * The parameters and types for this system call are:
+ *     SIG_REQUEST     # request to perform                    (long)
+ *     SIG_PROC        # process to signal/ pending            (int)
+ *     SIG_CTXT_PTR    # pointer to sigcontext structure       (pointer)       
+ *     SIG_FLAGS       # flags for S_SIGRETURN call            (int)   
+ *     SIG_MAP         # bit map with pending signals          (long)  
+ *     SIG_NUMBER      # signal number to send to process      (int)   
+ *
+ * Supported request types are in the parameter SIG_REQUEST:
+ *     S_GETSIG                # get a pending kernel signal
+ *     S_ENDSIG                # signal has been processed 
+ *     S_SENDSIG       # deliver a POSIX-style signal 
+ *     S_SIGRETURN     # return from a POSIX-style signal 
+ *     S_KILL          # send a signal to a process 
+ */
+
+#include "../system.h"
+#include <signal.h>
+#include <sys/sigcontext.h>
+
+#if USE_ENDKSIG 
+
+/*===========================================================================*
+ *                           do_endksig                                     *
+ *===========================================================================*/
+PUBLIC int do_endksig(m_ptr)
+message *m_ptr;                        /* pointer to request message */
+{
+/* Finish up after a kernel type signal, caused by a SYS_KILL message or a 
+ * call to cause_sig by a task. This is called by the PM after processing a
+ * signal it got with SYS_GETKSIG.
+ */
+  register struct proc *rp;
+
+  rp = proc_addr(m_ptr->SIG_PROC);
+  if (isemptyp(rp)) return(EINVAL);            /* process already dead? */
+
+  /* PM has finished one kernel signal. Perhaps process is ready now? */
+  if (! (rp->p_rts_flags & SIGNALED))          /* new signal arrived */
+     if ((rp->p_rts_flags &= ~SIG_PENDING)==0) /* remove pending flag */
+         lock_ready(rp);                       /* ready if no flags */
+  return(OK);
+}
+
+#endif /* USE_ENDKSIG */
+
diff --git a/kernel/system/do_exec.c b/kernel/system/do_exec.c
new file mode 100644 (file)
index 0000000..d5e0635
--- /dev/null
@@ -0,0 +1,63 @@
+/* The system call implemented in this file:
+ *   m_type:   SYS_EXEC
+ *
+ * The parameters for this system call are:
+ *    m1_i1:   PR_PROC_NR              (process that did exec call)
+ *    m1_i3:   PR_TRACING              (flag to indicate tracing is on/ off)
+ *    m1_p1:   PR_STACK_PTR            (new stack pointer)
+ *    m1_p2:   PR_NAME_PTR             (pointer to program name)
+ *    m1_p3:   PR_IP_PTR               (new instruction pointer)
+ */
+#include "../system.h"
+#include <signal.h>
+
+#if USE_EXEC
+
+/*===========================================================================*
+ *                             do_exec                                      *
+ *===========================================================================*/
+PUBLIC int do_exec(m_ptr)
+register message *m_ptr;       /* pointer to request message */
+{
+/* Handle sys_exec().  A process has done a successful EXEC. Patch it up. */
+
+  register struct proc *rp;
+  reg_t sp;                    /* new sp */
+  phys_bytes phys_name;
+  char *np;
+
+  rp = proc_addr(m_ptr->PR_PROC_NR);
+  if (m_ptr->PR_TRACING) cause_sig(m_ptr->PR_PROC_NR, SIGTRAP);
+  sp = (reg_t) m_ptr->PR_STACK_PTR;
+  rp->p_reg.sp = sp;           /* set the stack pointer */
+#if (CHIP == M68000)
+  rp->p_splow = sp;            /* set the stack pointer low water */
+#ifdef FPP
+  /* Initialize fpp for this process */
+  fpp_new_state(rp);
+#endif
+#endif
+#if (CHIP == INTEL)            /* wipe extra LDT entries */
+  kmemset(&rp->p_ldt[EXTRA_LDT_INDEX], 0,
+       (LDT_SIZE - EXTRA_LDT_INDEX) * sizeof(rp->p_ldt[0]));
+#endif
+  rp->p_reg.pc = (reg_t) m_ptr->PR_IP_PTR;     /* set pc */
+  rp->p_rts_flags &= ~RECEIVING;       /* PM does not reply to EXEC call */
+  if (rp->p_rts_flags == 0) lock_ready(rp);
+
+  /* Save command name for debugging, ps(1) output, etc. */
+  phys_name = numap_local(m_ptr->m_source, (vir_bytes) m_ptr->PR_NAME_PTR,
+                                       (vir_bytes) P_NAME_LEN - 1);
+  if (phys_name != 0) {
+       phys_copy(phys_name, vir2phys(rp->p_name), (phys_bytes) P_NAME_LEN - 1);
+       for (np = rp->p_name; (*np & BYTE) >= ' '; np++) {}
+       *np = 0;                                        /* mark end */
+  } else {
+       kstrncpy(rp->p_name, "<unset>", P_NAME_LEN);
+  }
+  return(OK);
+}
+#endif /* USE_EXEC */
+
+
+
diff --git a/kernel/system/do_exit.c b/kernel/system/do_exit.c
new file mode 100644 (file)
index 0000000..c690b09
--- /dev/null
@@ -0,0 +1,42 @@
+/* The system call implemented in this file:
+ *   m_type:   SYS_EXIT
+ *
+ * The parameters for this system call are:
+ *    m1_i1:   PR_PROC_NR              (slot number of exiting process)
+ */
+
+#include "../system.h"
+
+#if USE_EXIT
+
+/*===========================================================================*
+ *                             do_exit                                      *
+ *===========================================================================*/
+PUBLIC int do_exit(m_ptr)
+message *m_ptr;                        /* pointer to request message */
+{
+/* Handle sys_exit. A user process has exited or a system process requests 
+ * to exit. Only the PM can request other process slots to be cleared.
+ * The routine to clean up a process table slot cancels outstanding timers, 
+ * possibly removes the process from the message queues, and resets certain 
+ * process table fields to the default values.
+ */
+  int exit_proc_nr;                            
+
+  /* Determine what process exited. User processes are handled here. */
+  if (PM_PROC_NR == m_ptr->m_source) {
+      exit_proc_nr = m_ptr->PR_PROC_NR;                /* get exiting process */
+      if (exit_proc_nr != SELF) {              /* PM tries to exit self */
+          if (! isokprocn(exit_proc_nr)) return(EINVAL);
+          clear_proc(exit_proc_nr);            /* exit a user process */
+          return(OK);                          /* report back to PM */
+      }
+  } 
+
+  /* The PM or some other system process requested to be exited. */
+  clear_proc(m_ptr->m_source);
+  return(EDONTREPLY);
+}
+#endif /* USE_EXIT */
+
+
diff --git a/kernel/system/do_fork.c b/kernel/system/do_fork.c
new file mode 100644 (file)
index 0000000..8afdcd4
--- /dev/null
@@ -0,0 +1,62 @@
+/* The system call implemented in this file:
+ *   m_type:   SYS_FORK
+ *
+ * The parameters for this system call are:
+ *    m1_i1:   PR_PROC_NR      (child's process table slot)    
+ *    m1_i2:   PR_PPROC_NR     (parent, process that forked)   
+ *    m1_i3:   PR_PID          (child pid received from PM)
+ */
+
+#include "../system.h"
+#include <signal.h>
+#if (CHIP == INTEL)
+#include "../protect.h"
+#endif
+
+#if USE_FORK
+
+/*===========================================================================*
+ *                             do_fork                                      *
+ *===========================================================================*/
+PUBLIC int do_fork(m_ptr)
+register message *m_ptr;       /* pointer to request message */
+{
+/* Handle sys_fork().  PR_PPROC_NR has forked.  The child is PR_PROC_NR. */
+
+#if (CHIP == INTEL)
+  reg_t old_ldt_sel;
+#endif
+  register struct proc *rpc;
+  struct proc *rpp;
+
+  rpp = proc_addr(m_ptr->PR_PPROC_NR);
+  rpc = proc_addr(m_ptr->PR_PROC_NR);
+  if (! isemptyp(rpc)) return(EINVAL);
+
+  /* Copy parent 'proc' struct to child. */
+#if (CHIP == INTEL)
+  old_ldt_sel = rpc->p_ldt_sel;        /* stop this being obliterated by copy */
+#endif
+
+  *rpc = *rpp;                                 /* copy 'proc' struct */
+
+#if (CHIP == INTEL)
+  rpc->p_ldt_sel = old_ldt_sel;
+#endif
+  rpc->p_nr = m_ptr->PR_PROC_NR;       /* this was obliterated by copy */
+  rpc->p_ntf_q = NULL;                 /* remove pending notifications */
+
+  /* Only one in group should have SIGNALED, child doesn't inherit tracing. */
+  rpc->p_rts_flags |= NO_MAP;          /* inhibit process from running */
+  rpc->p_rts_flags &= ~(SIGNALED | SIG_PENDING | P_STOP);
+  sigemptyset(&rpc->p_pending);
+
+  rpc->p_reg.retreg = 0;       /* child sees pid = 0 to know it is child */
+  rpc->p_user_time = 0;                /* set all the accounting times to 0 */
+  rpc->p_sys_time = 0;
+
+  return(OK);
+}
+
+#endif /* USE_FORK */
+
similarity index 63%
rename from kernel/system/misc.c
rename to kernel/system/do_getinfo.c
index 8eea9c6b2900835c79ad35eff6d56f3f6c9a51a7..6dfc9191fc151dc1f2e8619d6a1e8990037dba0e 100644 (file)
@@ -1,61 +1,3 @@
-#include "../kernel.h"
-#include "../system.h"
-#include <unistd.h>
-#include <minix/config.h>
-
-
-/*===========================================================================*
- *                               do_unused                                  *
- *===========================================================================*/
-PUBLIC int do_unused(m)
-message *m;                            /* pointer to request message */
-{
-  kprintf("SYS task got illegal request from %d.", m->m_source);
-  return(EBADREQUEST);         /* illegal message type */
-}
-
-
-
-/* The system call implemented in this file:
- *   m_type:   SYS_ABORT
- *
- * The parameters for this system call are:
- *    m1_i1:   ABRT_HOW        (how to abort, possibly fetch monitor params)   
- *    m1_i2:   ABRT_MON_PROC   (proc nr to get monitor params from)    
- *    m1_i3:   ABRT_MON_LEN    (length of monitor params)
- *    m1_p1:   ABRT_MON_ADDR   (virtual address of params)     
- */
-
-/*===========================================================================*
- *                             do_abort                                     *
- *===========================================================================*/
-PUBLIC int do_abort(m_ptr)
-message *m_ptr;                        /* pointer to request message */
-{
-/* Handle sys_abort. MINIX is unable to continue. This can originate in the
- * PM (normal abort or panic) or FS (panic), or TTY (a CTRL-ALT-DEL or ESC
- * after debugging dumps).
- */
-  int how = m_ptr->ABRT_HOW;
-  
-  if (how == RBT_MONITOR) {
-      /* The monitor is to run the specified instructions. */
-      int proc_nr = m_ptr->ABRT_MON_PROC;
-      int length = m_ptr->ABRT_MON_LEN + 1;
-      vir_bytes src_vir = (vir_bytes) m_ptr->ABRT_MON_ADDR;
-      phys_bytes src_phys = numap_local(proc_nr, src_vir, length);
-
-      /* Validate length and address of shutdown code before copying. */
-      if (length > kinfo.params_size || src_phys == 0) 
-         phys_copy(vir2phys("delay;boot"), kinfo.params_base, 11);
-      else
-          phys_copy(src_phys, kinfo.params_base, (phys_bytes) length);
-  }
-  prepare_shutdown(how);
-  return(OK);                          /* pro-forma (really EDISASTER) */
-}
-
-
 /* The system call implemented in this file:
  *   m_type:   SYS_GETINFO
  *
@@ -71,6 +13,10 @@ message *m_ptr;                      /* pointer to request message */
  *    Jorrit N. Herder <jnherder@cs.vu.nl>
  */
 
+#include "../system.h"
+
+#if USE_GETINFO
+
 /*===========================================================================*
  *                             do_getinfo                                   *
  *===========================================================================*/
@@ -96,7 +42,7 @@ register message *m_ptr;      /* pointer to request message */
        break;
     }
     case GET_IMAGE: {
-       length = sizeof(struct system_image) * IMAGE_SIZE;
+       length = sizeof(struct system_image) * NR_BOOT_PROCS;
        src_phys = vir2phys(image);
         break;
     }
@@ -123,6 +69,11 @@ register message *m_ptr;    /* pointer to request message */
        src_phys = vir2phys(proc);
         break;
     }
+    case GET_PRIVTAB: {
+       length = sizeof(struct priv) * (NR_SYS_PROCS);
+       src_phys = vir2phys(priv);
+        break;
+    }
     case GET_PROC: {
        nr = (m_ptr->I_KEY_LEN == SELF) ? m_ptr->m_source : m_ptr->I_KEY_LEN;
        if (! isokprocn(nr)) return(EINVAL);    /* validate request */
@@ -147,7 +98,7 @@ register message *m_ptr;     /* pointer to request message */
         src_phys = vir2phys(&kmess);
         break;
     }
-#if ENABLE_LOCK_TIMING
+#if DEBUG_TIME_LOCKS
     case GET_LOCKTIMING: {
        length = sizeof(timingdata);
        src_phys = vir2phys(timingdata);
@@ -167,4 +118,5 @@ register message *m_ptr;    /* pointer to request message */
   return(OK);
 }
 
+#endif /* USE_GETINFO */
 
diff --git a/kernel/system/do_getksig.c b/kernel/system/do_getksig.c
new file mode 100644 (file)
index 0000000..51e5bfc
--- /dev/null
@@ -0,0 +1,55 @@
+/* The system call that is implemented in this file:
+ *     SYS_SIGCTL      # signal handling functionality 
+ *
+ * The parameters and types for this system call are:
+ *     SIG_REQUEST     # request to perform                    (long)
+ *     SIG_PROC        # process to signal/ pending            (int)
+ *     SIG_CTXT_PTR    # pointer to sigcontext structure       (pointer)       
+ *     SIG_FLAGS       # flags for S_SIGRETURN call            (int)   
+ *     SIG_MAP         # bit map with pending signals          (long)  
+ *     SIG_NUMBER      # signal number to send to process      (int)   
+ *
+ * Supported request types are in the parameter SIG_REQUEST:
+ *     S_GETSIG                # get a pending kernel signal
+ *     S_ENDSIG                # signal has been processed 
+ *     S_SENDSIG       # deliver a POSIX-style signal 
+ *     S_SIGRETURN     # return from a POSIX-style signal 
+ *     S_KILL          # send a signal to a process 
+ */
+
+#include "../system.h"
+#include <signal.h>
+#include <sys/sigcontext.h>
+
+#if USE_GETKSIG
+
+/*===========================================================================*
+ *                           do_getksig                                     *
+ *===========================================================================*/
+PUBLIC int do_getksig(m_ptr)
+message *m_ptr;                        /* pointer to request message */
+{
+/* PM is ready to accept signals and repeatedly does a system call to get 
+ * one. Find a process with pending signals. If no signals are available, 
+ * return NONE in the process number field.
+ */
+  register struct proc *rp;
+
+  /* Find the next process with pending signals. */
+  for (rp = BEG_USER_ADDR; rp < END_PROC_ADDR; rp++) {
+      if (rp->p_rts_flags & SIGNALED) {
+          m_ptr->SIG_PROC = rp->p_nr;
+          m_ptr->SIG_MAP = rp->p_pending;
+          sigemptyset(&rp->p_pending);         /* ball is in PM's court */
+          rp->p_rts_flags &= ~SIGNALED;        /* blocked by SIG_PENDING */
+          return(OK);
+      }
+  }
+
+  /* No process with pending signals was found. */
+  m_ptr->SIG_PROC = NONE; 
+  return(OK);
+}
+#endif /* USE_GETKSIG */
+
+
similarity index 98%
rename from kernel/system/irqctl.c
rename to kernel/system/do_irqctl.c
index 8cb0a1a7181a278d4776dc484e05b0a654ebace0..618c07f8373313db383d2e68da6aa233cda97133 100644 (file)
  *    Jorrit N. Herder <jnherder@cs.vu.nl>
  */
 
-#include "../kernel.h"
 #include "../system.h"
 
+#if USE_IRQCTL
+
 /*===========================================================================*
  *                             do_irqctl                                    *
  *===========================================================================*/
@@ -95,3 +96,5 @@ register message *m_ptr;      /* pointer to request message */
   return(r);
 }
 
+#endif /* USE_IRQCTL */
+
diff --git a/kernel/system/do_kill.c b/kernel/system/do_kill.c
new file mode 100644 (file)
index 0000000..0b33cc9
--- /dev/null
@@ -0,0 +1,41 @@
+/* The system call that is implemented in this file:
+ *     SYS_SIGCTL      # signal handling functionality 
+ *
+ * The parameters and types for this system call are:
+ *     SIG_REQUEST     # request to perform                    (long)
+ *     SIG_PROC        # process to signal/ pending            (int)
+ *     SIG_CTXT_PTR    # pointer to sigcontext structure       (pointer)       
+ *     SIG_FLAGS       # flags for S_SIGRETURN call            (int)   
+ *     SIG_MAP         # bit map with pending signals          (long)  
+ *     SIG_NUMBER      # signal number to send to process      (int)   
+ *
+ * Supported request types are in the parameter SIG_REQUEST:
+ *     S_GETSIG                # get a pending kernel signal
+ *     S_ENDSIG                # signal has been processed 
+ *     S_SENDSIG       # deliver a POSIX-style signal 
+ *     S_SIGRETURN     # return from a POSIX-style signal 
+ *     S_KILL          # send a signal to a process 
+ */
+
+#include "../system.h"
+#include <signal.h>
+#include <sys/sigcontext.h>
+
+#if USE_KILL
+
+/*===========================================================================*
+ *                               do_kill                                    *
+ *===========================================================================*/
+PUBLIC int do_kill(m_ptr)
+message *m_ptr;                        /* pointer to request message */
+{
+/* Handle sys_kill(). Cause a signal to be sent to a process via PM.
+ * Note that this has nothing to do with the kill (2) system call, this
+ * is how the FS (and possibly other servers) get access to cause_sig. 
+ */
+  cause_sig(m_ptr->SIG_PROC, m_ptr->SIG_NUMBER);
+  return(OK);
+}
+
+#endif /* USE_KILL */
+
diff --git a/kernel/system/do_memset.c b/kernel/system/do_memset.c
new file mode 100644 (file)
index 0000000..68efcf9
--- /dev/null
@@ -0,0 +1,27 @@
+/* The system call implemented in this file:
+ *   m_type:   SYS_MEMSET
+ *
+ * The parameters for this system call are:
+ *    m5_l1:   CP_SRC_ADDR     (virtual address)       
+ *    m5_l2:   CP_DST_ADDR     (returns physical address)      
+ *    m5_l3:   CP_NR_BYTES     (size of datastructure)         
+ */
+
+#include "../system.h"
+
+#if USE_MEMSET
+
+/*===========================================================================*
+ *                             do_memset                                    *
+ *===========================================================================*/
+PUBLIC int do_memset(m_ptr)
+register message *m_ptr;
+{
+/* Handle sys_memset(). */
+  phys_zero((phys_bytes) m_ptr->MEM_PTR, (phys_bytes) m_ptr->MEM_COUNT);
+  return(OK);
+}
+
+#endif /* USE_MEMSET */
+
+
diff --git a/kernel/system/do_newmap.c b/kernel/system/do_newmap.c
new file mode 100644 (file)
index 0000000..60d712b
--- /dev/null
@@ -0,0 +1,53 @@
+/* The system call implemented in this file:
+ *   m_type:   SYS_NEWMAP
+ *
+ * The parameters for this system call are:
+ *    m1_i1:   PR_PROC_NR              (install new map for this process)
+ *    m1_p1:   PR_MEM_PTR              (pointer to memory map)
+ */
+#include "../system.h"
+
+#if USE_NEWMAP
+
+/*===========================================================================*
+ *                             do_newmap                                    *
+ *===========================================================================*/
+PUBLIC int do_newmap(m_ptr)
+message *m_ptr;                        /* pointer to request message */
+{
+/* Handle sys_newmap().  Fetch the memory map from PM. */
+
+  register struct proc *rp;
+  phys_bytes src_phys;
+  int caller;                  /* whose space has the new map (usually PM) */
+  int k;                       /* process whose map is to be loaded */
+  int old_flags;               /* value of flags before modification */
+  struct mem_map *map_ptr;     /* virtual address of map inside caller (PM) */
+
+  /* Extract message parameters and copy new memory map from PM. */
+  caller = m_ptr->m_source;
+  k = m_ptr->PR_PROC_NR;
+  map_ptr = (struct mem_map *) m_ptr->PR_MEM_PTR;
+  if (!isokprocn(k)) return(EINVAL);
+  rp = proc_addr(k);           /* ptr to entry of user getting new map */
+
+  /* Copy the map from PM. */
+  src_phys = umap_local(proc_addr(caller), D, (vir_bytes) map_ptr, 
+       sizeof(rp->p_memmap));
+  if (src_phys == 0) return(EFAULT);
+  phys_copy(src_phys,vir2phys(rp->p_memmap),(phys_bytes)sizeof(rp->p_memmap));
+
+#if (CHIP != M68000)
+  alloc_segments(rp);
+#else
+  pmmu_init_proc(rp);
+#endif
+  old_flags = rp->p_rts_flags; /* save the previous value of the flags */
+  rp->p_rts_flags &= ~NO_MAP;
+  if (old_flags != 0 && rp->p_rts_flags == 0) lock_ready(rp);
+
+  return(OK);
+}
+#endif /* USE_NEWMAP */
+
+
diff --git a/kernel/system/do_schedctl.c b/kernel/system/do_schedctl.c
new file mode 100644 (file)
index 0000000..08a0a5f
--- /dev/null
@@ -0,0 +1,50 @@
+/* The system call implemented in this file:
+ *   m_type:   SYS_SCHEDCTL
+ *
+ * The parameters for this system call are:
+ *    m1_i1:   PR_PROC_NR      process number to change priority
+ *    m1_i2:   PR_PRIORITY     the new priority
+ */
+
+#include "../system.h"
+#include <minix/type.h>
+#include <sys/resource.h>
+
+#if USE_SCHEDCTL
+
+/*===========================================================================*
+ *                             do_schedctl                                  *
+ *===========================================================================*/
+PUBLIC int do_schedctl(message *m_ptr)
+{
+  int proc_nr, pri, new_q ;
+  register struct proc *rp;
+
+  /* Extract the message parameters and do sanity checking. */
+  proc_nr = m_ptr->PR_PROC_NR;
+  if (! isokprocn(proc_nr)) return(EINVAL);
+  pri = m_ptr->PR_PRIORITY;
+  if (pri < PRIO_MIN || pri > PRIO_MAX) return(EINVAL);
+
+  /* The priority is currently between PRIO_MIN and PRIO_MAX. We have to
+   * scale this between MIN_USER_Q and MAX_USER_Q.
+   */
+  new_q = MAX_USER_Q + (pri-PRIO_MIN) * (MIN_USER_Q-MAX_USER_Q+1) / 
+      (PRIO_MAX-PRIO_MIN+1);
+  if (new_q < MAX_USER_Q) new_q = MAX_USER_Q;  /* shouldn't happen */
+  if (new_q > MIN_USER_Q) new_q = MIN_USER_Q;  /* shouldn't happen */
+
+  /* Make sure the process is not running while changing its priority; the
+   * max_priority is the base priority. Put the process back in its new
+   * queue if it is runnable.
+   */
+  rp = proc_addr(proc_nr);
+  lock_unready(rp);
+  rp->p_max_priority = rp->p_priority = new_q;
+  if (! rp->p_rts_flags) lock_ready(rp);
+
+  return(OK);
+}
+
+#endif /* USE_SCHEDCTL */
+
diff --git a/kernel/system/do_sdevio.c b/kernel/system/do_sdevio.c
new file mode 100644 (file)
index 0000000..cc723bc
--- /dev/null
@@ -0,0 +1,61 @@
+/* The system call implemented in this file:
+ *   m_type:   SYS_SDEVIO
+ *
+ * The parameters for this system call are:
+ *    m2_i3:   DIO_REQUEST     (request input or output)       
+ *    m2_i1:   DIO_TYPE        (flag indicating byte, word, or long)
+ *    m2_l1:   DIO_PORT        (port to read/ write)   
+ *    m2_p1:   DIO_VEC_ADDR    (virtual address of buffer)     
+ *    m2_l2:   DIO_VEC_SIZE    (number of elements)    
+ *    m2_i2:   DIO_VEC_PROC    (process where buffer is)       
+ */
+
+#include "../system.h"
+#include <minix/devio.h>
+
+#if USE_SDEVIO
+
+/*===========================================================================*
+ *                             do_sdevio                                    *
+ *===========================================================================*/
+PUBLIC int do_sdevio(m_ptr)
+register message *m_ptr;       /* pointer to request message */
+{
+  int proc_nr = m_ptr->DIO_VEC_PROC;
+  int count = m_ptr->DIO_VEC_SIZE;
+  long port = m_ptr->DIO_PORT;
+  phys_bytes phys_buf;
+
+  /* Check if process number is OK. */
+  if (proc_nr == SELF) proc_nr = m_ptr->m_source;
+  if (! isokprocn(proc_nr))
+      return(EINVAL);
+
+  /* Get and check physical address. */
+  if ((phys_buf = numap_local(proc_nr, (vir_bytes) m_ptr->DIO_VEC_ADDR, count)) == 0)
+      return(EFAULT);
+
+  /* Perform device I/O for bytes and words. Longs are not supported. */
+  if (m_ptr->DIO_REQUEST == DIO_INPUT) { 
+      switch (m_ptr->DIO_TYPE) {
+      case DIO_BYTE: phys_insb(port, phys_buf, count); break; 
+      case DIO_WORD: phys_insw(port, phys_buf, count); break; 
+      default: return(EINVAL);
+      } 
+  } else if (m_ptr->DIO_REQUEST == DIO_OUTPUT) { 
+      switch (m_ptr->DIO_TYPE) {
+      case DIO_BYTE: phys_outsb(port, phys_buf, count); break;  
+      case DIO_WORD: phys_outsw(port, phys_buf, count); break;  
+      default: return(EINVAL);
+      } 
+  }
+  else {
+      return(EINVAL);
+  }
+  return(OK);
+}
+
+#endif /* USE_SDEVIO */
+
+
+
diff --git a/kernel/system/do_segctl.c b/kernel/system/do_segctl.c
new file mode 100644 (file)
index 0000000..0b39813
--- /dev/null
@@ -0,0 +1,84 @@
+/* The system call implemented in this file:
+ *   m_type:   SYS_SEGCTL
+ *
+ * The parameters for this system call are:
+ *    m4_l3:   SEG_PHYS        (physical base address)
+ *    m4_l4:   SEG_SIZE        (size of segment)
+ *    m4_l1:   SEG_SELECT      (return segment selector here)
+ *    m4_l2:   SEG_OFFSET      (return offset within segment here)
+ *    m4_l5:   SEG_INDEX       (return index into remote memory map here)
+ *
+ * Author:
+ *    Jorrit N. Herder <jnherder@cs.vu.nl>
+ */
+#include "../system.h"
+#include "../protect.h"
+
+#if USE_SEGCTL
+
+/*===========================================================================*
+ *                             do_segctl                                    *
+ *===========================================================================*/
+PUBLIC int do_segctl(m_ptr)
+register message *m_ptr;       /* pointer to request message */
+{
+/* Return a segment selector and offset that can be used to reach a physical
+ * address, for use by a driver doing memory I/O in the A0000 - DFFFF range.
+ */
+  u16_t selector;
+  vir_bytes offset;
+  int i, index;
+  register struct proc *rp;
+  phys_bytes phys = (phys_bytes) m_ptr->SEG_PHYS;
+  vir_bytes size = (vir_bytes) m_ptr->SEG_SIZE;
+  int result;
+
+  /* First check if there is a slot available for this segment. */
+  rp = proc_addr(m_ptr->m_source);
+  index = -1;
+  for (i=0; i < NR_REMOTE_SEGS; i++) {
+       if (! rp->p_priv->s_farmem[i].in_use) {
+               index = i; 
+               rp->p_priv->s_farmem[i].in_use = TRUE;
+               rp->p_priv->s_farmem[i].mem_phys = phys;
+               rp->p_priv->s_farmem[i].mem_len = size;
+               break;
+       }
+  }
+  if (index < 0) return(ENOSPC);
+
+
+  if (! machine.protected) {
+      selector = phys / HCLICK_SIZE;
+      offset = phys % HCLICK_SIZE;
+      result = OK;
+  } else {
+      /* Check if the segment size can be recorded in bytes, that is, check
+       * if descriptor's limit field can delimited the allowed memory region
+       * precisely. This works up to 1MB. If the size is larger, 4K pages
+       * instead of bytes are used.
+       */
+      if (size < BYTE_GRAN_MAX) {
+          init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX+i], phys, size, 
+               USER_PRIVILEGE);
+          selector = ((EXTRA_LDT_INDEX+i)*0x08) | (1*0x04) | USER_PRIVILEGE;
+          offset = 0;
+          result = OK;                 
+      } else {
+          init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX+i], phys & ~0xFFFF, 0, 
+               USER_PRIVILEGE);
+          selector = ((EXTRA_LDT_INDEX+i)*0x08) | (1*0x04) | USER_PRIVILEGE;
+          offset = phys & 0xFFFF;
+          result = OK;
+      }
+  }
+
+  /* Request successfully done. Now return the result. */
+  m_ptr->SEG_INDEX = index | REMOTE_SEG;
+  m_ptr->SEG_SELECT = selector;
+  m_ptr->SEG_OFFSET = offset;
+  return(result);
+}
+
+#endif /* USE_SEGCTL */
+
diff --git a/kernel/system/do_sigreturn.c b/kernel/system/do_sigreturn.c
new file mode 100644 (file)
index 0000000..d7abab4
--- /dev/null
@@ -0,0 +1,79 @@
+/* The system call that is implemented in this file:
+ *     SYS_SIGCTL      # signal handling functionality 
+ *
+ * The parameters and types for this system call are:
+ *     SIG_REQUEST     # request to perform                    (long)
+ *     SIG_PROC        # process to signal/ pending            (int)
+ *     SIG_CTXT_PTR    # pointer to sigcontext structure       (pointer)       
+ *     SIG_FLAGS       # flags for S_SIGRETURN call            (int)   
+ *     SIG_MAP         # bit map with pending signals          (long)  
+ *     SIG_NUMBER      # signal number to send to process      (int)   
+ *
+ * Supported request types are in the parameter SIG_REQUEST:
+ *     S_GETSIG                # get a pending kernel signal
+ *     S_ENDSIG                # signal has been processed 
+ *     S_SENDSIG       # deliver a POSIX-style signal 
+ *     S_SIGRETURN     # return from a POSIX-style signal 
+ *     S_KILL          # send a signal to a process 
+ */
+
+#include "../system.h"
+#include <signal.h>
+#include <sys/sigcontext.h>
+
+#if USE_SIGRETURN 
+
+/*===========================================================================*
+ *                           do_sigreturn                                   *
+ *===========================================================================*/
+PUBLIC int do_sigreturn(m_ptr)
+message *m_ptr;                        /* pointer to request message */
+{
+/* POSIX style signals require sys_sigreturn to put things in order before 
+ * the signalled process can resume execution
+ */
+  struct sigcontext sc;
+  register struct proc *rp;
+  phys_bytes src_phys;
+
+  rp = proc_addr(m_ptr->SIG_PROC);
+
+  /* Copy in the sigcontext structure. */
+  src_phys = umap_local(rp, D, (vir_bytes) m_ptr->SIG_CTXT_PTR,
+      (vir_bytes) sizeof(struct sigcontext));
+  if (src_phys == 0) return(EFAULT);
+  phys_copy(src_phys, vir2phys(&sc), (phys_bytes) sizeof(struct sigcontext));
+
+  /* Make sure that this is not just a jump buffer. */
+  if ((sc.sc_flags & SC_SIGCONTEXT) == 0) return(EINVAL);
+
+  /* Fix up only certain key registers if the compiler doesn't use
+   * register variables within functions containing setjmp.
+   */
+  if (sc.sc_flags & SC_NOREGLOCALS) {
+      rp->p_reg.retreg = sc.sc_retreg;
+      rp->p_reg.fp = sc.sc_fp;
+      rp->p_reg.pc = sc.sc_pc;
+      rp->p_reg.sp = sc.sc_sp;
+      return(OK);
+  }
+  sc.sc_psw  = rp->p_reg.psw;
+
+#if (CHIP == INTEL)
+  /* Don't panic kernel if user gave bad selectors. */
+  sc.sc_cs = rp->p_reg.cs;
+  sc.sc_ds = rp->p_reg.ds;
+  sc.sc_es = rp->p_reg.es;
+#if _WORD_SIZE == 4
+  sc.sc_fs = rp->p_reg.fs;
+  sc.sc_gs = rp->p_reg.gs;
+#endif
+#endif
+
+  /* Restore the registers. */
+  kmemcpy(&rp->p_reg, (char *)&sc.sc_regs, sizeof(struct sigregs));
+  return(OK);
+}
+#endif /* USE_SIGRETURN */
+
+
diff --git a/kernel/system/do_sigsend.c b/kernel/system/do_sigsend.c
new file mode 100644 (file)
index 0000000..88c3546
--- /dev/null
@@ -0,0 +1,89 @@
+/* The system call that is implemented in this file:
+ *     SYS_SIGCTL      # signal handling functionality 
+ *
+ * The parameters and types for this system call are:
+ *     SIG_REQUEST     # request to perform                    (long)
+ *     SIG_PROC        # process to signal/ pending            (int)
+ *     SIG_CTXT_PTR    # pointer to sigcontext structure       (pointer)       
+ *     SIG_FLAGS       # flags for S_SIGRETURN call            (int)   
+ *     SIG_MAP         # bit map with pending signals          (long)  
+ *     SIG_NUMBER      # signal number to send to process      (int)   
+ *
+ * Supported request types are in the parameter SIG_REQUEST:
+ *     S_GETSIG                # get a pending kernel signal
+ *     S_ENDSIG                # signal has been processed 
+ *     S_SENDSIG       # deliver a POSIX-style signal 
+ *     S_SIGRETURN     # return from a POSIX-style signal 
+ *     S_KILL          # send a signal to a process 
+ */
+
+#include "../system.h"
+#include <signal.h>
+#include <sys/sigcontext.h>
+
+#if USE_SIGSEND
+
+/*===========================================================================*
+ *                           do_sigsend                                     *
+ *===========================================================================*/
+PUBLIC int do_sigsend(m_ptr)
+message *m_ptr;                        /* pointer to request message */
+{
+/* Handle sys_sigsend, POSIX-style signal handling. */
+
+  struct sigmsg smsg;
+  register struct proc *rp;
+  phys_bytes src_phys, dst_phys;
+  struct sigcontext sc, *scp;
+  struct sigframe fr, *frp;
+
+  rp = proc_addr(m_ptr->SIG_PROC);
+
+  /* Get the sigmsg structure into our address space.  */
+  src_phys = umap_local(proc_addr(PM_PROC_NR), D, (vir_bytes) 
+      m_ptr->SIG_CTXT_PTR, (vir_bytes) sizeof(struct sigmsg));
+  if (src_phys == 0) return(EFAULT);
+  phys_copy(src_phys,vir2phys(&smsg),(phys_bytes) sizeof(struct sigmsg));
+
+  /* Compute the user stack pointer where sigcontext will be stored. */
+  scp = (struct sigcontext *) smsg.sm_stkptr - 1;
+
+  /* Copy the registers to the sigcontext structure. */
+  kmemcpy(&sc.sc_regs, &rp->p_reg, sizeof(struct sigregs));
+
+  /* Finish the sigcontext initialization. */
+  sc.sc_flags = SC_SIGCONTEXT;
+  sc.sc_mask = smsg.sm_mask;
+
+  /* Copy the sigcontext structure to the user's stack. */
+  dst_phys = umap_local(rp, D, (vir_bytes) scp,
+      (vir_bytes) sizeof(struct sigcontext));
+  if (dst_phys == 0) return(EFAULT);
+  phys_copy(vir2phys(&sc), dst_phys, (phys_bytes) sizeof(struct sigcontext));
+
+  /* Initialize the sigframe structure. */
+  frp = (struct sigframe *) scp - 1;
+  fr.sf_scpcopy = scp;
+  fr.sf_retadr2= (void (*)()) rp->p_reg.pc;
+  fr.sf_fp = rp->p_reg.fp;
+  rp->p_reg.fp = (reg_t) &frp->sf_fp;
+  fr.sf_scp = scp;
+  fr.sf_code = 0;      /* XXX - should be used for type of FP exception */
+  fr.sf_signo = smsg.sm_signo;
+  fr.sf_retadr = (void (*)()) smsg.sm_sigreturn;
+
+  /* Copy the sigframe structure to the user's stack. */
+  dst_phys = umap_local(rp, D, (vir_bytes) frp, 
+      (vir_bytes) sizeof(struct sigframe));
+  if (dst_phys == 0) return(EFAULT);
+  phys_copy(vir2phys(&fr), dst_phys, (phys_bytes) sizeof(struct sigframe));
+
+  /* Reset user registers to execute the signal handler. */
+  rp->p_reg.sp = (reg_t) frp;
+  rp->p_reg.pc = (reg_t) smsg.sm_sighandler;
+
+  return(OK);
+}
+
+#endif /* USE_SIGSEND */
+
diff --git a/kernel/system/do_svrctl.c b/kernel/system/do_svrctl.c
new file mode 100644 (file)
index 0000000..1580192
--- /dev/null
@@ -0,0 +1,72 @@
+/* The system call implemented in this file:
+ *   m_type:   SYS_SVRCTL
+ *
+ * The parameters for this system call are:
+ *    m2_i1:   CTL_PROC_NR     (process number of caller)      
+ *    m2_i2:   CTL_REQUEST     (request type)  
+ *    m2_i3:   CTL_MM_PRIV     (privilege)
+ *    m2_l1:    CTL_SEND_MASK   (new send mask to be installed)
+ *    m2_l2:    CTL_PROC_TYPE   (new process type)
+ *    m2_p1:   CTL_ARG_PTR     (argument pointer)
+ */
+
+#include "../system.h"
+#include "../ipc.h"
+#include <sys/svrctl.h>
+
+#if USE_SVRCTL
+
+/* NOTE: this call will radically change! */
+
+/*===========================================================================*
+ *                             do_svrctl                                    *
+ *===========================================================================*/
+PUBLIC int do_svrctl(m_ptr)
+message *m_ptr;                        /* pointer to request message */
+{
+  register struct proc *rp;
+  register struct priv *sp;
+  int proc_nr, rights;
+  int request;
+  vir_bytes argp;
+
+  /* Extract message parameters. */
+  proc_nr = m_ptr->CTL_PROC_NR;
+  if (proc_nr == SELF) proc_nr = m_ptr->m_source;
+  if (! isokprocn(proc_nr)) return(EINVAL);
+
+  request = m_ptr->CTL_REQUEST;
+  rights = m_ptr->CTL_MM_PRIV;
+  argp = (vir_bytes) m_ptr->CTL_ARG_PTR;
+  rp = proc_addr(proc_nr);
+
+  /* Check if the PM privileges are super user. */
+  if (!rights || !isuserp(rp)) 
+      return(EPERM);
+
+  /* See what is requested and handle the request. */
+  switch (request) {
+  case SYSSIGNON: {
+       /* Make this process a server. The system processes should be able
+        * to communicate with this new server, so update their send masks
+        * as well.
+        */
+       
+       /* Find a new system privileges structure for this process. */
+       for (sp=BEG_PRIV_ADDR; sp< END_PRIV_ADDR; sp++) 
+               if (sp->s_proc_nr == NONE) break;
+       if (sp->s_proc_nr != NONE) return(ENOSPC);
+
+       /* Now update the process' privileges as requested. */
+       rp->p_priv = sp;                        /* assign to process */
+       rp->p_priv->s_proc_nr = proc_nr(rp);    /* set association */
+       rp->p_priv->s_call_mask = SYSTEM_CALL_MASK;
+       return(OK);
+  }
+  default:
+       return(EINVAL);
+  }
+}
+
+#endif /* USE_SVRCTL */
+
diff --git a/kernel/system/do_times.c b/kernel/system/do_times.c
new file mode 100644 (file)
index 0000000..bbd925b
--- /dev/null
@@ -0,0 +1,40 @@
+/* The system call implemented in this file:
+ *   m_type:   SYS_TIMES
+ *
+ * The parameters for this system call are:
+ *    m4_l1:   T_PROC_NR               (get info for this process)     
+ *    m4_l1:   T_USER_TIME             (return values ...)     
+ *    m4_l2:   T_SYSTEM_TIME   
+ *    m4_l5:   T_BOOT_TICKS    
+ */
+
+#include "../system.h"
+
+#if USE_TIMES
+
+/*===========================================================================*
+ *                             do_times                                     *
+ *===========================================================================*/
+PUBLIC int do_times(m_ptr)
+register message *m_ptr;       /* pointer to request message */
+{
+/* Handle sys_times().  Retrieve the accounting information. */
+  register struct proc *rp;
+  int proc_nr;
+
+  /* Insert the times needed by the SYS_TIMES system call in the message. 
+   * The clock's interrupt handler may run to update the user or system time
+   * while in this code, but that cannot do any harm.
+   */
+  proc_nr = (m_ptr->T_PROC_NR == SELF) ? m_ptr->m_source : m_ptr->T_PROC_NR;
+  if (isokprocn(proc_nr)) {
+      rp = proc_addr(m_ptr->T_PROC_NR);
+      m_ptr->T_USER_TIME   = rp->p_user_time;
+      m_ptr->T_SYSTEM_TIME = rp->p_sys_time;
+  }
+  m_ptr->T_BOOT_TICKS = get_uptime();  
+  return(OK);
+}
+
+#endif /* USE_TIMES */
+
similarity index 99%
rename from kernel/system/tracing.c
rename to kernel/system/do_trace.c
index 02d9f3bf7d4fcd60cb8c65dbea960940bbb6d5ba..bcf07bef7469c9a5854b647605da3262e6bc31d4 100644 (file)
@@ -8,10 +8,10 @@
  *    m2_l2:    CTL_DATA        data to be written or returned here
  */
 
-#include "../kernel.h"
 #include "../system.h"
 #include <sys/ptrace.h>
 
+#if USE_TRACE
 
 /*==========================================================================*
  *                             do_trace                                    *
@@ -138,3 +138,4 @@ register message *m_ptr;
   return(OK);
 }
 
+#endif /* USE_TRACE */
diff --git a/kernel/system/do_umap.c b/kernel/system/do_umap.c
new file mode 100644 (file)
index 0000000..79956e1
--- /dev/null
@@ -0,0 +1,52 @@
+/* The system call implemented in this file:
+ *   m_type:   SYS_UMAP
+ *
+ * The parameters for this system call are:
+ *    m5_i1:   CP_SRC_PROC_NR  (process number)        
+ *    m5_c1:   CP_SRC_SPACE    (segment where address is: T, D, or S)
+ *    m5_l1:   CP_SRC_ADDR     (virtual address)       
+ *    m5_l2:   CP_DST_ADDR     (returns physical address)      
+ *    m5_l3:   CP_NR_BYTES     (size of datastructure)         
+ */
+
+#include "../system.h"
+
+#if USE_UMAP
+
+/*==========================================================================*
+ *                             do_umap                                     *
+ *==========================================================================*/
+PUBLIC int do_umap(m_ptr)
+register message *m_ptr;       /* pointer to request message */
+{
+/* Map virtual address to physical, for non-kernel processes. */
+  int seg_type = m_ptr->CP_SRC_SPACE & SEGMENT_TYPE;
+  int seg_index = m_ptr->CP_SRC_SPACE & SEGMENT_INDEX;
+  vir_bytes offset = m_ptr->CP_SRC_ADDR;
+  int count = m_ptr->CP_NR_BYTES;
+  int proc_nr = (int) m_ptr->CP_SRC_PROC_NR;
+  phys_bytes phys_addr;
+
+  /* Verify process number. */
+  if (proc_nr == SELF) proc_nr = m_ptr->m_source;
+  if (! isokprocn(proc_nr)) return(EINVAL);
+
+  /* See which mapping should be made. */
+  switch(seg_type) {
+  case LOCAL_SEG:
+      phys_addr = umap_local(proc_addr(proc_nr), seg_index, offset, count); 
+      break;
+  case REMOTE_SEG:
+      phys_addr = umap_remote(proc_addr(proc_nr), seg_index, offset, count); 
+      break;
+  case BIOS_SEG:
+      phys_addr = umap_bios(proc_addr(proc_nr), offset, count); 
+      break;
+  default:
+      return(EINVAL);
+  }
+  m_ptr->CP_DST_ADDR = phys_addr;
+  return (phys_addr == 0) ? EFAULT: OK;
+}
+
+#endif /* USE_UMAP */
diff --git a/kernel/system/do_unused.c b/kernel/system/do_unused.c
new file mode 100644 (file)
index 0000000..c0278ad
--- /dev/null
@@ -0,0 +1,15 @@
+
+#include "../system.h"
+
+/*===========================================================================*
+ *                               do_unused                                  *
+ *===========================================================================*/
+PUBLIC int do_unused(m)
+message *m;                            /* pointer to request message */
+{
+  kprintf("SYSTEM got unused request %d", m->m_type);
+  kprintf("from %d.\n", m->m_source);
+  return(EBADREQUEST);         /* illegal message type */
+}
+
+
diff --git a/kernel/system/do_vcopy.c b/kernel/system/do_vcopy.c
new file mode 100644 (file)
index 0000000..42cef86
--- /dev/null
@@ -0,0 +1,67 @@
+/* The system call implemented in this file:
+ *   m_type:   SYS_VIRVCOPY, SYS_PHYSVCOPY 
+ *
+ * The parameters for this system call are:
+ *    m5_c1:   CP_SRC_SPACE
+ *    m5_l1:   CP_SRC_ADDR
+ *    m5_i1:   CP_SRC_PROC_NR  
+ *    m5_c2:   CP_DST_SPACE
+ *    m5_l2:   CP_DST_ADDR     
+ *    m5_i2:   CP_DST_PROC_NR  
+ *    m5_l3:   CP_NR_BYTES
+ */
+
+#include "../system.h"
+#include <minix/type.h>
+
+#if (USE_VIRVCOPY || USE_PHYSVCOPY)
+
+/* Buffer to hold copy request vector from user. */
+PRIVATE struct vir_cp_req vir_cp_req[VCOPY_VEC_SIZE];
+
+/*===========================================================================*
+ *                             do_vcopy                                             *
+ *===========================================================================*/
+PUBLIC int do_vcopy(m_ptr)
+register message *m_ptr;       /* pointer to request message */
+{
+/* Handle sys_virvcopy(). Handle virtual copy requests from vector. */
+  int nr_req;
+  int caller_pid;
+  vir_bytes caller_vir;
+  phys_bytes caller_phys;
+  phys_bytes kernel_phys;
+  phys_bytes bytes;
+  int i,s;
+  struct vir_cp_req *req;
+
+  /* Check if request vector size is ok. */
+  nr_req = (unsigned) m_ptr->VCP_VEC_SIZE;
+  if (nr_req > VCOPY_VEC_SIZE) return(EINVAL);
+  bytes = nr_req * sizeof(struct vir_cp_req);
+
+  /* Calculate physical addresses and copy (port,value)-pairs from user. */
+  caller_pid = (int) m_ptr->m_source; 
+  caller_vir = (vir_bytes) m_ptr->VCP_VEC_ADDR;
+  caller_phys = umap_local(proc_addr(caller_pid), D, caller_vir, bytes);
+  if (0 == caller_phys) return(EFAULT);
+  kernel_phys = vir2phys(vir_cp_req);
+  phys_copy(caller_phys, kernel_phys, (phys_bytes) bytes);
+
+  /* Assume vector with requests is correct. Try to copy everything. */
+  for (i=0; i<nr_req; i++) {
+
+      req = &vir_cp_req[i];
+
+      /* Check if physical addressing is used without SYS_PHYSVCOPY. */
+      if (((req->src.segment | req->dst.segment) & PHYS_SEG) &&
+              m_ptr->m_type != SYS_PHYSVCOPY) 
+          return(EPERM);
+      if ((s=virtual_copy(&req->src, &req->dst, req->count)) != OK) 
+          return(s);
+  }
+  return(OK);
+}
+
+#endif /* (USE_VIRVCOPY || USE_PHYSVCOPY) */
+
similarity index 62%
rename from kernel/system/devio.c
rename to kernel/system/do_vdevio.c
index 4991486955ea8a04d5baf2eb9f53b3e97eaf3cf1..5b94870d1bfedec2f519a0b3a4b9ad88c0d78161 100644 (file)
 /* The system call implemented in this file:
- *   m_type:   SYS_DEVIO
+ *   m_type:   SYS_VDEVIO
  *
  * The parameters for this system call are:
  *    m2_i3:   DIO_REQUEST     (request input or output)       
  *    m2_i1:   DIO_TYPE        (flag indicating byte, word, or long)
- *    m2_l1:   DIO_PORT        (port to read/ write)   
- *    m2_l2:   DIO_VALUE       (value to write/ return value read)     
- *
- * Author:
- *    Jorrit N. Herder <jnherder@cs.vu.nl>
+ *    m2_p1:   DIO_VEC_ADDR    (pointer to port/ value pairs)  
+ *    m2_i2:   DIO_VEC_SIZE    (number of ports to read or write) 
  */
 
-#include "../kernel.h"
 #include "../system.h"
-#include "../debug.h"
 #include <minix/devio.h>
 
-/*===========================================================================*
- *                             do_devio                                     *
- *===========================================================================*/
-PUBLIC int do_devio(m_ptr)
-register message *m_ptr;       /* pointer to request message */
-{
-    /* perform actual device I/O for byte, word, and long values */
-    if (m_ptr->DIO_REQUEST == DIO_INPUT) { 
-      switch (m_ptr->DIO_TYPE) {
-        case DIO_BYTE: m_ptr->DIO_VALUE = inb(m_ptr->DIO_PORT); break; 
-        case DIO_WORD: m_ptr->DIO_VALUE = inw(m_ptr->DIO_PORT); break; 
-        case DIO_LONG: m_ptr->DIO_VALUE = inl(m_ptr->DIO_PORT); break; 
-       default: return(EINVAL);
-      } 
-    } else { 
-      switch (m_ptr->DIO_TYPE) {
-        case DIO_BYTE: outb(m_ptr->DIO_PORT, m_ptr->DIO_VALUE); break;  
-        case DIO_WORD: outw(m_ptr->DIO_PORT, m_ptr->DIO_VALUE); break;  
-        case DIO_LONG: outl(m_ptr->DIO_PORT, m_ptr->DIO_VALUE); break;  
-       default: return(EINVAL);
-      } 
-    }
-    return(OK);
-}
-
-
-/* The system call implemented in this file:
- *   m_type:   SYS_SDEVIO
- *
- * The parameters for this system call are:
- *    m2_i3:   DIO_REQUEST     (request input or output)       
- *    m2_i1:   DIO_TYPE        (flag indicating byte, word, or long)
- *    m2_l1:   DIO_PORT        (port to read/ write)   
- *    m2_p1:   DIO_VEC_ADDR    (virtual address of buffer)     
- *    m2_l2:   DIO_VEC_SIZE    (number of elements)    
- *    m2_i2:   DIO_VEC_PROC    (process where buffer is)       
- */
-
-/*===========================================================================*
- *                             do_sdevio                                    *
- *===========================================================================*/
-PUBLIC int do_sdevio(m_ptr)
-register message *m_ptr;       /* pointer to request message */
-{
-  int proc_nr = m_ptr->DIO_VEC_PROC;
-  int count = m_ptr->DIO_VEC_SIZE;
-  long port = m_ptr->DIO_PORT;
-  phys_bytes phys_buf;
-
-  /* Check if process number is OK. */
-  if (proc_nr == SELF) proc_nr = m_ptr->m_source;
-  if (! isokprocn(proc_nr))
-      return(EINVAL);
-
-  /* Get and check physical address. */
-  if ((phys_buf = numap_local(proc_nr, (vir_bytes) m_ptr->DIO_VEC_ADDR, count)) == 0)
-      return(EFAULT);
-
-  /* Perform device I/O for bytes and words. Longs are not supported. */
-  if (m_ptr->DIO_REQUEST == DIO_INPUT) { 
-      switch (m_ptr->DIO_TYPE) {
-      case DIO_BYTE: phys_insb(port, phys_buf, count); break; 
-      case DIO_WORD: phys_insw(port, phys_buf, count); break; 
-      default: return(EINVAL);
-      } 
-  } else if (m_ptr->DIO_REQUEST == DIO_OUTPUT) { 
-      switch (m_ptr->DIO_TYPE) {
-      case DIO_BYTE: phys_outsb(port, phys_buf, count); break;  
-      case DIO_WORD: phys_outsw(port, phys_buf, count); break;  
-      default: return(EINVAL);
-      } 
-  }
-  else {
-      return(EINVAL);
-  }
-  return(OK);
-}
-
+#if USE_VDEVIO
 
-/* The system call implemented in this file:
- *   m_type:   SYS_VDEVIO
- *
- * The parameters for this system call are:
- *    m2_i3:   DIO_REQUEST     (request input or output)       
- *    m2_i1:   DIO_TYPE        (flag indicating byte, word, or long)
- *    m2_p1:   DIO_VEC_ADDR    (pointer to port/ value pairs)  
- *    m2_i2:   DIO_VEC_SIZE    (number of ports to read or write) 
- */
 
 /* Buffer for SYS_VDEVIO to copy (port,value)-pairs from/ to user. */
 PRIVATE char vdevio_pv_buf[VDEVIO_BUF_SIZE];      
@@ -213,4 +122,5 @@ register message *m_ptr;    /* pointer to request message */
     return(OK);
 }
 
+#endif /* USE_VDEVIO */
 
diff --git a/kernel/system/priority.c b/kernel/system/priority.c
deleted file mode 100644 (file)
index 33db5d5..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* The system call implemented in this file:
- *   m_type:   SYS_SETPRIORITY
- *
- * The parameters for this system call are:
- *    m1_i1:   which
- *    m1_i2:   who
- *    m1_i3:   prio
- */
-
-#include "../kernel.h"
-#include "../system.h"
-#include <minix/type.h>
-#include <sys/resource.h>
-
-/*===========================================================================*
- *                             do_setpriority                                  *
- *===========================================================================*/
-PUBLIC int do_setpriority(message *m_ptr)
-{
-       int which_proc, pri, q, niceperq;
-       struct proc *which_procp;
-
-       which_proc = m_ptr->m1_i1;
-       pri  = m_ptr->m1_i2;
-
-       /* pri is currently between PRIO_MIN and PRIO_MAX. We have to
-        * scale this between MIN_USER_Q and MAX_USER_Q.
-        */
-
-       if(pri < PRIO_MIN || pri > PRIO_MAX)
-               return EINVAL;
-
-       if(which_proc < 0 || which_proc >= NR_TASKS+NR_PROCS)
-               return EINVAL;
-
-       which_procp = proc_addr(which_proc);
-
-       q = MAX_USER_Q + (pri - PRIO_MIN) * (MIN_USER_Q-MAX_USER_Q+1) / (PRIO_MAX-PRIO_MIN+1);
-
-       /* The below shouldn't happen. */
-       if(q < MAX_USER_Q) q = MAX_USER_Q;
-       if(q > MIN_USER_Q) q = MIN_USER_Q;
-
-       /* max_priority is the base priority. */
-       which_procp->p_max_priority = q;
-       lock_unready(which_procp);
-       which_procp->p_priority = q;
-
-       /* Runnable? Put it (back) on its new run queue. */
-       if(!which_procp->p_rts_flags)
-               lock_ready(which_procp);
-
-       return OK;
-}
-
-
diff --git a/kernel/system/proctl.c b/kernel/system/proctl.c
deleted file mode 100644 (file)
index a10f35c..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-/* The system call implemented in this file:
- *   m_type:   SYS_FORK
- *
- * The parameters for this system call are:
- *    m1_i1:   PR_PROC_NR      (child's process table slot)    
- *    m1_i2:   PR_PPROC_NR     (parent, process that forked)   
- *    m1_i3:   PR_PID          (child pid received from PM)
- */
-
-#include "../kernel.h"
-#include "../system.h"
-#include "../sendmask.h"
-#include <signal.h>
-#if (CHIP == INTEL)
-#include "../protect.h"
-#endif
-#include "../debug.h"
-
-
-/*===========================================================================*
- *                             do_fork                                      *
- *===========================================================================*/
-PUBLIC int do_fork(m_ptr)
-register message *m_ptr;       /* pointer to request message */
-{
-/* Handle sys_fork().  PR_PPROC_NR has forked.  The child is PR_PROC_NR. */
-
-#if (CHIP == INTEL)
-  reg_t old_ldt_sel;
-#endif
-  register struct proc *rpc;
-  struct proc *rpp;
-
-  rpp = proc_addr(m_ptr->PR_PPROC_NR);
-  rpc = proc_addr(m_ptr->PR_PROC_NR);
-  if (! isemptyp(rpc)) return(EINVAL);
-
-  /* Copy parent 'proc' struct to child. */
-#if (CHIP == INTEL)
-  old_ldt_sel = rpc->p_ldt_sel;        /* stop this being obliterated by copy */
-#endif
-
-  *rpc = *rpp;                                 /* copy 'proc' struct */
-
-#if (CHIP == INTEL)
-  rpc->p_ldt_sel = old_ldt_sel;
-#endif
-  rpc->p_nr = m_ptr->PR_PROC_NR;       /* this was obliterated by copy */
-  rpc->p_ntf_q = NULL;                 /* remove pending notifications */
-
-  /* Only one in group should have SIGNALED, child doesn't inherit tracing. */
-  rpc->p_rts_flags |= NO_MAP;          /* inhibit process from running */
-  rpc->p_rts_flags &= ~(SIGNALED | SIG_PENDING | P_STOP);
-  sigemptyset(&rpc->p_pending);
-
-  rpc->p_reg.retreg = 0;       /* child sees pid = 0 to know it is child */
-  rpc->p_user_time = 0;                /* set all the accounting times to 0 */
-  rpc->p_sys_time = 0;
-
-  return(OK);
-}
-
-
-/* The system call implemented in this file:
- *   m_type:   SYS_NEWMAP
- *
- * The parameters for this system call are:
- *    m1_i1:   PR_PROC_NR              (install new map for this process)
- *    m1_p1:   PR_MEM_PTR              (pointer to memory map)
- */
-
-
-/*===========================================================================*
- *                             do_newmap                                    *
- *===========================================================================*/
-PUBLIC int do_newmap(m_ptr)
-message *m_ptr;                        /* pointer to request message */
-{
-/* Handle sys_newmap().  Fetch the memory map from PM. */
-
-  register struct proc *rp;
-  phys_bytes src_phys;
-  int caller;                  /* whose space has the new map (usually PM) */
-  int k;                       /* process whose map is to be loaded */
-  int old_flags;               /* value of flags before modification */
-  struct mem_map *map_ptr;     /* virtual address of map inside caller (PM) */
-
-  /* Extract message parameters and copy new memory map from PM. */
-  caller = m_ptr->m_source;
-  k = m_ptr->PR_PROC_NR;
-  map_ptr = (struct mem_map *) m_ptr->PR_MEM_PTR;
-  if (!isokprocn(k)) return(EINVAL);
-  rp = proc_addr(k);           /* ptr to entry of user getting new map */
-
-  /* Copy the map from PM. */
-  src_phys = umap_local(proc_addr(caller), D, (vir_bytes) map_ptr, 
-       sizeof(rp->p_memmap));
-  if (src_phys == 0) return(EFAULT);
-  phys_copy(src_phys,vir2phys(rp->p_memmap),(phys_bytes)sizeof(rp->p_memmap));
-
-#if (CHIP != M68000)
-  alloc_segments(rp);
-#else
-  pmmu_init_proc(rp);
-#endif
-  old_flags = rp->p_rts_flags; /* save the previous value of the flags */
-  rp->p_rts_flags &= ~NO_MAP;
-  if (old_flags != 0 && rp->p_rts_flags == 0) lock_ready(rp);
-
-  return(OK);
-}
-
-
-/* The system call implemented in this file:
- *   m_type:   SYS_EXEC
- *
- * The parameters for this system call are:
- *    m1_i1:   PR_PROC_NR              (process that did exec call)
- *    m1_i3:   PR_TRACING              (flag to indicate tracing is on/ off)
- *    m1_p1:   PR_STACK_PTR            (new stack pointer)
- *    m1_p2:   PR_NAME_PTR             (pointer to program name)
- *    m1_p3:   PR_IP_PTR               (new instruction pointer)
- */
-
-/*===========================================================================*
- *                             do_exec                                      *
- *===========================================================================*/
-PUBLIC int do_exec(m_ptr)
-register message *m_ptr;       /* pointer to request message */
-{
-/* Handle sys_exec().  A process has done a successful EXEC. Patch it up. */
-
-  register struct proc *rp;
-  reg_t sp;                    /* new sp */
-  phys_bytes phys_name;
-  char *np;
-
-  rp = proc_addr(m_ptr->PR_PROC_NR);
-  if (m_ptr->PR_TRACING) cause_sig(m_ptr->PR_PROC_NR, SIGTRAP);
-  sp = (reg_t) m_ptr->PR_STACK_PTR;
-  rp->p_reg.sp = sp;           /* set the stack pointer */
-#if (CHIP == M68000)
-  rp->p_splow = sp;            /* set the stack pointer low water */
-#ifdef FPP
-  /* Initialize fpp for this process */
-  fpp_new_state(rp);
-#endif
-#endif
-#if (CHIP == INTEL)            /* wipe extra LDT entries */
-  kmemset(&rp->p_ldt[EXTRA_LDT_INDEX], 0,
-       (LDT_SIZE - EXTRA_LDT_INDEX) * sizeof(rp->p_ldt[0]));
-#endif
-  rp->p_reg.pc = (reg_t) m_ptr->PR_IP_PTR;     /* set pc */
-  rp->p_rts_flags &= ~RECEIVING;       /* PM does not reply to EXEC call */
-  if (rp->p_rts_flags == 0) lock_ready(rp);
-
-  /* Save command name for debugging, ps(1) output, etc. */
-  phys_name = numap_local(m_ptr->m_source, (vir_bytes) m_ptr->PR_NAME_PTR,
-                                       (vir_bytes) P_NAME_LEN - 1);
-  if (phys_name != 0) {
-       phys_copy(phys_name, vir2phys(rp->p_name), (phys_bytes) P_NAME_LEN - 1);
-       for (np = rp->p_name; (*np & BYTE) >= ' '; np++) {}
-       *np = 0;                                        /* mark end */
-  } else {
-       kstrncpy(rp->p_name, "<unset>", P_NAME_LEN);
-  }
-  return(OK);
-}
-
-
-/* The system call implemented in this file:
- *   m_type:   SYS_XIT
- *
- * The parameters for this system call are:
- *    m1_i1:   PR_PROC_NR              (slot number of exiting process)
- */
-
-
-
-/*===========================================================================*
- *                             do_xit                                       *
- *===========================================================================*/
-PUBLIC int do_xit(m_ptr)
-message *m_ptr;                        /* pointer to request message */
-{
-/* Handle sys_exit. A user process has exited or a system process requests 
- * to exit. Only the PM can request other process slots to be cleared.
- * The routine to clean up a process table slot cancels outstanding timers, 
- * possibly removes the process from the message queues, and resets certain 
- * process table fields to the default values.
- */
-  int exit_proc_nr;                            
-
-  /* Determine what process exited. */
-  if (PM_PROC_NR == m_ptr->m_source) {
-      exit_proc_nr = m_ptr->PR_PROC_NR;                /* get exiting process */
-      if (exit_proc_nr != SELF) {              /* PM tries to exit self */
-          if (! isokprocn(exit_proc_nr)) return(EINVAL);
-          clear_proc(exit_proc_nr);            /* exit a user process */
-          return(OK);                          /* report back to PM */
-      }
-  } 
-
-  /* The PM or some other system process requested to be exited. */
-  clear_proc(m_ptr->m_source);
-  return(EDONTREPLY);
-}
-
-
diff --git a/kernel/system/sigctl.c b/kernel/system/sigctl.c
deleted file mode 100644 (file)
index fc5c5cd..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/* The system call that is implemented in this file:
- *     SYS_SIGCTL      # signal handling functionality 
- *
- * The parameters and types for this system call are:
- *     SIG_REQUEST     # request to perform                    (long)
- *     SIG_PROC        # process to signal/ pending            (int)
- *     SIG_CTXT_PTR    # pointer to sigcontext structure       (pointer)       
- *     SIG_FLAGS       # flags for S_SIGRETURN call            (int)   
- *     SIG_MAP         # bit map with pending signals          (long)  
- *     SIG_NUMBER      # signal number to send to process      (int)   
- *
- * Supported request types are in the parameter SIG_REQUEST:
- *     S_GETSIG                # get a pending kernel signal
- *     S_ENDSIG                # signal has been processed 
- *     S_SENDSIG       # deliver a POSIX-style signal 
- *     S_SIGRETURN     # return from a POSIX-style signal 
- *     S_KILL          # send a signal to a process 
- */
-
-#include "../kernel.h"
-#include "../system.h"
-#include <signal.h>
-#include <sys/sigcontext.h>
-
-/* PM is ready to accept signals and repeatedly does a system call to get 
- * one. Find a process with pending signals. If no signals are available, 
- * return NONE in the process number field.
- */
-PUBLIC int do_getsig(m_ptr)
-message *m_ptr;                        /* pointer to request message */
-{
-  register struct proc *rp;
-
-  /* Find the next process with pending signals. */
-  for (rp = BEG_USER_ADDR; rp < END_PROC_ADDR; rp++) {
-      if (rp->p_rts_flags & SIGNALED) {
-          m_ptr->SIG_PROC = rp->p_nr;
-          m_ptr->SIG_MAP = rp->p_pending;
-          sigemptyset(&rp->p_pending);         /* ball is in PM's court */
-          rp->p_rts_flags &= ~SIGNALED;        /* blocked by SIG_PENDING */
-          return(OK);
-      }
-  }
-
-  /* No process with pending signals was found. */
-  m_ptr->SIG_PROC = NONE; 
-  return(OK);
-}
-
-PUBLIC int do_endsig(m_ptr)
-message *m_ptr;                        /* pointer to request message */
-{
-/* Finish up after a kernel type signal, caused by a SYS_KILL message or a 
- * call to cause_sig by a task. This is called by the PM after processing a
- * signal it got with SYS_GETSIG.
- */
-  register struct proc *rp;
-
-  rp = proc_addr(m_ptr->SIG_PROC);
-  if (isemptyp(rp)) return(EINVAL);            /* process already dead? */
-
-  /* PM has finished one kernel signal. Perhaps process is ready now? */
-  if (! (rp->p_rts_flags & SIGNALED))          /* new signal arrived */
-     if ((rp->p_rts_flags &= ~SIG_PENDING)==0) /* remove pending flag */
-         lock_ready(rp);                       /* ready if no flags */
-  return(OK);
-}
-
-PUBLIC int do_sigsend(m_ptr)
-message *m_ptr;                        /* pointer to request message */
-{
-/* Handle sys_sigsend, POSIX-style signal handling. */
-
-  struct sigmsg smsg;
-  register struct proc *rp;
-  phys_bytes src_phys, dst_phys;
-  struct sigcontext sc, *scp;
-  struct sigframe fr, *frp;
-
-  rp = proc_addr(m_ptr->SIG_PROC);
-
-  /* Get the sigmsg structure into our address space.  */
-  src_phys = umap_local(proc_addr(PM_PROC_NR), D, (vir_bytes) 
-      m_ptr->SIG_CTXT_PTR, (vir_bytes) sizeof(struct sigmsg));
-  if (src_phys == 0) return(EFAULT);
-  phys_copy(src_phys,vir2phys(&smsg),(phys_bytes) sizeof(struct sigmsg));
-
-  /* Compute the user stack pointer where sigcontext will be stored. */
-  scp = (struct sigcontext *) smsg.sm_stkptr - 1;
-
-  /* Copy the registers to the sigcontext structure. */
-  kmemcpy(&sc.sc_regs, &rp->p_reg, sizeof(struct sigregs));
-
-  /* Finish the sigcontext initialization. */
-  sc.sc_flags = SC_SIGCONTEXT;
-  sc.sc_mask = smsg.sm_mask;
-
-  /* Copy the sigcontext structure to the user's stack. */
-  dst_phys = umap_local(rp, D, (vir_bytes) scp,
-      (vir_bytes) sizeof(struct sigcontext));
-  if (dst_phys == 0) return(EFAULT);
-  phys_copy(vir2phys(&sc), dst_phys, (phys_bytes) sizeof(struct sigcontext));
-
-  /* Initialize the sigframe structure. */
-  frp = (struct sigframe *) scp - 1;
-  fr.sf_scpcopy = scp;
-  fr.sf_retadr2= (void (*)()) rp->p_reg.pc;
-  fr.sf_fp = rp->p_reg.fp;
-  rp->p_reg.fp = (reg_t) &frp->sf_fp;
-  fr.sf_scp = scp;
-  fr.sf_code = 0;      /* XXX - should be used for type of FP exception */
-  fr.sf_signo = smsg.sm_signo;
-  fr.sf_retadr = (void (*)()) smsg.sm_sigreturn;
-
-  /* Copy the sigframe structure to the user's stack. */
-  dst_phys = umap_local(rp, D, (vir_bytes) frp, 
-      (vir_bytes) sizeof(struct sigframe));
-  if (dst_phys == 0) return(EFAULT);
-  phys_copy(vir2phys(&fr), dst_phys, (phys_bytes) sizeof(struct sigframe));
-
-  /* Reset user registers to execute the signal handler. */
-  rp->p_reg.sp = (reg_t) frp;
-  rp->p_reg.pc = (reg_t) smsg.sm_sighandler;
-
-  return(OK);
-}
-
-PUBLIC int do_sigreturn(m_ptr)
-message *m_ptr;                        /* pointer to request message */
-{
-/* POSIX style signals require sys_sigreturn to put things in order before 
- * the signalled process can resume execution
- */
-  struct sigcontext sc;
-  register struct proc *rp;
-  phys_bytes src_phys;
-
-  rp = proc_addr(m_ptr->SIG_PROC);
-
-  /* Copy in the sigcontext structure. */
-  src_phys = umap_local(rp, D, (vir_bytes) m_ptr->SIG_CTXT_PTR,
-      (vir_bytes) sizeof(struct sigcontext));
-  if (src_phys == 0) return(EFAULT);
-  phys_copy(src_phys, vir2phys(&sc), (phys_bytes) sizeof(struct sigcontext));
-
-  /* Make sure that this is not just a jmp_buf. */
-  if ((sc.sc_flags & SC_SIGCONTEXT) == 0) return(EINVAL);
-
-  /* Fix up only certain key registers if the compiler doesn't use
-   * register variables within functions containing setjmp.
-   */
-  if (sc.sc_flags & SC_NOREGLOCALS) {
-      rp->p_reg.retreg = sc.sc_retreg;
-      rp->p_reg.fp = sc.sc_fp;
-      rp->p_reg.pc = sc.sc_pc;
-      rp->p_reg.sp = sc.sc_sp;
-      return(OK);
-  }
-  sc.sc_psw  = rp->p_reg.psw;
-
-#if (CHIP == INTEL)
-  /* Don't panic kernel if user gave bad selectors. */
-  sc.sc_cs = rp->p_reg.cs;
-  sc.sc_ds = rp->p_reg.ds;
-  sc.sc_es = rp->p_reg.es;
-#if _WORD_SIZE == 4
-  sc.sc_fs = rp->p_reg.fs;
-  sc.sc_gs = rp->p_reg.gs;
-#endif
-#endif
-
-  /* Restore the registers. */
-  kmemcpy(&rp->p_reg, (char *)&sc.sc_regs, sizeof(struct sigregs));
-  return(OK);
-}
-
-/*===========================================================================*
- *                           do_sigctl                                      *
- *===========================================================================*/
-
-PUBLIC int do_kill(m_ptr)
-message *m_ptr;                        /* pointer to request message */
-{
-/* Handle sys_kill(). Cause a signal to be sent to a process via PM.
- * Note that this has nothing to do with the kill (2) system call, this
- * is how the FS (and possibly other servers) get access to cause_sig. 
- */
-  cause_sig(m_ptr->SIG_PROC, m_ptr->SIG_NUMBER);
-  return(OK);
-}
-
-
diff --git a/kernel/system/sysctl.c b/kernel/system/sysctl.c
deleted file mode 100644 (file)
index 4dd97c2..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-#include "../kernel.h"
-#include "../ipc.h"
-#include "../system.h"
-#include "../protect.h"
-#include <sys/svrctl.h>
-#include "../sendmask.h"
-
-
-
-/* The system call implemented in this file:
- *   m_type:   SYS_SVRCTL
- *
- * The parameters for this system call are:
- *    m2_i1:   CTL_PROC_NR     (process number of caller)      
- *    m2_i2:   CTL_REQUEST     (request type)  
- *    m2_i3:   CTL_MM_PRIV     (privilege)
- *    m2_l1:    CTL_SEND_MASK   (new send mask to be installed)
- *    m2_l2:    CTL_PROC_TYPE   (new process type)
- *    m2_p1:   CTL_ARG_PTR     (argument pointer)
- */
-
-/* NOTE: this call will radically change! */
-
-/*===========================================================================*
- *                             do_svrctl                                    *
- *===========================================================================*/
-PUBLIC int do_svrctl(m_ptr)
-message *m_ptr;                        /* pointer to request message */
-{
-  register struct proc *rp;
-  int proc_nr, priv;
-  int request;
-  vir_bytes argp;
-
-  /* Extract message parameters. */
-  proc_nr = m_ptr->CTL_PROC_NR;
-  if (proc_nr == SELF) proc_nr = m_ptr->m_source;
-  if (! isokprocn(proc_nr)) return(EINVAL);
-
-  request = m_ptr->CTL_REQUEST;
-  priv = m_ptr->CTL_MM_PRIV;
-  argp = (vir_bytes) m_ptr->CTL_ARG_PTR;
-  rp = proc_addr(proc_nr);
-
-  /* Check if the PM privileges are super user. */
-  if (!priv || !isuserp(rp)) 
-      return(EPERM);
-
-  /* See what is requested and handle the request. */
-  switch (request) {
-  case SYSSIGNON: {
-       /* Make this process a server. The system processes should be able
-        * to communicate with this new server, so update their send masks
-        * as well.
-        */
-       /* fall through */
-  }
-  case SYSSENDMASK: {
-       rp->p_call_mask = SYSTEM_CALL_MASK;
-       rp->p_sendmask = ALLOW_ALL_MASK;
-       send_mask_allow(proc_addr(USR8139)->p_sendmask, proc_nr);
-       send_mask_allow(proc_addr(PM_PROC_NR)->p_sendmask, proc_nr);
-       send_mask_allow(proc_addr(FS_PROC_NR)->p_sendmask, proc_nr);
-       send_mask_allow(proc_addr(IS_PROC_NR)->p_sendmask, proc_nr);
-       send_mask_allow(proc_addr(CLOCK)->p_sendmask, proc_nr);
-       send_mask_allow(proc_addr(SYSTASK)->p_sendmask, proc_nr);
-       send_mask_allow(proc_addr(FXP)->p_sendmask, proc_nr);
-       return(OK); 
-  }
-  default:
-       return(EINVAL);
-  }
-}
-
-/* The system call implemented in this file:
- *   m_type:   SYS_SEGCTL
- *
- * The parameters for this system call are:
- *    m4_l3:   SEG_PHYS        (physical base address)
- *    m4_l4:   SEG_SIZE        (size of segment)
- *    m4_l1:   SEG_SELECT      (return segment selector here)
- *    m4_l2:   SEG_OFFSET      (return offset within segment here)
- *    m4_l5:   SEG_INDEX       (return index into remote memory map here)
- *
- * Author:
- *    Jorrit N. Herder <jnherder@cs.vu.nl>
- */
-
-/*===========================================================================*
- *                             do_segctl                                    *
- *===========================================================================*/
-PUBLIC int do_segctl(m_ptr)
-register message *m_ptr;       /* pointer to request message */
-{
-/* Return a segment selector and offset that can be used to reach a physical
- * address, for use by a driver doing memory I/O in the A0000 - DFFFF range.
- */
-  u16_t selector;
-  vir_bytes offset;
-  int i, index;
-  register struct proc *rp;
-  phys_bytes phys = (phys_bytes) m_ptr->SEG_PHYS;
-  vir_bytes size = (vir_bytes) m_ptr->SEG_SIZE;
-  int result;
-
-  /* First check if there is a slot available for this segment. */
-  rp = proc_addr(m_ptr->m_source);
-  index = -1;
-  for (i=0; i < NR_REMOTE_SEGS; i++) {
-       if (! rp->p_farmem[i].in_use) {
-               index = i; 
-               rp->p_farmem[i].in_use = TRUE;
-               rp->p_farmem[i].mem_phys = phys;
-               rp->p_farmem[i].mem_len = size;
-               break;
-       }
-  }
-  if (index < 0) return(ENOSPC);
-
-
-  if (! machine.protected) {
-      selector = phys / HCLICK_SIZE;
-      offset = phys % HCLICK_SIZE;
-      result = OK;
-  } else {
-      /* Check if the segment size can be recorded in bytes, that is, check
-       * if descriptor's limit field can delimited the allowed memory region
-       * precisely. This works up to 1MB. If the size is larger, 4K pages
-       * instead of bytes are used.
-       */
-      if (size < BYTE_GRAN_MAX) {
-          init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX+i], phys, size, 
-               USER_PRIVILEGE);
-          selector = ((EXTRA_LDT_INDEX+i)*0x08) | (1*0x04) | USER_PRIVILEGE;
-          offset = 0;
-          result = OK;                 
-      } else {
-          init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX+i], phys & ~0xFFFF, 0, 
-               USER_PRIVILEGE);
-          selector = ((EXTRA_LDT_INDEX+i)*0x08) | (1*0x04) | USER_PRIVILEGE;
-          offset = phys & 0xFFFF;
-          result = OK;
-      }
-  }
-
-  /* Request successfully done. Now return the result. */
-  m_ptr->SEG_INDEX = index | REMOTE_SEG;
-  m_ptr->SEG_SELECT = selector;
-  m_ptr->SEG_OFFSET = offset;
-  return(result);
-}
-
-
-/* The system call implemented in this file:
- *   m_type:   SYS_IOPENABLE
- *
- * The parameters for this system call are:
- *    m2_i2:   PROC_NR         (process to give I/O Protection Level bits)
- *
- * Author:
- *    Jorrit N. Herder <jnherder@cs.vu.nl>
- */
-
-/*===========================================================================*
- *                             do_iopenable                                 *
- *===========================================================================*/
-PUBLIC int do_iopenable(m_ptr)
-register message *m_ptr;       /* pointer to request message */
-{
-#if ENABLE_USERPRIV && ENABLE_USERIOPL
-  enable_iop(proc_addr(m_ptr->PROC_NR)); 
-  return(OK);
-#else
-  return(EPERM);
-#endif
-}
-
-
index ca2401052dd5a1f534662da4e5352791607b448e..cbd5ed6b4312e03191857facf3849536eecf32ca 100755 (executable)
@@ -32,7 +32,6 @@
 #include "kernel.h"
 #include "proc.h"
 #include "ipc.h"
-#include "sendmask.h"
 #include <minix/com.h>
 #include <ibm/int86.h>
 
@@ -61,43 +60,46 @@ PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
  * routine and stack size is also provided.
  */
 #define IDLE_F         (PREEMPTIBLE | BILLABLE)
-#define USER_F         (PREEMPTIBLE | SCHED_Q_HEAD)
-#define SYS_F                  (PREEMPTIBLE)
+#define USER_F         (PREEMPTIBLE | RDY_Q_HEAD)
+#define SYS_F                  (PREEMPTIBLE | SYS_PROC)
+#define TCB_F                  (SYS_PROC)      /* trusted computing base */
 
 #define IDLE_T         32              /* ticks */
 #define USER_T          8              /* ticks */
 #define SYS_T          16              /* ticks */
 
 PUBLIC struct system_image image[] = {
- { IDLE,    idle_task,  IDLE_F, IDLE_T,   IDLE_Q,  IDLE_S,    EMPTY_CALL_MASK, DENY_ALL_MASK,    "IDLE"    },
- { CLOCK,   clock_task, 0, SYS_T,   TASK_Q, CLOCK_S,   SYSTEM_CALL_MASK, ALLOW_ALL_MASK,   "CLOCK"   },
- { SYSTASK, sys_task,   0, SYS_T,   TASK_Q, SYSTEM_S,     SYSTEM_CALL_MASK, ALLOW_ALL_MASK,  "SYS"     },
- { HARDWARE,   0,       0, SYS_T,   TASK_Q, HARDWARE_S, EMPTY_CALL_MASK, ALLOW_ALL_MASK,"HARDW." },
- { PM_PROC_NR, 0,       0, SYS_T, 3, 0,          SYSTEM_CALL_MASK,   ALLOW_ALL_MASK,      "PM"      },
- { FS_PROC_NR, 0,       0, SYS_T, 3, 0,          SYSTEM_CALL_MASK,   ALLOW_ALL_MASK,      "FS"      },
- { IS_PROC_NR, 0,       SYS_F, SYS_T, 2, 0,           SYSTEM_CALL_MASK,  ALLOW_ALL_MASK,      "IS"      },
- { TTY, 0,              SYS_F, SYS_T, 1, 0,           SYSTEM_CALL_MASK, ALLOW_ALL_MASK,      "TTY"      },
- { MEMORY, 0,           SYS_F, SYS_T, 2, 0,           SYSTEM_CALL_MASK,  ALLOW_ALL_MASK,     "MEMORY" },
+ { IDLE,    idle_task,  IDLE_F, IDLE_T,   IDLE_Q,  IDLE_S,    EMPTY_CALL_MASK, 0,    "IDLE"    },
+ { CLOCK,   clock_task, TCB_F, SYS_T,   TASK_Q, CLOCK_S,   SYSTEM_CALL_MASK, 0,   "CLOCK"   },
+ { SYSTEM,  sys_task,   TCB_F, SYS_T,   TASK_Q, SYSTEM_S,     SYSTEM_CALL_MASK, 0,  "SYS"     },
+ { HARDWARE,   0,       0, SYS_T,   TASK_Q, HARDWARE_S, EMPTY_CALL_MASK, 0,"KERNEL" },
+ { PM_PROC_NR, 0,       TCB_F, SYS_T, 3, 0,          SYSTEM_CALL_MASK,   0,      "PM"      },
+ { FS_PROC_NR, 0,       TCB_F, SYS_T, 3, 0,          SYSTEM_CALL_MASK,   0,      "FS"      },
+ { IS_PROC_NR, 0,       SYS_F, SYS_T, 2, 0,           SYSTEM_CALL_MASK,  0,      "IS"      },
+ { TTY, 0,              SYS_F, SYS_T, 1, 0,           SYSTEM_CALL_MASK, 0,      "TTY"      },
+ { MEMORY, 0,           SYS_F, SYS_T, 2, 0,           SYSTEM_CALL_MASK,  0,     "MEMORY" },
 #if ENABLE_AT_WINI
- { AT_WINI, 0,            SYS_F, SYS_T, 2, 0,          SYSTEM_CALL_MASK, ALLOW_ALL_MASK,      "AT_WINI" },
+ { AT_WINI, 0,            SYS_F, SYS_T, 2, 0,          SYSTEM_CALL_MASK, 0,      "AT_WINI" },
 #endif
 #if ENABLE_FLOPPY
- { FLOPPY, 0,            SYS_F, SYS_T, 2, 0,           SYSTEM_CALL_MASK,  ALLOW_ALL_MASK,  "FLOPPY" },
+ { FLOPPY, 0,            SYS_F, SYS_T, 2, 0,           SYSTEM_CALL_MASK,  0,  "FLOPPY" },
 #endif
 #if ENABLE_PRINTER
- { PRINTER, 0,            SYS_F, SYS_T, 3, 0,         SYSTEM_CALL_MASK,  ALLOW_ALL_MASK,     "PRINTER" },
+ { PRINTER, 0,            SYS_F, SYS_T, 3, 0,         SYSTEM_CALL_MASK,  0,     "PRINTER" },
 #endif
 #if ENABLE_RTL8139
- { USR8139, 0,            SYS_F, SYS_T, 2, 0,           SYSTEM_CALL_MASK,  ALLOW_ALL_MASK,  "RTL8139" },
+ { USR8139, 0,            SYS_F, SYS_T, 2, 0,           SYSTEM_CALL_MASK,  0,  "RTL8139" },
 #endif
 #if ENABLE_FXP
- { FXP, 0,                SYS_F, SYS_T, 2, 0,           SYSTEM_CALL_MASK,  ALLOW_ALL_MASK,  "FXP" },
+ { FXP, 0,                SYS_F, SYS_T, 2, 0,           SYSTEM_CALL_MASK,  0,  "FXP" },
 #endif
 #if ENABLE_DPETH
- { DPETH, 0,              SYS_F, SYS_T, 2, 0,           SYSTEM_CALL_MASK,  ALLOW_ALL_MASK,  "DPETH" },
+ { DPETH, 0,              SYS_F, SYS_T, 2, 0,           SYSTEM_CALL_MASK,  0,  "DPETH" },
 #endif
- { LOG_PROC_NR, 0,     SYS_F, SYS_T, 2, 0,           SYSTEM_CALL_MASK,  ALLOW_ALL_MASK,  "LOG" },
- { INIT_PROC_NR, 0,    USER_F, USER_T, USER_Q, 0,         USER_CALL_MASK,    USER_PROC_SENDMASK,    "INIT"    },
+#if ENABLE_LOG
+ { LOG_PROC_NR, 0,     SYS_F, SYS_T, 2, 0,           SYSTEM_CALL_MASK,  0,  "LOG" },
+#endif
+ { INIT_PROC_NR, 0,    USER_F, USER_T, USER_Q, 0,         USER_CALL_MASK,    0,  "INIT"    },
 };
 
 /* Verify the size of the system image table at compile time. If the number 
@@ -105,5 +107,5 @@ PUBLIC struct system_image image[] = {
  * a compile time error. Note that no space is allocated because 'dummy' is
  * declared extern.
   */
-extern int dummy[(IMAGE_SIZE==sizeof(image)/sizeof(struct system_image))?1:-1];
+extern int dummy[(NR_BOOT_PROCS==sizeof(image)/sizeof(struct system_image))?1:-1];
 
index d2460c422acefb33047364f88f3a18461fff41bf..ffeb3cf95ef75b72f2e02286809b5ae7fae1c6ca 100755 (executable)
@@ -8,13 +8,12 @@ typedef _PROTOTYPE( void task_t, (void) );
  */
 typedef long karg_t;                   /* use largest type here */
 
-/* Process related types. 
- * A process number defines the index into the process table. With a signed
- * short we can support up to 256 user processes and more kernel tasks than
- * one can ever create.
- */ 
-typedef short proc_nr_t;               /* process table entry number */
-typedef unsigned long send_mask_t;     /* bit mask for sender */
+/* Process table and system property related types. */ 
+typedef int proc_nr_t;                 /* process table entry number */
+typedef short sys_id_t;                        /* system process index */
+typedef struct {                       /* bitmap for system indexes */
+  bitchunk_t chunk[BITMAP_CHUNKS(NR_SYS_PROCS)];
+} sys_map_t;
 
 struct system_image {
   proc_nr_t proc_nr;                   /* process number to use */
@@ -24,7 +23,7 @@ struct system_image {
   int priority;                                /* scheduling priority */
   int stksize;                         /* stack size for tasks */
   char call_mask;                      /* allowed system calls */
-  send_mask_t sendmask;                        /* send mask protection */
+  long send_mask;                      /* send mask protection */
   char proc_name[P_NAME_LEN];          /* name in process table */
 };