Kernel cleanup.

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.
This commit is contained in:
Jorrit Herder 2005-06-07 12:34:25 +00:00
parent bb2ef4e039
commit 0e2a7a9730
14 changed files with 155 additions and 270 deletions

View file

@ -92,7 +92,6 @@ main.o: sendmask.h
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
@ -124,7 +123,6 @@ system.o: $h/com.h
system.o: system.h
system.o: proc.h
system.o: protect.h
system.o: assert.h
system.o: sendmask.h
table.o: $a

View file

@ -1,25 +0,0 @@
/* 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 */

View file

@ -1,4 +1,3 @@
#ifndef DEBUG_H
#define DEBUG_H

View file

@ -13,7 +13,7 @@
#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)))

View file

@ -1,10 +1,7 @@
/* 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"
@ -20,11 +17,7 @@ PUBLIC void panic(s,n)
_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;
@ -37,26 +30,6 @@ int n;
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 *
*===========================================================================*/
@ -107,39 +80,3 @@ bit_t nr_bits;
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 */

View file

@ -1,6 +1,7 @@
#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:
@ -57,7 +58,7 @@
*/
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 ) );
@ -111,10 +112,12 @@ message *m_ptr; /* pointer to message in the caller's space */
* 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;
@ -145,21 +148,7 @@ message *m_ptr; /* pointer to message in the caller's space */
* - 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)) {
@ -179,7 +168,7 @@ message *m_ptr; /* pointer to message in the caller's space */
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);
@ -217,12 +206,20 @@ unsigned flags; /* system call flags */
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) {
@ -233,6 +230,7 @@ unsigned flags; /* system call flags */
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.
@ -272,9 +270,9 @@ unsigned flags; /* system call flags */
}
/*===========================================================================*
* 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 */
@ -398,7 +396,7 @@ 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;

View file

@ -110,26 +110,24 @@ struct proc {
#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

View file

@ -40,7 +40,6 @@ _PROTOTYPE( void stop_sequence, (struct timer *tp) );
_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) );
@ -54,7 +53,6 @@ _PROTOTYPE( void lock_unready, (struct proc *rp) );
/* 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) );

View file

@ -3,7 +3,6 @@
*
* 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.
@ -13,10 +12,8 @@
#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 *
@ -29,7 +26,8 @@ U16_t parmoff, parmsize; /* boot parameters offset and length */
/* 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;
@ -53,8 +51,8 @@ U16_t parmoff, parmsize; /* boot parameters offset and length */
/* 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;
@ -64,8 +62,8 @@ U16_t parmoff, parmsize; /* boot parameters offset and length */
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
@ -74,20 +72,20 @@ U16_t parmoff, parmsize; /* boot parameters offset and length */
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().
@ -107,7 +105,8 @@ U16_t parmoff, parmsize; /* boot parameters offset and length */
/*=========================================================================*
* 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
@ -128,22 +127,23 @@ PRIVATE void mem_init()
* 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;
@ -158,10 +158,11 @@ PRIVATE void mem_init()
/*==========================================================================*
* 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.
@ -169,7 +170,7 @@ _CONST char *name;
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);

View file

@ -13,7 +13,6 @@
#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) );
@ -27,6 +26,7 @@ _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_physzero, (message *m_ptr) );
_PROTOTYPE( int do_unused, (message *m_ptr) ); /* miscellaneous */
_PROTOTYPE( int do_abort, (message *m_ptr) );
@ -60,9 +60,5 @@ _PROTOTYPE( int do_trace, (message *m_ptr) ); /* process tracing */
#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 */

View file

@ -37,7 +37,7 @@ a = $h/config.h $h/const.h $h/type.h $h/ipc.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

View file

@ -2,7 +2,6 @@
#include "../system.h"
#include <unistd.h>
#include <minix/config.h>
INIT_ASSERT
/*===========================================================================*
@ -37,26 +36,26 @@ message *m_ptr; /* pointer to request message */
* 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
*

View file

@ -16,7 +16,6 @@
#endif
#include "../debug.h"
INIT_ASSERT
/*===========================================================================*
* do_fork *
@ -33,9 +32,8 @@ register message *m_ptr; /* pointer to request message */
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)
@ -99,7 +97,7 @@ message *m_ptr; /* pointer to request message */
/* 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)
@ -140,7 +138,6 @@ register message *m_ptr; /* pointer to request message */
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 */

View file

@ -21,7 +21,6 @@
#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,
@ -72,61 +71,58 @@ 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;
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));
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));
assert(src_phys != 0);
phys_copy(src_phys,vir2phys(&smsg),(phys_bytes) sizeof(struct sigmsg));
/* 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;
/* 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));
/* 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;
/* 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));
/* 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;
/* 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));
/* 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;
/* 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);
return(OK);
}
PUBLIC int do_sigreturn(m_ptr)
@ -135,54 +131,47 @@ 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;
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));
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));
/* 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);
/* 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;
/* 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);
}
/*===========================================================================*