# define SYS_SIGNALRM 15 /* sys_signalrm(proc_nr, ticks) */
# define SYS_SYNCALRM 16 /* sys_syncalrm(proc_nr,exp_time,abs_time) */
# define SYS_FLAGALRM 17 /* sys_flagalrm(ticks, flag_ptr) */
-
+# define SYS_PHYSVCOPY 18 /* sys_physvcopy(vec_ptr, vec_size) */
# define SYS_SVRCTL 19 /* sys_svrctl(proc_nr, req, argp) */
# define SYS_SDEVIO 20 /* sys_sdevio(port, proc_nr, buf, count) */
# define SYS_SIGRETURN 21 /* sys_sigreturn(proc_nr, ctxt_ptr, flags) */
#define BIOS_SEG 0x0200 /* flags indicating BIOS memory segment */
#define NR_BIOS_SEGS 3 /* # BIOS memory regions (variable) */
-#define PHYS_SEG 0x0300 /* flag indicating entire physical memory */
+#define PHYS_SEG 0x0400 /* flag indicating entire physical memory */
/* Labels used to disable code sections for different reasons. */
#define DEAD_CODE 0 /* unused code in normal configuration */
map(SYS_VIRCOPY, do_vircopy); /* use pure virtual addressing */
map(SYS_PHYSCOPY, do_physcopy); /* use physical addressing */
map(SYS_VIRVCOPY, do_virvcopy); /* vector with copy requests */
+ map(SYS_PHYSVCOPY, do_physvcopy); /* vector with copy requests */
/* Miscellaneous. */
map(SYS_ABORT, do_abort); /* abort MINIX */
#define do_physcopy do_copy
_PROTOTYPE( int do_vcopy, (message *m_ptr) );
#define do_virvcopy do_vcopy
+#define do_physvcopy do_vcopy
_PROTOTYPE( int do_umap, (message *m_ptr) );
_PROTOTYPE( int do_unused, (message *m_ptr) ); /* miscellaneous */
_PROTOTYPE( int do_getinfo, (message *m_ptr) );
_PROTOTYPE( int do_random, (message *m_ptr) );
-_PROTOTYPE( int do_exit, (message *m_ptr) ); /* server control */
+_PROTOTYPE( int do_exit, (message *m_ptr) ); /* system control */
_PROTOTYPE( int do_svrctl, (message *m_ptr) );
_PROTOTYPE( int do_kmalloc, (message *m_ptr) );
_PROTOTYPE( int do_iopenable, (message *m_ptr) );
_PROTOTYPE( int do_segctl, (message *m_ptr) );
-_PROTOTYPE( int do_devio, (message *m_ptr) ); /* device I/O */
+_PROTOTYPE( int do_irqctl, (message *m_ptr) ); /* device I/O */
+_PROTOTYPE( int do_devio, (message *m_ptr) );
_PROTOTYPE( int do_vdevio, (message *m_ptr) );
_PROTOTYPE( int do_sdevio, (message *m_ptr) );
-_PROTOTYPE( int do_irqctl, (message *m_ptr) ); /* interrupt control */
-
_PROTOTYPE( int do_kill, (message *m_ptr) ); /* signal handling */
_PROTOTYPE( int do_getsig, (message *m_ptr) );
_PROTOTYPE( int do_endsig, (message *m_ptr) );
}
/* Check if physical addressing is used without SYS_PHYSCOPY. */
- if ((vir_addr[i].segment & SEGMENT_TYPE) == PHYS_SEG &&
+ if ((vir_addr[i].segment & PHYS_SEG) &&
m_ptr->m_type != SYS_PHYSCOPY) return(EPERM);
}
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;
/* Assume vector with requests is correct. Try to copy everything. */
for (i=0; i<nr_req; i++) {
- s = virtual_copy(&vir_cp_req[i].src, &vir_cp_req[i].dst,
- vir_cp_req[i].count);
- if (s != OK) break;
+
+ 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(s);
+ return(OK);
}
switch(m_ptr->IRQ_REQUEST) {
/* Enable or disable IRQs. This is straightforward. */
- case IRQ_ENABLE: {
+ case IRQ_ENABLE:
+ case IRQ_DISABLE:
irq_hook_id = (unsigned) m_ptr->IRQ_HOOK_ID;
if (irq_hook_id >= NR_IRQ_HOOKS) return(EINVAL);
- enable_irq(&irq_hooks[irq_hook_id]);
+ if (irq_hooks[irq_hook_id].proc_nr != m_ptr->m_source) return(EPERM);
+ if (m_ptr->IRQ_REQUEST == IRQ_ENABLE)
+ enable_irq(&irq_hooks[irq_hook_id]);
+ else
+ disable_irq(&irq_hooks[irq_hook_id]);
break;
- }
- case IRQ_DISABLE: {
- irq_hook_id = (unsigned) m_ptr->IRQ_HOOK_ID;
- if (irq_hook_id >= NR_IRQ_HOOKS) return(EINVAL);
- disable_irq(&irq_hooks[irq_hook_id]);
- break;
- }
+
/* Control IRQ policies. Set a policy and needed details in the IRQ table.
* This policy is used by a generic function to handle hardware interrupts.
*/
- case IRQ_SETPOLICY: {
+ case IRQ_SETPOLICY:
/* Check if IRQ line is acceptable. */
irq_vec = (unsigned) m_ptr->IRQ_VECTOR;
/* Return index of the IRQ hook in use. */
m_ptr->IRQ_HOOK_ID = irq_hook_id;
break;
- }
+
default:
return(EINVAL); /* invalid IRQ_REQUEST */
}
+++ /dev/null
-/* 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)
- */
-
-#include "../kernel.h"
-#include "../system.h"
-#include <unistd.h>
-INIT_ASSERT
-
-/*===========================================================================*
- * 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
- * MM (normal abort or panic) or FS (panic), or TTY (a CTRL-ALT-DEL or ESC
- * after debugging dumps).
- */
- register struct proc *rp;
- phys_bytes src_phys;
- vir_bytes len;
- int how = m_ptr->ABRT_HOW;
-
- rp = proc_addr(m_ptr->m_source);
-
- if (how == RBT_MONITOR) {
- /* The monitor is to run user specified instructions. */
- len = m_ptr->ABRT_MON_LEN + 1;
- assert(len <= mon_parmsize);
- src_phys = numap_local(m_ptr->ABRT_MON_PROC,
- (vir_bytes) m_ptr->ABRT_MON_ADDR, len);
- assert(src_phys != 0);
- phys_copy(src_phys, mon_params, (phys_bytes) len);
- }
- prepare_shutdown(how);
- return(OK); /* pro-forma (really EDISASTER) */
-}
-
+++ /dev/null
-/* The system call implemented in this file:
- * m_type: SYS_ENDSIG
- *
- * The parameters for this system call are:
- * m2_i1: SIG_PROC (process that was signaled)
- */
-
-#include "../kernel.h"
-#include "../system.h"
-INIT_ASSERT
-
-/*===========================================================================*
- * do_endsig *
- *===========================================================================*/
-PUBLIC int do_endsig(m_ptr)
-register message *m_ptr; /* pointer to request message */
-{
-/* Finish up after a KSIG-type signal, caused by a SYS_KILL message or a call
- * to cause_sig by a task
- */
-
- register struct proc *rp;
-
- rp = proc_addr(m_ptr->SIG_PROC);
- if (isemptyp(rp)) return(EINVAL); /* process already dead? */
- assert(isuserp(rp));
-
- /* MM has finished one KSIG. */
- if (rp->p_pendcount != 0 && --rp->p_pendcount == 0
- && (rp->p_flags &= ~SIG_PENDING) == 0)
- lock_ready(rp);
- return(OK);
-}
-
+++ /dev/null
-/* 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 "../kernel.h"
-#include "../system.h"
-#include <signal.h>
-#if (CHIP == INTEL)
-#include "../protect.h"
-#endif
-INIT_ASSERT
-
-/*===========================================================================*
- * 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;
-#define NLEN (sizeof(rp->p_name)-1)
-
- rp = proc_addr(m_ptr->PR_PROC_NR);
- assert(isuserp(rp));
- 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 */
- memset(&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_flags &= ~RECEIVING; /* MM does not reply to EXEC call */
- if (rp->p_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) NLEN);
- if (phys_name != 0) {
- phys_copy(phys_name, vir2phys(rp->p_name), (phys_bytes) NLEN);
- for (np = rp->p_name; (*np & BYTE) >= ' '; np++) {}
- *np = 0;
- }
- return(OK);
-}
-
-
+++ /dev/null
-/* The system call implemented in this file:
- * m_type: SYS_EXIT
- *
- * The parameters for this system call are:
- * m1_i1: EXIT_STATUS (exit status, 0 if normal exit)
- *
- * Author:
- * Jorrit N. Herder <jnherder@cs.vu.nl>
- */
-
-#include "../kernel.h"
-#include "../system.h"
-
-/*===========================================================================*
- * do_exit *
- *===========================================================================*/
-PUBLIC int do_exit(m_ptr)
-message *m_ptr; /* pointer to request message */
-{
-/* Handle sys_exit. A server or driver wants to exit. This may happen
- * on a panic, but also is done when MINIX is shutdown.
- */
- register struct proc *rp;
- int proc_nr = m_ptr->m_source; /* can only exit own process */
-
- if (m_ptr->EXIT_STATUS != 0) {
- kprintf("WARNING: system process %d exited with an error.\n", proc_nr );
- }
-
- /* Now call the routine to clean up of the process table slot. This cancels
- * outstanding timers, possibly removes the process from the message queues,
- * and reset important process table fields.
- */
- clear_proc(proc_nr);
-
- /* If the shutdown sequence is active, see if it was awaiting the shutdown
- * of this system service. If so, directly continue the stop sequence.
- */
- if (shutting_down && shutdown_process == proc_addr(proc_nr)) {
- stop_sequence(&shutdown_timer);
- }
- return(EDONTREPLY); /* no reply is sent */
-}
-
-
+++ /dev/null
-/* 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 MM)
- */
-
-#include "../kernel.h"
-#include "../system.h"
-#include <signal.h>
-#include "../sendmask.h"
-INIT_ASSERT
-
-/*===========================================================================*
- * 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);
- assert(isuserp(rpp));
- rpc = proc_addr(m_ptr->PR_PROC_NR);
- assert(isemptyp(rpc));
-
- /* 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_flags |= NO_MAP; /* inhibit the process from running */
-
- rpc->p_flags &= ~(PENDING | SIG_PENDING | P_STOP);
-
- /* Only 1 in group should have PENDING, child does not inherit trace status*/
- sigemptyset(&rpc->p_pending);
- rpc->p_pendcount = 0;
- rpc->p_reg.retreg = 0; /* child sees pid = 0 to know it is child */
-
- rpc->user_time = 0; /* set all the accounting times to 0 */
- rpc->sys_time = 0;
- rpc->child_utime = 0;
- rpc->child_stime = 0;
-
- return(OK);
-}
-
-
+++ /dev/null
-/* The system call implemented in this file:
- * m_type: SYS_GETINFO
- *
- * The parameters for this system call are:
- * m1_i3: I_REQUEST (what info to get)
- * m1_i4: I_PROC_NR (process to store value at)
- * m1_p1: I_VAL_PTR (where to put it)
- * m1_i1: I_VAL_LEN (maximum length expected, optional)
- * m1_p2: I_KEY_PTR (environment variable key)
- * m1_i2: I_KEY_LEN (lenght of environment variable key)
- *
- * Author:
- * Jorrit N. Herder <jnherder@cs.vu.nl>
- */
-
-
-#include "../kernel.h"
-#include "../system.h"
-
-
-/*===========================================================================*
- * do_getinfo *
- *===========================================================================*/
-PUBLIC int do_getinfo(m_ptr)
-register message *m_ptr; /* pointer to request message */
-{
-/* Request system information to be copied to caller's address space. */
- size_t length;
- phys_bytes src_phys;
- phys_bytes dst_phys;
- int proc_nr;
-
- /* First get the process number and verify it. */
- proc_nr = (m_ptr->I_PROC_NR == SELF) ? m_ptr->m_source : m_ptr->I_PROC_NR;
- if (! isokprocn(proc_nr)) {
- printf("Invalid process number: %d from %d\n", proc_nr, m_ptr->m_source);
- return(EINVAL);
- }
-
- /* Set source address and length based on request type. */
- switch (m_ptr->I_REQUEST) {
- case GET_KENVIRON: {
- struct kenviron kenv;
- extern int end;
- kenv.pc_at = pc_at; kenv.ps_mca = ps_mca;
- kenv.processor = processor; kenv.protected = protected_mode;
- kenv.ega = ega; kenv.vga = vga;
- kenv.proc_addr = (vir_bytes) proc;
- kenv.kmem_start = vir2phys(0);
- kenv.kmem_end = vir2phys(&end);
- length = sizeof(struct kenviron);
- src_phys = vir2phys(&kenv);
- break;
- }
- case GET_IMAGE: {
- length = sizeof(struct system_image) * IMAGE_SIZE;
- src_phys = vir2phys(image);
- break;
- }
- case GET_IRQTAB: {
- length = sizeof(struct irqtab) * NR_IRQ_VECTORS;
- src_phys = vir2phys(irqtab);
- break;
- }
- case GET_MEMCHUNKS: {
- length = sizeof(struct memory) * NR_MEMS;
- src_phys = vir2phys(mem);
- break;
- }
- case GET_SCHEDINFO: {
- /* This is slightly complicated because we need several variables
- * at once, otherwise the scheduling information may be incorrect.
- */
- length = sizeof(struct proc *) * NR_SCHED_QUEUES;
- src_phys = vir2phys(rdy_head);
- dst_phys = numap_local(m_ptr->m_source, (vir_bytes) m_ptr->I_KEY_PTR,
- length);
- if (src_phys == 0 || dst_phys == 0) return(EFAULT);
- phys_copy(src_phys, dst_phys, length);
- /* Fall through to also get a copy of the process table. */
- }
- case GET_PROCTAB: {
- length = sizeof(struct proc) * (NR_PROCS + NR_TASKS);
- src_phys = vir2phys(proc);
- break;
- }
- case GET_PROC: {
- if (! isokprocn(m_ptr->I_KEY_LEN)) return(EINVAL);
- length = sizeof(struct proc);
- src_phys = vir2phys(proc_addr(m_ptr->I_KEY_LEN));
- break;
- }
- case GET_MONPARAMS: {
- src_phys = mon_params; /* already is a physical address! */
- length = mon_parmsize;
- break;
- }
- case GET_KENV: { /* get one string by name */
- char key[32]; /* boot variable key provided by caller */
- char *val; /* pointer to actual boot variable value */
- if (m_ptr->I_KEY_LEN > sizeof(key)) return(EINVAL);
- if (vir_copy(proc_nr, (vir_bytes) m_ptr->I_KEY_PTR,
- SYSTASK, (vir_bytes) key, m_ptr->I_KEY_LEN) != OK) return(EFAULT);
- if ((val=getkenv(key)) == NULL) return(ESRCH);
- length = strlen(val) + 1;
- src_phys = vir2phys(val);
- break;
- }
- case GET_PROCNR: {
- length = sizeof(int);
- if (m_ptr->I_KEY_LEN == 0) { /* get own process nr */
- src_phys = vir2phys(&proc_nr);
- } else { /* lookup nr by name */
- int proc_found = FALSE;
- struct proc *pp;
- char key[8]; /* storage for process name to lookup */
- if (m_ptr->I_KEY_LEN > sizeof(key)) return(EINVAL);
- if (vir_copy(proc_nr, (vir_bytes) m_ptr->I_KEY_PTR, SYSTASK,
- (vir_bytes) key, m_ptr->I_KEY_LEN) != OK) return(EFAULT);
- for (pp= BEG_PROC_ADDR; pp<END_PROC_ADDR; pp++) {
- if (strncmp(pp->p_name, key, m_ptr->I_KEY_LEN) == 0) {
- src_phys = vir2phys(&(pp->p_nr));
- proc_found = TRUE;
- break;
- }
- }
- if (! proc_found) return(ESRCH);
- }
- break;
- }
- case GET_KMESSAGES: {
- length = sizeof(struct kmessages);
- src_phys = vir2phys(&kmess);
- break;
- }
- default:
- return(EINVAL);
- }
-
- /* Try to make the actual copy for the requested data. */
- if (m_ptr->I_VAL_LEN > 0 && length > m_ptr->I_VAL_LEN) return (E2BIG);
- dst_phys = numap_local(proc_nr, (vir_bytes) m_ptr->I_VAL_PTR, length);
- if (src_phys == 0 || dst_phys == 0) return(EFAULT);
- phys_copy(src_phys, dst_phys, length);
- return(OK);
-}
-
-
+++ /dev/null
-/* The system call implemented in this file:
- * m_type: SYS_GETMAP
- *
- * The parameters for this system call are:
- * m1_i1: PR_PROC_NR (process to get map of)
- * m1_p1: PR_MEM_PTR (copy the memory map here)
- */
-
-#include "../kernel.h"
-#include "../system.h"
-INIT_ASSERT
-
-/*===========================================================================*
- * do_getmap *
- *===========================================================================*/
-PUBLIC int do_getmap(m_ptr)
-message *m_ptr; /* pointer to request message */
-{
-/* Handle sys_getmap(). Report the memory map to MM. */
-
- register struct proc *rp;
- phys_bytes dst_phys;
- int caller; /* where the map has to be stored */
- int k; /* process whose map is to be loaded */
- struct mem_map *map_ptr; /* virtual address of map inside caller (MM) */
-
- /* Extract message parameters and copy new memory map to MM. */
- caller = m_ptr->m_source;
- k = m_ptr->PR_PROC_NR;
- map_ptr = (struct mem_map *) m_ptr->PR_MEM_PTR;
-
- assert(isokprocn(k)); /* unlikely: MM sends a bad proc nr. */
-
- rp = proc_addr(k); /* ptr to entry of the map */
-
- /* Copy the map to MM. */
- dst_phys = umap_local(proc_addr(caller), D, (vir_bytes) map_ptr, sizeof(rp->p_map));
- assert(dst_phys != 0);
- phys_copy(vir2phys(rp->p_map), dst_phys, sizeof(rp->p_map));
-
- return(OK);
-}
-
-
+++ /dev/null
-/* The system call implemented in this file:
- * m_type: SYS_GETSIG
- *
- * The parameters for this system call are:
- * m2_i1: SIG_PROC (return proc nr or NONE here)
- * m2_l1: SIG_MAP (return signal map here)
- */
-
-#include "../kernel.h"
-#include "../system.h"
-#include <signal.h>
-
-
-
-/*===========================================================================*
- * do_getsig *
- *===========================================================================*/
-PUBLIC int do_getsig(m_ptr)
-message *m_ptr; /* pointer to the request message */
-{
-/* MM is ready to accept signals and repeatedly does a system call to get one
- * Find a process with pending signals. If no more signals are available,
- * return NONE in the process number field.
- */
- register struct proc *rp;
-
- /* Only the MM is allowed to request pending signals. */
- if (m_ptr->m_source != PM_PROC_NR)
- return(EPERM);
-
- /* Find the next process with pending signals. */
- for (rp = BEG_SERV_ADDR; rp < END_PROC_ADDR; rp++) {
- if (rp->p_flags & PENDING) {
- m_ptr->SIG_PROC = proc_number(rp);
- m_ptr->SIG_MAP = rp->p_pending;
- sigemptyset(&rp->p_pending); /* the ball is now in MM's court */
- rp->p_flags &= ~PENDING; /* remains inhibited by SIG_PENDING */
- return(OK);
- }
- }
-
- /* No process with pending signals was found. */
- m_ptr->SIG_PROC = NONE;
- return(OK);
-}
-
+++ /dev/null
-/* The system call implemented in this file:
- * m_type: SYS_GETSP
- *
- * The parameters for this system call are:
- * m1_i1: PR_PROC_NR (process to get stack pointer of)
- * m1_p1: PR_STACK_PTR (return stack pointer here)
- *
- * Author:
- * Jorrit N. Herder <jnherder@cs.vu.nl>
- */
-
-#include "../kernel.h"
-#include "../system.h"
-INIT_ASSERT
-
-/*===========================================================================*
- * do_getsp *
- *===========================================================================*/
-PUBLIC int do_getsp(m_ptr)
-register message *m_ptr; /* pointer to request message */
-{
-/* Handle sys_getsp(). MM wants to know what sp is. */
-
- register struct proc *rp;
-
- rp = proc_addr(m_ptr->PR_PROC_NR);
- assert(isuserp(rp));
- m_ptr->PR_STACK_PTR = (char *) rp->p_reg.sp; /* return sp here (bad type) */
- return(OK);
-}
-
-
+++ /dev/null
-/* 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>
- */
-
-#include "../kernel.h"
-#include "../system.h"
-
-/*===========================================================================*
- * 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
-}
-
-
+++ /dev/null
-#include "../kernel.h"
-#include "../system.h"
-
-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 MM.
- * 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);
-}
-
-
+++ /dev/null
-/* The system call implemented in this file:
- * m_type: SYS_KMALLOC
- *
- * The parameters for this system call are:
- * m4_l2: MEM_CHUNK_SIZE (request a buffer of this size)
- * m4_l1: MEM_CHUNK_BASE (return physical address on success)
- *
- * Author:
- * Jorrit N. Herder <jnherder@cs.vu.nl>
- */
-
-#include "../kernel.h"
-#include "../system.h"
-
-/*===========================================================================*
- * do_kmalloc *
- *===========================================================================*/
-PUBLIC int do_kmalloc(m_ptr)
-register message *m_ptr; /* pointer to request message */
-{
-/* Request a (DMA) buffer to be allocated in one of the memory chunks. */
- phys_clicks tot_clicks;
- struct memory *memp;
-
- tot_clicks = (m_ptr->MEM_CHUNK_SIZE + CLICK_SIZE-1) >> CLICK_SHIFT;
- memp = &mem[NR_MEMS];
- while ((--memp)->size < tot_clicks) {
- if (memp == mem) {
- return(ENOMEM);
- }
- }
- memp->size -= tot_clicks;
- m_ptr->MEM_CHUNK_BASE = (memp->base + memp->size) << CLICK_SHIFT;
- return(OK);
-}
-
+++ /dev/null
-/* The system call implemented in this file:
- * m_type: SYS_MEM
- *
- * The parameters for this system call are:
- * m4_l1: MEM_CHUNK_BASE (memory base)
- * m4_l2: MEM_CHUNK_SIZE (memory size)
- * m4_l3: MEM_TOT_SIZE (total memory)
- */
-
-#include "../kernel.h"
-#include "../system.h"
-
-/*===========================================================================*
- * do_mem *
- *===========================================================================*/
-PUBLIC int do_mem(m_ptr)
-register message *m_ptr; /* pointer to request message */
-{
-/* Return the base and size of the next chunk of memory. */
-
- struct memory *memp;
-
- for (memp = mem; memp < &mem[NR_MEMS]; ++memp) {
- m_ptr->MEM_CHUNK_BASE = memp->base;
- m_ptr->MEM_CHUNK_SIZE = memp->size;
- m_ptr->MEM_TOT_SIZE = tot_mem_size;
- memp->size = 0;
- if (m_ptr->MEM_CHUNK_SIZE != 0) break; /* found a chunk */
- }
- return(OK);
-}
-
-
+++ /dev/null
-/* 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 "../kernel.h"
-#include "../system.h"
-INIT_ASSERT
-
-/*===========================================================================*
- * do_newmap *
- *===========================================================================*/
-PUBLIC int do_newmap(m_ptr)
-message *m_ptr; /* pointer to request message */
-{
-/* Handle sys_newmap(). Fetch the memory map from MM. */
-
- register struct proc *rp;
- phys_bytes src_phys;
- int caller; /* whose space has the new map (usually MM) */
- 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 (MM) */
-
- /* Extract message parameters and copy new memory map from MM. */
- 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 MM. */
- src_phys = umap_local(proc_addr(caller), D, (vir_bytes) map_ptr, sizeof(rp->p_map));
- assert(src_phys != 0);
- phys_copy(src_phys, vir2phys(rp->p_map), (phys_bytes) sizeof(rp->p_map));
-
-#if (CHIP != M68000)
- alloc_segments(rp);
-#else
- pmmu_init_proc(rp);
-#endif
- old_flags = rp->p_flags; /* save the previous value of the flags */
- rp->p_flags &= ~NO_MAP;
- if (old_flags != 0 && rp->p_flags == 0) lock_ready(rp);
-
- return(OK);
-}
-
-
+++ /dev/null
-/* The system call implemented in this file:
- * m_type: SYS_PHYS2SEG
- *
- * The parameters for this system call are:
- * m4_l1: SEG_SELECT (return segment selector here)
- * m4_l2: SEG_OFFSET (return offset within segment here)
- * m4_l3: SEG_PHYS (physical address to convert)
- * m4_l4: SEG_SIZE (size of segment)
- *
- * Author:
- * Jorrit N. Herder <jnherder@cs.vu.nl>
- */
-
-#include "../kernel.h"
-#include "../system.h"
-#include "../protect.h"
-
-
-/*===========================================================================*
- * do_phys2seg *
- *===========================================================================*/
-PUBLIC int do_phys2seg(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;
- register struct proc *rp;
- phys_bytes phys = (phys_bytes) m_ptr->SEG_PHYS;
- vir_bytes size = (vir_bytes) m_ptr->SEG_SIZE;
- int result;
-
-#if 0
- kprintf("FLAT DS SELECTOR used\n", NO_ARG);
- selector = FLAT_DS_SELECTOR;
- offset = phys;
-#else
- kprintf("Using Experimental LDT selector for video memory\n", NO_ARG);
-
- if (!protected_mode) {
- 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) {
- rp = proc_addr(m_ptr->m_source);
- init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX], phys, size,
- USER_PRIVILEGE);
- selector = (EXTRA_LDT_INDEX * 0x08) | (1 * 0x04) | USER_PRIVILEGE;
- offset = 0;
- result = OK;
- } else {
-#if ENABLE_USERPRIV && ENABLE_LOOSELDT
- rp = proc_addr(m_ptr->m_source);
- init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX], phys & ~0xFFFF, 0,
- USER_PRIVILEGE);
- selector = (EXTRA_LDT_INDEX * 0x08) | (1 * 0x04) | USER_PRIVILEGE;
- offset = phys & 0xFFFF;
- result = OK;
-#else
- result = E2BIG; /* allow settings only */
-#endif
- }
- }
-#endif
-
-#if 0
- kprintf("do_phys2seg: proc %d", m_ptr->m_source);
- kprintf(" phys %u", phys);
- kprintf(" size %u", size);
- kprintf(" sel %u", selector);
- kprintf(" off %u\n", offset);
-#endif
- m_ptr->SEG_SELECT = selector;
- m_ptr->SEG_OFFSET = offset;
- return(result);
-}
-
-
+++ /dev/null
-/* The system call implemented in this file:
- * m_type: SYS_PHYSCOPY
- *
- * The parameters for this system call are:
- * m5_l1: CP_SRC_ADDR (physical source address)
- * m5_l2: CP_DST_ADDR (physical destination address)
- * m5_l3: CP_NR_BYTES (number of bytes to copy)
- *
- * Author:
- * Jorrit N. Herder <jnherder@cs.vu.nl>
- */
-
-#include "../kernel.h"
-#include "../system.h"
-
-/*===========================================================================*
- * do_physcopy *
- *===========================================================================*/
-PUBLIC int do_physcopy(m_ptr)
-register message *m_ptr; /* pointer to request message */
-{
-/* Handle sys_physcopy(). Copy data by using physical addressing. */
-
- phys_bytes src_phys, dst_phys, bytes;
-
- /* Dismember the command message. */
- src_phys = (phys_bytes) m_ptr->CP_SRC_ADDR;
- dst_phys = (phys_bytes) m_ptr->CP_DST_ADDR;
- bytes = (phys_bytes) m_ptr->CP_NR_BYTES;
-
- /* Do some checks and copy the data. */
- if (src_phys == 0 || dst_phys == 0) return(EFAULT);
- phys_copy(src_phys, dst_phys, bytes);
- return(OK);
-}
-
-
+++ /dev/null
-/* 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)
- *
- * Author:
- * Jorrit N. Herder <jnherder@cs.vu.nl>
- */
-
-#include "../kernel.h"
-#include "../system.h"
-#include <minix/devio.h>
-
-/*===========================================================================*
- * 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);
-}
-
-
+++ /dev/null
-/* The system call implemented in this file:
- * m_type: SYS_SIGRETURN
- *
- * The parameters for this system call are:
- * m2_i1: SIG_PROC (process number)
- * m2_i3: SIG_FLAGS (sig return flags) (unused)
- * m2_p1: SIG_CTXT_PTR (pointer to sigcontext structure)
- */
-
-#include "../kernel.h"
-#include "../system.h"
-#include <signal.h>
-#include <sys/sigcontext.h>
-INIT_ASSERT
-
-/*===========================================================================*
- * do_sigreturn *
- *===========================================================================*/
-PUBLIC int do_sigreturn(m_ptr)
-register message *m_ptr;
-{
-/* 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);
- if (! isuserp(rp))
- printf("message source: %d; rp: %d\n", m_ptr->m_source, rp->p_nr);
- assert(isuserp(rp));
-
- /* 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. */
- memcpy(&rp->p_reg, (char *)&sc.sc_regs, sizeof(struct sigregs));
-
- return(OK);
-}
-
+++ /dev/null
-/* 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 "../kernel.h"
-#include "../system.h"
-#include <sys/svrctl.h>
-#include "../sendmask.h"
-
-/*===========================================================================*
- * 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 MM 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_type = P_SERVER;
- rp->p_sendmask = ALLOW_ALL_MASK;
- send_mask_allow(proc_addr(RTL8139)->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);
- return(OK);
- }
- default:
- return(EINVAL);
- }
-}
-
+++ /dev/null
-/* 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 "../kernel.h"
-#include "../system.h"
-
-/*==========================================================================*
- * do_umap *
- *==========================================================================*/
-PUBLIC int do_umap(m_ptr)
-register message *m_ptr; /* pointer to request message */
-{
-/* Same as umap_local(), for non-kernel processes. */
- int proc_nr = (int) m_ptr->CP_SRC_PROC_NR;
- if (proc_nr == SELF) proc_nr = m_ptr->m_source;
- if (! isokprocn(proc_nr)) return(EINVAL);
-
- m_ptr->CP_DST_ADDR = umap_local(proc_addr(proc_nr),
- (int) m_ptr->CP_SRC_SPACE,
- (vir_bytes) m_ptr->CP_SRC_ADDR,
- (vir_bytes) m_ptr->CP_NR_BYTES);
- return(OK);
-}
-
-
+++ /dev/null
-/* 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)
- *
- * Author:
- * Jorrit N. Herder <jnherder@cs.vu.nl>
- */
-
-#include "../kernel.h"
-#include "../system.h"
-#include <minix/devio.h>
-
-/* Buffer for SYS_VDEVIO to copy (port,value)-pairs from/ to user. */
-PRIVATE char vdevio_pv_buf[VDEVIO_BUF_SIZE];
-
-/* SYS_VDEVIO sends a pointer to a (port,value)-pairs vector at the caller.
- * Define the maximum number of (port,value)-pairs that can be handled in a
- * in a single SYS_VDEVIO system call based on the struct definitions.
- */
-#define MAX_PVB_PAIRS ((VDEVIO_BUF_SIZE * sizeof(char)) / sizeof(pvb_pair_t))
-#define MAX_PVW_PAIRS ((VDEVIO_BUF_SIZE * sizeof(char)) / sizeof(pvw_pair_t))
-#define MAX_PVL_PAIRS ((VDEVIO_BUF_SIZE * sizeof(char)) / sizeof(pvl_pair_t))
-
-
-/*===========================================================================*
- * do_vdevio *
- *===========================================================================*/
-PUBLIC int do_vdevio(m_ptr)
-register message *m_ptr; /* pointer to request message */
-{
-/* Perform a series of device I/O on behalf of a non-kernel process. The
- * I/O addresses and I/O values are fetched from and returned to some buffer
- * in user space. The actual I/O is wrapped by lock() and unlock() to prevent
- * that I/O batch from being interrrupted.
- * This is the counterpart of do_devio, which performs a single device I/O.
- */
- pvb_pair_t *pvb_pairs; /* needed for byte values */
- pvw_pair_t *pvw_pairs; /* needed for word values */
- pvl_pair_t *pvl_pairs; /* needed for long values */
- int i;
- pid_t caller_pid; /* process id of caller */
- size_t bytes; /* # bytes to be copied */
- vir_bytes caller_vir; /* virtual address at caller */
- phys_bytes caller_phys; /* physical address at caller */
- phys_bytes kernel_phys; /* physical address in kernel */
-
-
- /* Check if nr of ports is ok and get size of (port,value) data. */
- if (m_ptr->DIO_VEC_SIZE <= 0) return(EINVAL);
- switch(m_ptr->DIO_TYPE) {
- case DIO_BYTE:
- if (m_ptr->DIO_VEC_SIZE > MAX_PVB_PAIRS) return(EINVAL);
- bytes = (size_t) (m_ptr->DIO_VEC_SIZE * sizeof(pvb_pair_t));
- break;
- case DIO_WORD:
- if (m_ptr->DIO_VEC_SIZE > MAX_PVW_PAIRS) return(EINVAL);
- bytes = (size_t) (m_ptr->DIO_VEC_SIZE * sizeof(pvw_pair_t));
- break;
- case DIO_LONG:
- if (m_ptr->DIO_VEC_SIZE > MAX_PVL_PAIRS) return(EINVAL);
- bytes = (size_t) (m_ptr->DIO_VEC_SIZE * sizeof(pvl_pair_t));
- break;
- default: /* this once and for all checks for a correct type */
- return(EINVAL);
- }
-
- /* Calculate physical addresses and copy (port,value)-pairs from user. */
- caller_pid = (pid_t) m_ptr->m_source;
- caller_vir = (vir_bytes) m_ptr->DIO_VEC_ADDR;
- caller_phys = umap_local(proc_addr(caller_pid), D, caller_vir, bytes);
- if (0 == caller_phys) return EFAULT;
- kernel_phys = vir2phys(vdevio_pv_buf);
- phys_copy(caller_phys, kernel_phys, (phys_bytes) bytes);
-
- /* Perform actual device I/O for byte, word, and long values. Note that
- * the entire switch is wrapped in lock() and unlock() to prevent the I/O
- * batch from being interrupted. It may be cleaner to do this just around
- * the for loops, but this results in rather lenghty code.
- */
- lock();
- switch (m_ptr->DIO_TYPE) {
- case DIO_BYTE: /* byte values */
- pvb_pairs = (pvb_pair_t *) vdevio_pv_buf;
- if (DIO_INPUT == m_ptr->DIO_REQUEST) {
- for (i=0; i < m_ptr->DIO_VEC_SIZE; i++)
- pvb_pairs[i].value = inb(pvb_pairs[i].port);
- } else {
- for (i=0; i < m_ptr->DIO_VEC_SIZE; i++)
- outb(pvb_pairs[i].port, pvb_pairs[i].value);
- }
- break;
- case DIO_WORD: /* word values */
- pvw_pairs = (pvw_pair_t *) vdevio_pv_buf;
- if (DIO_INPUT == m_ptr->DIO_REQUEST) {
- for (i=0; i < m_ptr->DIO_VEC_SIZE; i++)
- pvw_pairs[i].value = inw(pvw_pairs[i].port);
- } else {
- for (i=0; i < m_ptr->DIO_VEC_SIZE; i++)
- outw(pvw_pairs[i].port, pvw_pairs[i].value);
- }
- break;
- case DIO_LONG: /* fall through: long values */
- default: /* only DIO_LONG can arrive here, see above switch */
- pvl_pairs = (pvl_pair_t *) vdevio_pv_buf;
- if (DIO_INPUT == m_ptr->DIO_REQUEST) {
- for (i=0; i < m_ptr->DIO_VEC_SIZE; i++)
- pvl_pairs[i].value = inl(pvl_pairs[i].port);
- } else {
- for (i=0; i < m_ptr->DIO_VEC_SIZE; i++)
- outl(pvb_pairs[i].port, pvl_pairs[i].value);
- }
- }
- unlock();
-
- /* Almost done, copy back results for input requests. */
- if (DIO_INPUT == m_ptr->REQUEST)
- phys_copy(kernel_phys, caller_phys, (phys_bytes) bytes);
- return(OK);
-}
-
-
+++ /dev/null
-/* The system call implemented in this file:
- * m_type: SYS_VIRCOPY
- *
- * 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"
-
-/*===========================================================================*
- * do_vircopy *
- *===========================================================================*/
-PUBLIC int do_vircopy(m_ptr)
-register message *m_ptr; /* pointer to request message */
-{
-/* Handle sys_vircopy(). Copy data by using virtual 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)) {
- kprintf("do_vircopy: illegal proc nr\n",NO_ARG);
- return(EINVAL);
- }
-
- /* Copying from or to special segments can only done by the owner. */
- if ((vir_addr[i].segment & SEGMENT_TYPE) != LOCAL_SEG &&
- vir_addr[i].proc_nr != m_ptr->m_source) {
- kprintf("do_vircopy: special seg permission denied\n", NO_ARG);
- return(EPERM);
- }
- }
-
- /* Check for overflow. This would happen for 64K segments and 16-bit
- * vir_bytes. Especially copying by the MM on do_fork() is affected.
- */
- if (bytes != (vir_bytes) bytes) {
- kprintf("do_vircopy: overflow\n", NO_ARG);
- return(E2BIG);
- }
-
- /* Now try to make the actual virtual copy. */
- return( virtual_copy(&vir_addr[_SRC_], &vir_addr[_DST_], bytes) );
-}
-
-
+++ /dev/null
-/*===========================================================================*
- * do_xit *
- *===========================================================================*/
-PUBLIC int do_xit(m_ptr)
-message *m_ptr; /* pointer to request message */
-{
-/* Handle sys_exit. A user process has exited (the MM sent the request).
- */
- register struct proc *rp, *rc;
- struct proc *np, *xp;
- int exit_proc_nr;
-
- /* Get a pointer to the process that exited. */
- exit_proc_nr = m_ptr->PR_PROC_NR;
- if (exit_proc_nr == SELF) exit_proc_nr = m_ptr->m_source;
- if (! isokprocn(exit_proc_nr)) return(EINVAL);
- rc = proc_addr(exit_proc_nr);
-
- /* If this is a user process and the MM passed in a valid parent process,
- * accumulate the child times at the parent.
- */
- if (isuserp(rc) && isokprocn(m_ptr->PR_PPROC_NR)) {
- rp = proc_addr(m_ptr->PR_PPROC_NR);
- lock();
- rp->child_utime += rc->user_time + rc->child_utime;
- rp->child_stime += rc->sys_time + rc->child_stime;
- unlock();
- }
-
- /* Now call the routine to clean up of the process table slot. This cancels
- * outstanding timers, possibly removes the process from the message queues,
- * and resets important process table fields.
- */
- clear_proc(exit_proc_nr);
- return(OK); /* tell MM that cleanup succeeded */
-}
-
-
struct system_image image[IMAGE_SIZE];
-
/*===========================================================================*
* handle_fkey *
*===========================================================================*/
PRIVATE void irqtab_dmp()
{
int i,j,r;
- struct irq_hook irqhooks[NR_IRQ_HOOKS];
+ struct irq_hook irq_hooks[NR_IRQ_HOOKS];
struct irq_hook *e; /* irq tab entry */
- int p; /* policy */
char *irq[] = {
"clock", /* 00 */
"keyboard", /* 01 */
"at_wini_1", /* 15 */
};
- if ((r = sys_getirqhooks(irqhooks)) != OK) {
+ if ((r = sys_getirqhooks(irq_hooks)) != OK) {
report("warning: couldn't get copy of irq hooks", r);
return;
}
- printf("IRQ table dump showing hardware interrupt policies for each IRQ vector.\n");
-#if 0
- printf("-irq name/nr- -pnr- --port-- msk_val --addr-- -type-rdp-str-ech-wrp-ena- \n");
- for (i=0; i<NR_IRQ_VECTORS; i++) {
- e = &irqtab[i];
- p = e->policy;
- printf("%9s %2d ", irq[i], i);
- if (e->proc_nr!=NONE) printf("%4d ", e->proc_nr);
- else printf(" ");
- printf(" 0x%06x 0x%05x 0x%06x %c%c%c %d\n",
- e->port, e->mask_val, e->addr,
- (p&IRQ_BYTE)?'B':'-', (p&IRQ_WORD)?'W':'-', (p&IRQ_LONG)?'L':'-',
- ((p&IRQ_REENABLE) != 0)
- );
+ printf("IRQ policies dump shows use of kernel's IRQ hooks.\n");
+ printf("-h.id- -proc.nr- -IRQ vector (nr.)- -policy- \n");
+ for (i=0; i<NR_IRQ_HOOKS; i++) {
+ e = &irq_hooks[i];
+ printf("%3d", i);
+ if (e->proc_nr==NONE) {
+ printf(" <unused>\n");
+ continue;
+ }
+ printf("%10d ", e->proc_nr);
+ printf(" %9.9s (%02d) ", irq[i], i);
+ printf(" %s\n", (e->policy & IRQ_REENABLE) ? "reenable" : "-");
}
-#endif
printf("\n");
}