Reduced kernel size by 512KB by moving private buffer into cstart() function.
Replaced assertions with erroneous return values. Removed assertions relating
to isuserp(rp), since all processes should become user processes; system
processes are now treated similar to other processes.
misc.o: $a
misc.o: $i/stdlib.h
misc.o: $h/com.h
-misc.o: assert.h
printer.o: $a
printer.o: $h/callnr.h
system.o: system.h
system.o: proc.h
system.o: protect.h
-system.o: assert.h
system.o: sendmask.h
table.o: $a
+++ /dev/null
-/* assert.h */
-
-#ifndef NDEBUG /* 8086 must do without training wheels. */
-#define NDEBUG (_WORD_SIZE == 2)
-#endif
-
-#if !NDEBUG
-
-#define INIT_ASSERT static char *assert_file= __FILE__;
-
-void bad_assertion(char *file, int line, char *what);
-void bad_compare(char *file, int line, int lhs, char *what, int rhs);
-
-#define assert(x) (!(x) ? bad_assertion(assert_file, __LINE__, #x) \
- : (void) 0)
-#define compare(a,t,b) (!((a) t (b)) ? bad_compare(assert_file, __LINE__, \
- (a), #a " " #t " " #b, (b)) : (void) 0)
-#else /* NDEBUG */
-
-#define INIT_ASSERT /* nothing */
-
-#define assert(x) (void)0
-#define compare(a,t,b) (void)0
-
-#endif /* NDEBUG */
-
#ifndef DEBUG_H
#define DEBUG_H
#define NOTIFY 4 /* function code for notifications */
#if 0
-/* Bit map operations used to bits of simple bit mask. */
+/* Bit map operations to manipulate bits of a simple mask variable. */
#define set_bit(mask, n) ((mask) |= (1 << (n)))
#define clear_bit(mask, n) ((mask) &= ~(1 << (n)))
#define isset_bit(mask, n) ((mask) & (1 << (n)))
/* This file contains a collection of miscellaneous procedures:
* panic abort MINIX due to a fatal error
- * bad_assertion for debugging
- * bad_compare for debugging
* alloc_bit bit map manipulation
* free_bit bit map manipulation
- * print_bitmap bit map manipulation
*/
#include "kernel.h"
_CONST char *s;
int n;
{
-/* The system has run aground of a fatal error. Terminate execution.
- * If the panic originated in MM or FS, the string will be empty and the
- * file system already syncked. If the panic originates in the kernel, we are
- * kind of stuck.
- */
+/* The system has run aground of a fatal kernel error. Terminate execution. */
static int panicking = 0;
if (panicking ++) /* prevent recursive panics */
return;
prepare_shutdown(RBT_PANIC);
}
-#if ENABLE_K_DEBUGGING
-/*===========================================================================*
- * print_bitmap *
- *===========================================================================*/
-PUBLIC void print_bitmap(bitmap, nr_bits)
-bitchunk_t *bitmap;
-bit_t nr_bits;
-{
- bit_t bit_i;
-
- for (bit_i=0; bit_i < nr_bits; bit_i++) {
-
- kprintf("%d", GET_BIT(bitmap, bit_i) > 0 );
- if (! ((bit_i+1) % 8) ) kprintf(" ", NO_ARG);
- if (! ((bit_i+1) % 64) ) kprintf("\n", NO_ARG);
- }
- kprintf("\n", NO_ARG);
-}
-#endif /* ENABLE_K_DEBUGGING */
-
/*===========================================================================*
* free_bit *
*===========================================================================*/
return(-1);
}
-
-
-
-#if !NDEBUG
-/*=========================================================================*
- * bad_assertion *
- *=========================================================================*/
-PUBLIC void bad_assertion(file, line, what)
-char *file;
-int line;
-char *what;
-{
- kprintf("panic at %s", karg(file));
- kprintf(" (line %d): ", line);
- kprintf("assertion \"%s\" failed.\n", karg(what));
- panic(NULL, NO_NUM);
-}
-
-/*=========================================================================*
- * bad_compare *
- *=========================================================================*/
-PUBLIC void bad_compare(file, line, lhs, what, rhs)
-char *file;
-int line;
-int lhs;
-char *what;
-int rhs;
-{
- kprintf("panic at %s", karg(file));
- kprintf(" (line %d): ", line);
- kprintf("compare (%d)", lhs);
- kprintf(" %s ", karg(what));
- kprintf("(%d) failed.\n", rhs);
- panic(NULL, NO_NUM);
-}
-#endif /* !NDEBUG */
-#define NEW_SCHED_Q 1
-#define OLD_SEND 0
-#define OLD_RECV 0
+#define NEW_ELOCKED_CHECK 1
+#define NEW_SCHED_Q 1
+#define OLD_SEND 0
+#define OLD_RECV 0
/* This file contains essentially all of the process and message handling.
* Together with "mpx.s" it forms the lowest layer of the MINIX kernel.
* There is one entry point from the outside:
*/
FORWARD _PROTOTYPE( int mini_send, (struct proc *caller_ptr, int dst,
message *m_ptr, unsigned flags) );
-FORWARD _PROTOTYPE( int mini_rec, (struct proc *caller_ptr, int src,
+FORWARD _PROTOTYPE( int mini_receive, (struct proc *caller_ptr, int src,
message *m_ptr, unsigned flags) );
FORWARD _PROTOTYPE( int mini_notify, (struct proc *caller_ptr, int dst,
message *m_ptr ) );
* if the caller doesn't do receive().
*/
if (! (caller_ptr->p_call_mask & (1 << function)) ||
- iskernel(src_dst) && function != SENDREC) return(ECALLDENIED);
+ (iskerneltask(src_dst) && function != SENDREC))
+ return(ECALLDENIED);
- /* Verify that requested source and/ or destination is a valid process. */
- if (! isoksrc_dst(src_dst) && function != ECHO) return(EBADSRCDST);
+ /* Require a valid source and/ or destination process, unless echoing. */
+ if (! (isokprocn(src_dst) || src_dst == ANY || function == ECHO))
+ return(EBADSRCDST);
/* Check validity of message pointer. */
vb = (vir_bytes) m_ptr;
* - ECHO: the message directly will be echoed to the sender
*/
switch(function) {
- case SENDREC: /* has FRESH_ANSWER flags */
-#if DEAD_CODE
- { message m;
- if (caller_ptr->p_nr == MEMORY && src_dst == FS_PROC_NR) {
- CopyMess(caller_ptr->p_nr, caller_ptr, m_ptr, proc_addr(HARDWARE), &m);
- kprintf("MEMORY sendrec FS, m.m_type %d", m.m_type);
- kprintf("TTY_LINE %d", m.TTY_LINE);
- kprintf("TTY_REQ %d\n", m.TTY_REQUEST);
- }
- if (caller_ptr->p_nr == FS_PROC_NR && src_dst == MEMORY) {
- CopyMess(caller_ptr->p_nr, caller_ptr, m_ptr, proc_addr(HARDWARE), &m);
- kprintf("FS sendrec MEMORY, m.m_type %d\n", m.m_type);
- }
- }
-#endif
+ case SENDREC: /* has FRESH_ANSWER flag */
/* fall through */
case SEND:
if (! isalive(src_dst)) {
break; /* done, or SEND failed */
} /* fall through for SENDREC */
case RECEIVE:
- result = mini_rec(caller_ptr, src_dst, m_ptr, flags);
+ result = mini_receive(caller_ptr, src_dst, m_ptr, flags);
break;
case NOTIFY:
result = mini_notify(caller_ptr, src_dst, m_ptr);
register struct proc *xp;
#else
register struct proc **xpp;
+ register struct proc *xp;
#endif
dst_ptr = proc_addr(dst); /* pointer to destination's proc entry */
/* Check for deadlock by 'caller_ptr' and 'dst' sending to each other. */
+#if NEW_ELOCKED_CHECK
+ xp = dst_ptr;
+ while (xp->p_flags & SENDING) { /* check while sending */
+ xp = proc_addr(xp->p_sendto); /* get xp's destination */
+ if (xp == caller_ptr) return(ELOCKED); /* deadlock if cyclic */
+ }
+#else
if (dst_ptr->p_flags & SENDING) {
next_ptr = proc_addr(dst_ptr->p_sendto);
while (TRUE) {
break;
}
}
+#endif
/* Check if 'dst' is blocked waiting for this message. The destination's
* SENDING flag may be set when its SENDREC call blocked while sending.
}
/*===========================================================================*
- * mini_rec *
+ * mini_receive *
*===========================================================================*/
-PRIVATE int mini_rec(caller_ptr, src, m_ptr, flags)
+PRIVATE int mini_receive(caller_ptr, src, m_ptr, flags)
register struct proc *caller_ptr; /* process trying to get message */
int src; /* which message source is wanted */
message *m_ptr; /* pointer to message buffer */
/* Destination is not ready. Add the notification to the pending queue.
* Get pointer to notification message. Don't copy if already in kernel.
*/
- if (! iskernelp(caller_ptr)) {
+ if (! istaskp(caller_ptr)) {
CopyMess(proc_nr(caller_ptr), caller_ptr, m_ptr,
proc_addr(HARDWARE), &ntf_mess);
m_ptr = &ntf_mess;
#define END_PROC_ADDR (&proc[NR_TASKS + NR_PROCS])
#define NIL_PROC ((struct proc *) 0)
+#define cproc_addr(n) (&(proc + NR_TASKS)[(n)])
+#define proc_addr(n) (pproc_addr + NR_TASKS)[(n)]
+#define proc_nr(p) ((p)->p_nr)
+
+#define iskerneltask(n) ((n) == CLOCK || (n) == SYSTASK)
#define isidlehardware(n) ((n) == IDLE || (n) == HARDWARE)
#define isokprocn(n) ((unsigned) ((n) + NR_TASKS) < NR_PROCS + NR_TASKS)
#define isokprocp(p) ((p) >= BEG_PROC_ADDR && (p) < END_PROC_ADDR)
-#define isoksrc_dst(n) (isokprocn(n) || (n) == ANY)
#define isalive(n) (proc_addr(n)->p_type > P_NONE)
#define isalivep(p) ((p)->p_type > P_NONE)
-#define isrxhardware(n) ((n) == ANY || (n) == HARDWARE)
-#define isreservedp(p) ((p)->p_type == P_RESERVED)
#define isemptyp(p) ((p)->p_type == P_NONE)
#define istaskp(p) ((p)->p_type == P_TASK)
#define isdriverp(p) ((p)->p_type == P_DRIVER)
#define isserverp(p) ((p)->p_type == P_SERVER)
#define isuserp(p) ((p)->p_type == P_USER)
-#define isuser(n) (proc_addr(n)->p_type == P_USER)
#define isidlep(p) ((p)->p_type == P_IDLE)
-#define cproc_addr(n) (&(proc + NR_TASKS)[(n)])
-#define proc_addr(n) (pproc_addr + NR_TASKS)[(n)]
-#define proc_nr(p) ((p)->p_nr)
-#define iskernelp(p) ((p)->p_nr < 0)
-#define iskernel(n) ((n) == CLOCK || (n) == SYSTASK)
+
+#define isuser(n) (proc_addr(n)->p_type == P_USER)
/* The process table and pointers to process table slots. The pointers allow
* faster access because now a process entry can be found by indexing the
_PROTOTYPE( void panic, (_CONST char *s, int n) );
_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) );
-_PROTOTYPE( void print_bitmap, (bitchunk_t *map, bit_t nr_bits) );
/* proc.c */
_PROTOTYPE( int sys_call, (int function, int src_dest, message *m_ptr) );
/* start.c */
_PROTOTYPE( void cstart, (U16_t cs, U16_t ds, U16_t mds,
U16_t parmoff, U16_t parmsize) );
-_PROTOTYPE( char *getkenv, (_CONST char *key) );
/* system.c */
_PROTOTYPE( void cause_sig, (int proc_nr, int sig_nr) );
*
* This code runs in real mode for a 16 bit kernel and may have to switch
* to protected mode for a 286.
- *
* For a 32 bit kernel this already runs in protected mode, but the selectors
* are still those given by the BIOS with interrupts disabled, so the
* descriptors need to be reloaded and interrupt descriptors made.
#include "protect.h"
#include "proc.h"
-/* Environment strings passed by loader. */
-PRIVATE char k_environ[128*sizeof(char *)];
-
-FORWARD _PROTOTYPE( void mem_init, (void) );
+FORWARD _PROTOTYPE( void mem_init, (_CONST char *params));
+FORWARD _PROTOTYPE( char *get_value, (_CONST char *params, _CONST char *key));
/*==========================================================================*
* cstart *
/* Perform system initializations prior to calling main(). Most settings are
* determined with help of the environment strings passed by MINIX' loader.
*/
- register char *envp;
+ char params[128*sizeof(char *)]; /* boot monitor parameters */
+ register char *value; /* value in key=value pair */
unsigned mon_start;
extern int etext, end;
/* Copy the boot parameters to kernel memory. */
kinfo.params_base = seg2phys(mds) + parmoff;
- kinfo.params_size = MAX(parmsize,sizeof(k_environ)-2);
- phys_copy(kinfo.params_base, vir2phys(k_environ), kinfo.params_size);
+ kinfo.params_size = MAX(parmsize,sizeof(params)-2);
+ phys_copy(kinfo.params_base, vir2phys(params), kinfo.params_size);
/* Record miscellaneous information for user-space servers. */
kinfo.nr_procs = NR_PROCS;
kinfo.kmem_base = vir2phys(0);
kinfo.kmem_size = (phys_bytes) &end;
- /* Processor? */
- machine.processor=katoi(getkenv("processor")); /* 86, 186, 286, 386, ... */
+ /* Processor? 86, 186, 286, 386, ... */
+ machine.processor=katoi(get_value(params, "processor"));
/* Decide if mode is protected for older machines. */
#if _WORD_SIZE == 2
if (! machine.protected) mon_return = 0;
/* XT, AT or MCA bus? */
- envp = getkenv("bus");
- if (envp == NIL_PTR || kstrcmp(envp, "at") == 0) {
+ value = get_value(params, "bus");
+ if (value == NIL_PTR || kstrcmp(value, "at") == 0) {
machine.pc_at = TRUE; /* PC-AT compatible hardware */
- } else if (kstrcmp(envp, "mca") == 0) {
+ } else if (kstrcmp(value, "mca") == 0) {
machine.pc_at = machine.ps_mca = TRUE; /* PS/2 with micro channel */
}
/* Type of VDU: */
- envp = getkenv("video"); /* EGA or VGA video unit */
- if (kstrcmp(envp, "ega") == 0) machine.vdu_ega = TRUE;
- if (kstrcmp(envp, "vga") == 0) machine.vdu_vga = machine.vdu_ega = TRUE;
+ value = get_value(params, "video"); /* EGA or VGA video unit */
+ if (kstrcmp(value, "ega") == 0) machine.vdu_ega = TRUE;
+ if (kstrcmp(value, "vga") == 0) machine.vdu_vga = machine.vdu_ega = TRUE;
/* Initialize free memory list from size passed by boot monitor. */
- mem_init();
+ mem_init(params);
/* Return to assembler code to switch to protected mode (if 286),
* reload selectors and call main().
/*=========================================================================*
* mem_init *
*=========================================================================*/
-PRIVATE void mem_init()
+PRIVATE void mem_init(params)
+_CONST char *params; /* boot monitor parameters */
{
/* Initialize the free memory list from the 'memory' boot variable. Translate
* the byte offsets and sizes in this list to clicks, properly truncated. Also
* b1:s1 is mem between 1M and 16M, b2:s2 is mem above 16M. Pairs b1:s1
* and b2:s2 are combined if the memory is adjacent.
*/
- s = getkenv("memory"); /* get memory boot variable */
+ s = get_value(params, "memory"); /* get memory boot variable */
for (i = 0; i < NR_MEMS; i++) {
- memp = &mem[i]; /* result is stored here */
- base = size = 0;
- if (*s != 0) { /* end of boot variable */
- /* Expect base to be read (end != s) and ':' as next char. */
+ memp = &mem[i]; /* next mem chunk is stored here */
+ base = size = 0; /* initialize next base:size pair */
+ if (*s != 0) { /* get fresh data, unless at end */
+
+ /* Read fresh base and expect colon as next char. */
base = kstrtoul(s, &end, 0x10); /* get number */
if (end != s && *end == ':') s = ++end; /* skip ':' */
- else *s=0; /* fake end for next; should not happen */
- /* Expect size to be read and skip ',', unless at end. */
+ else *s=0; /* terminate, should not happen */
+
+ /* Read fresh size and expect comma or assume end. */
size = kstrtoul(s, &end, 0x10); /* get number */
if (end != s && *end == ',') s = ++end; /* skip ',' */
- else if (end != s && *end == 0) s = end; /* end found */
- else *s=0; /* fake end for next; should not happen */
+ else *s=0; /* found end */
}
- limit = base + size;
+ limit = base + size; /* limit is used for validity check */
#if _WORD_SIZE == 2
max_address = kinfo.protected ? MAX_16BIT : MAX_REAL;
if (limit > max_address) limit = max_address;
/*==========================================================================*
- * getkenv *
+ * get_value *
*==========================================================================*/
-PUBLIC char *getkenv(name)
-_CONST char *name;
+PRIVATE char *get_value(params, name)
+_CONST char *params; /* boot monitor parameters */
+_CONST char *name; /* key to look up */
{
/* Get environment value - kernel version of getenv to avoid setting up the
* usual environment array.
register _CONST char *namep;
register char *envp;
- for (envp = k_environ; *envp != 0;) {
+ for (envp = (char *) params; *envp != 0;) {
for (namep = name; *namep != 0 && *namep == *envp; namep++, envp++)
;
if (*namep == '\0' && *envp == '=') return(envp + 1);
#include <minix/com.h>
#include <minix/config.h>
#include "proc.h"
-#include "assert.h"
_PROTOTYPE( int do_exec, (message *m_ptr) ); /* process control */
_PROTOTYPE( int do_fork, (message *m_ptr) );
#define do_virvcopy do_vcopy
#define do_physvcopy do_vcopy
_PROTOTYPE( int do_umap, (message *m_ptr) );
+_PROTOTYPE( int do_physzero, (message *m_ptr) );
_PROTOTYPE( int do_unused, (message *m_ptr) ); /* miscellaneous */
_PROTOTYPE( int do_abort, (message *m_ptr) );
#define do_trace do_unused
#endif
-_PROTOTYPE( int do_vircopy, (message *m_ptr) );
-_PROTOTYPE( int do_physcopy, (message *m_ptr) );
-_PROTOTYPE( int do_physzero, (message *m_ptr) );
-_PROTOTYPE( int do_biosio, (message *m_ptr) );
#endif /* SYSTEM_H */
$k/proc.h $k/const.h $k/type.h $k/proto.h $k/glo.h
# Dependencies from src/kernel/system.h
-b = $k/system.h $h/com.h $k/proc.h $k/assert.h
+b = $k/system.h $h/com.h $k/proc.h
clock.o: $a $b
copying.o: $a $b
#include "../system.h"
#include <unistd.h>
#include <minix/config.h>
-INIT_ASSERT
/*===========================================================================*
* PM (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 <= kinfo.params_size);
- 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, kinfo.params_base, (phys_bytes) len);
+ /* The monitor is to run user 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)
+ kprintf("Warning, skipping shutdown code\n", NO_NUM);
+ 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
*
#endif
#include "../debug.h"
-INIT_ASSERT
/*===========================================================================*
* do_fork *
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));
+ if (! isemptyp(rpc)) return(EINVAL);
/* Copy parent 'proc' struct to child. */
#if (CHIP == INTEL)
/* Copy the map from PM. */
src_phys = umap_local(proc_addr(caller), D, (vir_bytes) map_ptr,
sizeof(rp->p_memmap));
- assert(src_phys != 0);
+ if (src_phys == 0) return(EFAULT);
phys_copy(src_phys,vir2phys(rp->p_memmap),(phys_bytes)sizeof(rp->p_memmap));
#if (CHIP != M68000)
char *np;
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 */
#include "../system.h"
#include <signal.h>
#include <sys/sigcontext.h>
-INIT_ASSERT
/* 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,
{
/* 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);
- assert(isuserp(rp));
-
- /* 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));
- assert(src_phys != 0);
- 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);
+ 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)
/* 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)) {
- kprintf("S_SIGRETURN: message source: %d; ", m_ptr->m_source);
- kprintf("got non-user process rp: %d\n", 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;
+ 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;
+ /* 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;
+ 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);
-
+ /* Restore the registers. */
+ kmemcpy(&rp->p_reg, (char *)&sc.sc_regs, sizeof(struct sigregs));
+ return(OK);
}
/*===========================================================================*