System processes can be signaled; signals are transformed in SYS_EVENT message

that passes signal map along. This mechanisms is also used for nonuser signals
like SIGKMESS, SIGKSTOP, SIGKSIG.

Revised comments of many system call handlers. Renamed setpriority to nice.
This commit is contained in:
Jorrit Herder 2005-07-19 12:21:36 +00:00
parent f8c380c195
commit 198c976f7e
33 changed files with 289 additions and 395 deletions

View file

@ -7,10 +7,8 @@
*
* Changes:
* Mar 18, 2004 clock interface moved to SYSTEM task (Jorrit N. Herder)
* Oct 10, 2004 call vector + return values allowed (Jorrit N. Herder)
* Sep 30, 2004 source code documentation updated (Jorrit N. Herder)
* Sep 24, 2004 redesigned timers and alarms (Jorrit N. Herder)
* Jun 04, 2004 new timeout flag alarm functionality (Jorrit N. Herder)
*
* The function do_clocktick() is not triggered from the clock library, but
* by the clock's interrupt handler when a watchdog timer has expired or
@ -60,25 +58,18 @@ FORWARD _PROTOTYPE( int do_clocktick, (message *m_ptr) );
#endif
/* The CLOCK's timers queue. The functions in <timers.h> operate on this.
* The process structure contains one timer per type of alarm (SIGNALRM,
* SYNCALRM, and FLAGALRM), which means that a process can have a single
* outstanding timer for each alarm type.
* If other kernel parts want to use additional timers, they must declare
* their own persistent timer structure, which can be passed to the clock
* All system processes possess a single synchronous alarm timer. If other
* kernel parts want to use additional timers, they must declare their own
* persistent (static) timer structure, which can be passed to the clock
* via (re)set_timer().
* When a timer expires its watchdog function is run by the CLOCK task.
*/
PRIVATE timer_t *clock_timers; /* queue of CLOCK timers */
PRIVATE clock_t next_timeout; /* realtime that next timer expires */
/* The boot time and the current real time. The real time is incremented by
* the clock on each clock tick. The boot time is set by a utility program
* after system startup to prevent troubles reading the CMOS.
*/
/* The time is incremented by the interrupt handler on each clock tick. */
PRIVATE clock_t realtime; /* real time clock */
/* Variables for and changed by the CLOCK's interrupt handler. */
PRIVATE irq_hook_t clock_hook;
PRIVATE irq_hook_t clock_hook; /* interrupt handler hook */
/*===========================================================================*
@ -86,12 +77,12 @@ PRIVATE irq_hook_t clock_hook;
*===========================================================================*/
PUBLIC void clock_task()
{
/* Main program of clock task. It corrects realtime by adding pending ticks
* seen only by the interrupt service, then it determines which call this is
* by looking at the message type and dispatches.
/* Main program of clock task. It determines which call this is by looking at
* the message type and dispatches.
*/
message m; /* message buffer for both input and output */
int result;
int result; /* result returned by the handler */
init_clock(); /* initialize clock task */
/* Main loop of the clock task. Get work, process it, sometimes reply. */
@ -297,11 +288,9 @@ PUBLIC unsigned long read_clock()
*/
unsigned count;
/* lock(10, "read_clock"); */
outb(TIMER_MODE, LATCH_COUNT);
count = inb(TIMER0);
count |= (inb(TIMER0) << 8);
/* unlock(10); */
return count;
}

View file

@ -34,7 +34,7 @@
#define USE_IRQCTL 1 /* set an interrupt policy */
#define USE_SEGCTL 1 /* set up a remote segment */
#define USE_SVRCTL 1 /* system server control */
#define USE_SCHEDCTL 1 /* change scheduling priority (nice) */
#define USE_NICE 1 /* change scheduling priority */
#define USE_UMAP 1 /* map virtual to physical address */
#define USE_VIRCOPY 1 /* copy using virtual addressing */
#define USE_VIRVCOPY 1 /* vector with virtual copy requests */
@ -70,8 +70,13 @@
#define VDEVIO_BUF_SIZE 64 /* max elements per VDEVIO request */
#define VCOPY_VEC_SIZE 16 /* max elements per VCOPY request */
#if TEMP_CODE
/* How many buffers for notification messages should there be? */
#define NR_NOTIFY_BUFS 32
#endif
/* How many bytes for the kernel stack. Space allocated in mpx.s. */
#define K_STACK_BYTES 1024
/* This section allows to enable kernel debugging and timing functionality.

View file

@ -20,9 +20,6 @@
#define structof(type, field, ptr) \
((type *) (((char *) (ptr)) - offsetof(type, field)))
/* How many bytes for the kernel stack. Space allocated in mpx.s. */
#define K_STACK_BYTES 1024
/* Constants used in virtual_copy(). Values must be 0 and 1, respectively. */
#define _SRC_ 0
#define _DST_ 1

View file

@ -33,9 +33,11 @@ EXTERN char k_reenter; /* kernel reentry count (entry count less 1) */
EXTERN int sched_ticks; /* keep track of quantum usage */
EXTERN unsigned lost_ticks; /* clock ticks counted outside clock task */
#if TEMP_CODE
/* Declare buffer space and a bit map for notification messages. */
EXTERN struct notification notify_buffer[NR_NOTIFY_BUFS];
EXTERN bitchunk_t notify_bitmap[BITMAP_CHUNKS(NR_NOTIFY_BUFS)];
#endif
#if (CHIP == INTEL)

View file

@ -51,39 +51,39 @@ int mine;
intr_disable();
if (machine.protected) {
/* The AT and newer PS/2 have two interrupt controllers, one master,
* one slaved at IRQ 2. (We don't have to deal with the PC that
* has just one controller, because it must run in real mode.)
*/
outb(INT_CTL, machine.ps_mca ? ICW1_PS : ICW1_AT);
outb(INT_CTLMASK, mine ? IRQ0_VECTOR : BIOS_IRQ0_VEC);
/* The AT and newer PS/2 have two interrupt controllers, one master,
* one slaved at IRQ 2. (We don't have to deal with the PC that
* has just one controller, because it must run in real mode.)
*/
outb(INT_CTL, machine.ps_mca ? ICW1_PS : ICW1_AT);
outb(INT_CTLMASK, mine ? IRQ0_VECTOR : BIOS_IRQ0_VEC);
/* ICW2 for master */
outb(INT_CTLMASK, (1 << CASCADE_IRQ)); /* ICW3 tells slaves */
outb(INT_CTLMASK, ICW4_AT_MASTER);
outb(INT_CTLMASK, ~(1 << CASCADE_IRQ)); /* IRQ 0-7 mask */
outb(INT2_CTL, machine.ps_mca ? ICW1_PS : ICW1_AT);
outb(INT2_CTLMASK, mine ? IRQ8_VECTOR : BIOS_IRQ8_VEC);
outb(INT_CTLMASK, (1 << CASCADE_IRQ)); /* ICW3 tells slaves */
outb(INT_CTLMASK, ICW4_AT_MASTER);
outb(INT_CTLMASK, ~(1 << CASCADE_IRQ)); /* IRQ 0-7 mask */
outb(INT2_CTL, machine.ps_mca ? ICW1_PS : ICW1_AT);
outb(INT2_CTLMASK, mine ? IRQ8_VECTOR : BIOS_IRQ8_VEC);
/* ICW2 for slave */
outb(INT2_CTLMASK, CASCADE_IRQ); /* ICW3 is slave nr */
outb(INT2_CTLMASK, ICW4_AT_SLAVE);
outb(INT2_CTLMASK, ~0); /* IRQ 8-15 mask */
outb(INT2_CTLMASK, CASCADE_IRQ); /* ICW3 is slave nr */
outb(INT2_CTLMASK, ICW4_AT_SLAVE);
outb(INT2_CTLMASK, ~0); /* IRQ 8-15 mask */
/* Copy the BIOS vectors from the BIOS to the Minix location, so we
* can still make BIOS calls without reprogramming the i8259s.
*/
/* Copy the BIOS vectors from the BIOS to the Minix location, so we
* can still make BIOS calls without reprogramming the i8259s.
*/
#if IRQ0_VECTOR != BIOS_IRQ0_VEC
phys_copy(BIOS_VECTOR(0) * 4L, VECTOR(0) * 4L, 8 * 4L);
phys_copy(BIOS_VECTOR(0) * 4L, VECTOR(0) * 4L, 8 * 4L);
#endif
#if IRQ8_VECTOR != BIOS_IRQ8_VEC
phys_copy(BIOS_VECTOR(8) * 4L, VECTOR(8) * 4L, 8 * 4L);
phys_copy(BIOS_VECTOR(8) * 4L, VECTOR(8) * 4L, 8 * 4L);
#endif
} else {
/* Use the BIOS interrupt vectors in real mode. We only reprogram the
* exceptions here, the interrupt vectors are reprogrammed on demand.
* SYS_VECTOR is the Minix system call for message passing.
*/
for (i = 0; i < 8; i++) set_vec(i, int_vec[i]);
set_vec(SYS_VECTOR, s_call);
/* Use the BIOS interrupt vectors in real mode. We only reprogram the
* exceptions here, the interrupt vectors are reprogrammed on demand.
* SYS_VECTOR is the Minix system call for message passing.
*/
for (i = 0; i < 8; i++) set_vec(i, int_vec[i]);
set_vec(SYS_VECTOR, s_call);
}
}
@ -100,14 +100,14 @@ irq_handler_t handler;
irq_hook_t **line;
if (irq < 0 || irq >= NR_IRQ_VECTORS)
panic("invalid call to put_irq_handler", irq);
panic("invalid call to put_irq_handler", irq);
line = &irq_handlers[irq];
id = 1;
while (*line != NULL) {
if (hook == *line) return; /* extra initialization */
line = &(*line)->next;
id <<= 1;
if (hook == *line) return; /* extra initialization */
line = &(*line)->next;
id <<= 1;
}
if (id == 0) panic("Too many handlers for irq", irq);
@ -130,22 +130,20 @@ int id;
/* Unregister an interrupt handler. */
irq_hook_t **line;
if (irq < 0 || irq >= NR_IRQ_VECTORS) {
return EINVAL;
}
if (irq < 0 || irq >= NR_IRQ_VECTORS) return(EINVAL);
line = &irq_handlers[irq];
while (*line != NULL) {
if((*line)->id == id) {
(*line) = (*line)->next;
if(!irq_handlers[irq])
irq_use &= ~(1 << irq);
return OK;
}
line = &(*line)->next;
if((*line)->id == id) {
(*line) = (*line)->next;
if(! irq_handlers[irq])
irq_use &= ~(1 << irq);
return(OK);
}
line = &(*line)->next;
}
return ENOENT;
return(ENOENT);
}
/*==========================================================================*
@ -161,12 +159,12 @@ irq_hook_t *hook;
/* Call list of handlers for an IRQ. */
while (hook != NULL) {
/* For each handler in the list, mark it active by setting its ID bit,
* call the function, and unmark it if the function returns true.
*/
irq_actids[hook->irq] |= hook->id;
if ((*hook->handler)(hook)) irq_actids[hook->irq] &= ~hook->id;
hook = hook->next;
/* For each handler in the list, mark it active by setting its ID bit,
* call the function, and unmark it if the function returns true.
*/
irq_actids[hook->irq] |= hook->id;
if ((*hook->handler)(hook)) irq_actids[hook->irq] &= ~hook->id;
hook = hook->next;
}
/* The assembly code will now disable interrupts, unmask the IRQ if and only

View file

@ -18,9 +18,8 @@
/* Call masks indicating which system calls a process can make. */
#define EMPTY_CALL_MASK (0)
#define _USER_CALL_MASK ((1 << SENDREC) | (1 << ALERT))
#define USER_CALL_MASK (1 << SENDREC)
#define SYSTEM_CALL_MASK (~0)
#define USER_CALL_MASK (~0)
#endif /* IPC_H */

View file

@ -20,6 +20,7 @@
#include "kernel.h"
#include <signal.h>
#include <minix/com.h>
#define isdigit(c) ((unsigned) ((c) - '0') < (unsigned) 10)
@ -159,7 +160,7 @@ int c; /* character to append */
kmess.km_size += 1;
kmess.km_next = (kmess.km_next + 1) % KMESS_BUF_SIZE;
} else {
lock_alert(SYSTEM, PRINTF_PROC);
send_sig(PRINTF_PROC, SIGKMESS);
}
}

View file

@ -201,6 +201,9 @@ int how; /* reason to shut down */
return; /* await sys_abort() from TTY */
}
/* Send signal to TTY so that it can switch to the primary console. */
send_sig(TTY, SIGKSTOP);
/* Allow processes to be scheduled to clean up, unless a CPU exception
* occurred. This is done by setting a timer. The timer argument passes
* the shutdown status.

View file

@ -26,6 +26,7 @@ struct priv {
sys_map_t s_notify_pending; /* bit map with pending notifications */
short s_int_pending; /* pending hardware interrupts */
sigset_t s_sig_pending; /* pending signals */
timer_t s_alarm_timer; /* synchronous alarm timer */
struct far_mem s_farmem[NR_REMOTE_SEGS]; /* remote memory map */
@ -60,6 +61,9 @@ struct priv {
EXTERN struct priv priv[NR_SYS_PROCS]; /* system properties table */
EXTERN struct priv *ppriv_addr[NR_SYS_PROCS]; /* direct slot pointers */
/* Unprivileged user processes all share the same privilege structure. */
#define USER_PRIV_ID 0
/* Make sure the system can boot. The following sanity check verifies that
* the system privileges table is large enough for the number of processes
* in the boot image.

View file

@ -62,19 +62,27 @@ FORWARD _PROTOTYPE( void sched, (struct proc *rp) );
FORWARD _PROTOTYPE( void pick_proc, (void) );
#if TEMP_CODE
#define BuildOldMess(m,n) \
(m).NOTIFY_SOURCE = (n)->n_source, \
(m).NOTIFY_TYPE = (n)->n_type, \
(m).NOTIFY_FLAGS = (n)->n_flags, \
(m).NOTIFY_ARG = (n)->n_arg;
#endif
#define BuildMess(m_ptr, src, dst_ptr) \
(m_ptr)->m_source = (src); \
(m_ptr)->m_type = NOTIFY_FROM(src); \
(m_ptr)->NOTIFY_TIMESTAMP = get_uptime(); \
if ((src) == HARDWARE) { \
switch (src) { \
case HARDWARE: \
(m_ptr)->NOTIFY_ARG = priv(dst_ptr)->s_int_pending; \
priv(dst_ptr)->s_int_pending = 0; \
break; \
case SYSTEM: \
(m_ptr)->NOTIFY_ARG = priv(dst_ptr)->s_sig_pending; \
priv(dst_ptr)->s_sig_pending = 0; \
break; \
}
#if (CHIP == INTEL)
@ -123,24 +131,16 @@ message *m_ptr; /* pointer to message in the caller's space */
return(EBADSRCDST);
#if DEAD_CODE /* temporarily disabled for testing ALERT */
/* Check validity of message pointer. */
vb = (vir_bytes) m_ptr;
vlo = vb >> CLICK_SHIFT; /* vir click for bottom of message */
vhi = (vb + MESS_SIZE - 1) >> CLICK_SHIFT; /* vir click for top of msg */
#if ALLOW_GAP_MESSAGES
/* This check allows a message to be anywhere in data or stack or gap.
* It will have to be made more elaborate later for machines which
* don't have the gap mapped.
*/
vb = (vir_bytes) m_ptr;
vlo = vb >> CLICK_SHIFT; /* vir click for bottom of message */
vhi = (vb + MESS_SIZE - 1) >> CLICK_SHIFT; /* vir click for top of msg */
if (vlo < caller_ptr->p_memmap[D].mem_vir || vlo > vhi ||
vhi >= caller_ptr->p_memmap[S].mem_vir + caller_ptr->p_memmap[S].mem_len)
return(EFAULT);
#else
/* Check for messages wrapping around top of memory or outside data seg. */
if (vhi < vlo ||
vhi - caller_ptr->p_memmap[D].mem_vir >= caller_ptr->p_memmap[D].mem_len)
return(EFAULT);
#endif
#endif
/* Now check if the call is known and try to perform the request. The only
@ -183,9 +183,11 @@ message *m_ptr; /* pointer to message in the caller's space */
break;
case NOTIFY:
result = mini_notify(caller_ptr, src_dst, m_ptr);
#if TEMP_CODE
break;
case ECHO:
kprintf("Echo message from process %s\n", proc_nr(caller_ptr));
#endif
CopyMess(caller_ptr->p_nr, caller_ptr, m_ptr, caller_ptr, m_ptr);
result = OK;
break;
@ -197,7 +199,7 @@ message *m_ptr; /* pointer to message in the caller's space */
* be raised. The priority may have been lowered if a process consumed too
* many full quantums in a row to prevent damage from infinite loops
*/
#if DEAD_CODE /* temporarily disabled for testing ALERT */
#if DEAD_CODE /* buggy ... do unready() first! */
if ((caller_ptr->p_priority > caller_ptr->p_max_priority) &&
! (flags & NON_BLOCKING) && (result == OK)) {
caller_ptr->p_priority = caller_ptr->p_max_priority;

View file

@ -87,7 +87,7 @@ struct proc {
#define BEG_USER_ADDR (&proc[NR_TASKS])
#define END_PROC_ADDR (&proc[NR_TASKS + NR_PROCS])
#define NIL_PROC ((struct proc *) 0)
#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)

View file

@ -50,6 +50,7 @@ _PROTOTYPE( void cstart, (U16_t cs, U16_t ds, U16_t mds,
U16_t parmoff, U16_t parmsize) );
/* system.c */
_PROTOTYPE( void send_sig, (int proc_nr, int sig_nr) );
_PROTOTYPE( void cause_sig, (int proc_nr, int sig_nr) );
_PROTOTYPE( int init_proc, (int proc_nr, int proto_nr) );
_PROTOTYPE( void clear_proc, (int proc_nr) );

View file

@ -1,44 +0,0 @@
/* Definition of the 'p_sendmask' bit mask used in the process table. The bit
* mask of process is checked in mini_send() to see if the caller is allowed
* to send to the destination.
*
* PLEASE NOTE: the send masks definitions are a mess and must be updated!!!
* this will be done when dynamic driver loading is implemented
*
* Changes:
* May 01, 2004 created and sendmask definitions (Jorrit N. Herder)
*/
#ifndef SENDMASK_H
#define SENDMASK_H
/* Define type for sendmask, if not already done. */
#include "type.h"
/* Constants to support the bitmask operations. */
#define BIT_0 (send_mask_t) 1
#define MASK_ENTRIES NR_TASKS + (INIT_PROC_NR+1) + 1
#define USER_PROC_NR INIT_PROC_NR+1 /* used to set bit for user procs */
#define ALLOW_ALL_MASK (send_mask_t) -1
#define DENY_ALL_MASK (send_mask_t) 0
/* Check if given process number is in range. */
#define isvalid(n) ((unsigned) ((n)+NR_TASKS) <= MASK_ENTRIES -1)
/* Default masks and bit operations that easily allow to construct bit masks.
* Note the one always must start with a default mask like allow_all_mask.
* From that point, one can, for example, deny several processes.
*/
#define allow(enabled,n) | (enabled << ((n) + NR_TASKS))
#define deny(enabled,n) & ~(enabled << ((n) + NR_TASKS))
#define send_mask_allow(mask,n) ((mask) |= (1 << ((n) + NR_TASKS)))
#define send_mask_deny(mask,n) ((mask) &= ~(1 << ((n) + NR_TASKS)))
/* Check if the bit for the given process number is set. */
#define isallowed(mask,n) ((mask) & (BIT_0 << ((n) + NR_TASKS)))
#define USER_PROC_SENDMASK \
DENY_ALL_MASK allow(1, PM_PROC_NR) allow(1, FS_PROC_NR)
#endif /* SENDMASK_H */

View file

@ -11,7 +11,8 @@
*
* In addition to the main sys_task() entry point, which starts the main loop,
* there are several other minor entry points:
* cause_sig: take action to cause a signal to occur
* send_sig: send signal directly to a system process
* cause_sig: take action to cause a signal to occur via PM
* clear_proc: clean up a process in the process table, e.g. on exit
* umap_local: map virtual address in LOCAL_SEG to physical
* umap_remote: map virtual address in REMOTE_SEG to physical
@ -78,9 +79,6 @@ PUBLIC void sys_task()
/* Handle the request. */
if ((unsigned) m.m_type < NR_SYS_CALLS) {
result = (*call_vec[m.m_type])(&m); /* handle the kernel call */
} else if (m.m_type == NEW_KSIG) {
lock_alert(SYSTEM, PM_PROC_NR); /* tell PM about signal */
continue;
} else {
kprintf("Warning, illegal SYSTASK request from %d.\n", m.m_source);
result = EBADREQUEST; /* illegal message type */
@ -133,6 +131,7 @@ PRIVATE void initialize(void)
map(SYS_NEWMAP, do_newmap); /* set up a process memory map */
map(SYS_EXEC, do_exec); /* update process after execute */
map(SYS_EXIT, do_exit); /* clean up after process exit */
map(SYS_NICE, do_nice); /* set scheduling priority */
map(SYS_TRACE, do_trace); /* request a trace operation */
/* Signal handling. */
@ -153,7 +152,8 @@ PRIVATE void initialize(void)
map(SYS_VDEVIO, do_vdevio); /* vector with devio requests */
/* System control. */
map(SYS_SETPRIORITY, do_schedctl); /* set scheduling priority */
map(SYS_ABORT, do_abort); /* abort MINIX */
map(SYS_GETINFO, do_getinfo); /* request system information */
map(SYS_SEGCTL, do_segctl); /* add segment and get selector */
map(SYS_SVRCTL, do_svrctl); /* kernel control functions */
@ -164,10 +164,6 @@ PRIVATE void initialize(void)
map(SYS_VIRVCOPY, do_virvcopy); /* vector with copy requests */
map(SYS_PHYSVCOPY, do_physvcopy); /* vector with copy requests */
map(SYS_MEMSET, do_memset); /* write char to memory area */
/* Miscellaneous. */
map(SYS_ABORT, do_abort); /* abort MINIX */
map(SYS_GETINFO, do_getinfo); /* request system information */
}
@ -256,17 +252,18 @@ int proc_nr; /* slot of process to clean up */
while (rc->p_ntf_q != NULL) {
i = (int) (rc->p_ntf_q - &notify_buffer[0]);
free_bit(i, notify_bitmap, NR_NOTIFY_BUFS);
#if TEMP_CODE
rc->p_ntf_q = rc->p_ntf_q->n_next;
}
/* Now clean up the process table entry. Reset to defaults. */
kstrncpy(rc->p_name, "<none>", P_NAME_LEN); /* unset name */
sigemptyset(&rc->p_pending); /* remove pending signals */
rc->p_rts_flags = SLOT_FREE; /* announce slot empty */
#if (CHIP == M68000)
pmmu_delete(rc); /* we're done, remove tables */
#endif
/* Now it is safe to release the process table slot. If this is a system
* process, also release its privilege structure. Further cleanup is not
* needed at this point. All important fields are reinitialized when the
* slots are assigned to another, new process.
*/
rc->p_rts_flags = SLOT_FREE;
if (priv(rp)->s_flags & SYS_PROC) priv(rp)->s_proc_nr = NONE;
}
@ -331,6 +328,25 @@ irq_hook_t *hook;
}
/*===========================================================================*
* send_sig *
*===========================================================================*/
PUBLIC void send_sig(proc_nr, sig_nr)
int proc_nr; /* system process to be signalled */
int sig_nr; /* signal to be sent, 1 to _NSIG */
{
/* Notify a system process about a signal. This is straightforward. Simply
* set the signal that is to be delivered in the pending signals map and
* send a notification with source SYSTEM.
*/
register struct proc *rp;
rp = proc_addr(proc_nr);
sigaddset(&priv(rp)->s_sig_pending, sig_nr);
lock_alert(SYSTEM, proc_nr);
}
/*===========================================================================*
* cause_sig *
*===========================================================================*/
@ -346,8 +362,10 @@ int sig_nr; /* signal to be sent, 1 to _NSIG */
* signals and makes sure the PM gets them by sending a notification. The
* process being signaled is blocked while PM has not finished all signals
* for it.
* It is not sufficient to ready the process when PM is informed, because
* PM can block waiting for FS to do a core dump.
* Race conditions between calls to this function and the system calls that
* process pending kernel signals cannot exist. Signal related functions are
* only called when a user process causes a CPU exception and from the kernel
* process level, which runs to completion.
*/
register struct proc *rp;
@ -358,7 +376,7 @@ int sig_nr; /* signal to be sent, 1 to _NSIG */
if (! (rp->p_rts_flags & SIGNALED)) { /* other pending */
if (rp->p_rts_flags == 0) lock_unready(rp); /* make not ready */
rp->p_rts_flags |= SIGNALED | SIG_PENDING; /* update flags */
lock_alert(HARDWARE, SYSTEM);
send_sig(PM_PROC_NR, SIGKSIG);
}
}
}
@ -509,10 +527,7 @@ vir_bytes bytes; /* # of bytes to copy */
int i;
/* Check copy count. */
if (bytes <= 0) {
kprintf("v_cp: copy count problem <= 0\n", NO_NUM);
return(EDOM);
}
if (bytes <= 0) return(EDOM);
/* Do some more checks and map virtual addresses to physical addresses. */
vir_addr[_SRC_] = src_addr;
@ -539,16 +554,12 @@ vir_bytes bytes; /* # of bytes to copy */
phys_addr[i] = vir_addr[i]->offset;
break;
default:
kprintf("v_cp: Unknown segment type: %d\n",
vir_addr[i]->segment & SEGMENT_TYPE);
return(EINVAL);
}
/* Check if mapping succeeded. */
if (phys_addr[i] <= 0 && vir_addr[i]->segment != PHYS_SEG) {
kprintf("v_cp: Mapping failed ... phys <= 0\n", NO_NUM);
if (phys_addr[i] <= 0 && vir_addr[i]->segment != PHYS_SEG)
return(EFAULT);
}
}
/* Now copy bytes between physical addresseses. */

View file

@ -43,9 +43,9 @@ _PROTOTYPE( int do_trace, (message *m_ptr) );
#define do_trace do_unused
#endif
_PROTOTYPE( int do_schedctl, (message *m_ptr) );
#if ! USE_SCHEDCTL
#define do_schedctl do_unused
_PROTOTYPE( int do_nice, (message *m_ptr) );
#if ! USE_NICE
#define do_nice do_unused
#endif
_PROTOTYPE( int do_copy, (message *m_ptr) );

View file

@ -23,7 +23,7 @@ OBJECTS = \
$(SYSTEM)(do_newmap.o) \
$(SYSTEM)(do_exit.o) \
$(SYSTEM)(do_trace.o) \
$(SYSTEM)(do_schedctl.o) \
$(SYSTEM)(do_nice.o) \
$(SYSTEM)(do_times.o) \
$(SYSTEM)(do_alarm.o) \
$(SYSTEM)(do_irqctl.o) \
@ -75,8 +75,8 @@ $(SYSTEM)(do_exit.o): do_exit.c
$(SYSTEM)(do_trace.o): do_trace.c
$(CC) do_trace.c
$(SYSTEM)(do_schedctl.o): do_schedctl.c
$(CC) do_schedctl.c
$(SYSTEM)(do_nice.o): do_nice.c
$(CC) do_nice.c
$(SYSTEM)(do_times.o): do_times.c
$(CC) do_times.c

View file

@ -1,7 +1,3 @@
#include "../system.h"
#include <unistd.h>
/* The system call implemented in this file:
* m_type: SYS_ABORT
*
@ -11,6 +7,10 @@
* m1_i3: ABRT_MON_LEN (length of monitor params)
* m1_p1: ABRT_MON_ADDR (virtual address of params)
*/
#include "../system.h"
#include <unistd.h>
#if USE_ABORT
/*===========================================================================*
@ -24,7 +24,7 @@ message *m_ptr; /* pointer to request message */
* or ESC after debugging dumps).
*/
int how = m_ptr->ABRT_HOW;
if (how == RBT_MONITOR) {
/* The monitor is to run the specified instructions. */
int proc_nr = m_ptr->ABRT_MON_PROC;
@ -33,8 +33,8 @@ message *m_ptr; /* pointer to request message */
phys_bytes src_phys = numap_local(proc_nr, src_vir, length);
/* Validate length and address of shutdown code before copying. */
if (length > kinfo.params_size || src_phys == 0)
phys_copy(vir2phys("delay;boot"), kinfo.params_base, 11);
if (length > kinfo.params_size || src_phys == 0)
phys_copy(vir2phys("delay;boot"), kinfo.params_base, 11);
else
phys_copy(src_phys, kinfo.params_base, (phys_bytes) length);
}

View file

@ -5,10 +5,10 @@
* m2_i1: ALRM_PROC_NR (set alarm for this process)
* m2_l1: ALRM_EXP_TIME (alarm's expiration time)
* m2_i2: ALRM_ABS_TIME (expiration time is absolute?)
* m2_l1: ALRM_SEC_LEFT (return seconds left of previous)
* m2_l1: ALRM_TIME_LEFT (return seconds left of previous)
*
* Changes:
* Aug 25, 2004 fully rewritten to clean up code (Jorrit N. Herder)
* Aug 25, 2004 fully rewritten to clean up code (Jorrit N. Herder)
*/
#include "../system.h"
@ -40,10 +40,10 @@ message *m_ptr; /* pointer to request message */
/* Get the timer structure and set the parameters for this alarm. */
tp = &(proc_addr(proc_nr)->p_priv->s_alarm_timer);
tmr_arg(tp)->ta_int = proc_nr;
tp->tmr_func = cause_alarm;
tp->tmr_func = cause_alarm;
/* Return the ticks left on the previous alarm. */
uptime = get_uptime();
uptime = get_uptime();
if ((tp->tmr_exp_time == TMR_NEVER) || (tp->tmr_exp_time < uptime) ) {
m_ptr->ALRM_TIME_LEFT = 0;
} else {
@ -69,7 +69,7 @@ timer_t *tp;
{
/* Routine called if a timer goes off and the process requested a synchronous
* alarm. The process number is stored in timer argument 'ta_int'. Notify that
* process given with a SYN_ALARM message.
* process with a notification message from CLOCK.
*/
lock_alert(CLOCK, tmr_arg(tp)->ta_int);
}

View file

@ -45,10 +45,8 @@ register message *m_ptr; /* pointer to request message */
/* Check if process number was given implictly with SELF and is valid. */
if (vir_addr[i].proc_nr == SELF) vir_addr[i].proc_nr = m_ptr->m_source;
if (! isokprocn(vir_addr[i].proc_nr) && vir_addr[i].segment != PHYS_SEG) {
kprintf("do_vircopy: illegal proc nr, while not phys addr\n",NO_NUM);
if (! isokprocn(vir_addr[i].proc_nr) && vir_addr[i].segment != PHYS_SEG)
return(EINVAL);
}
/* Check if physical addressing is used without SYS_PHYSCOPY. */
if ((vir_addr[i].segment & PHYS_SEG) &&
@ -58,10 +56,7 @@ register message *m_ptr; /* pointer to request message */
/* Check for overflow. This would happen for 64K segments and 16-bit
* vir_bytes. Especially copying by the PM on do_fork() is affected.
*/
if (bytes != (vir_bytes) bytes) {
kprintf("do_vircopy: overflow\n", NO_NUM);
return(E2BIG);
}
if (bytes != (vir_bytes) bytes) return(E2BIG);
/* Now try to make the actual virtual copy. */
return( virtual_copy(&vir_addr[_SRC_], &vir_addr[_DST_], bytes) );

View file

@ -1,20 +1,8 @@
/* The system call that is implemented in this file:
* SYS_SIGCTL # signal handling functionality
* m_type: SYS_ENDKSIG
*
* The parameters and types for this system call are:
* SIG_REQUEST # request to perform (long)
* SIG_PROC # process to signal/ pending (int)
* SIG_CTXT_PTR # pointer to sigcontext structure (pointer)
* SIG_FLAGS # flags for S_SIGRETURN call (int)
* SIG_MAP # bit map with pending signals (long)
* SIG_NUMBER # signal number to send to process (int)
*
* Supported request types are in the parameter SIG_REQUEST:
* S_GETSIG # get a pending kernel signal
* S_ENDSIG # signal has been processed
* S_SENDSIG # deliver a POSIX-style signal
* S_SIGRETURN # return from a POSIX-style signal
* S_KILL # send a signal to a process
* The parameters for this system call are:
* m2_i1: SIG_PROC # process for which PM is done
*/
#include "../system.h"

View file

@ -3,7 +3,9 @@
*
* The parameters for this system call are:
* m1_i1: PR_PROC_NR (process that did exec call)
#if DEAD_CODE
* m1_i3: PR_TRACING (flag to indicate tracing is on/ off)
#endif
* 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)
@ -20,14 +22,15 @@ PUBLIC int do_exec(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Handle sys_exec(). A process has done a successful EXEC. Patch it up. */
register struct proc *rp;
reg_t sp; /* new sp */
phys_bytes phys_name;
char *np;
rp = proc_addr(m_ptr->PR_PROC_NR);
#if DEAD_CODE
if (m_ptr->PR_TRACING) cause_sig(m_ptr->PR_PROC_NR, SIGTRAP);
#endif
sp = (reg_t) m_ptr->PR_STACK_PTR;
rp->p_reg.sp = sp; /* set the stack pointer */
#if (CHIP == M68000)

View file

@ -26,25 +26,26 @@ register message *m_ptr; /* pointer to request message */
#if (CHIP == INTEL)
reg_t old_ldt_sel;
#endif
register struct proc *rpc;
struct proc *rpp;
register struct proc *rpc; /* child process pointer */
struct proc *rpp; /* parent process pointer */
rpp = proc_addr(m_ptr->PR_PPROC_NR);
rpc = proc_addr(m_ptr->PR_PROC_NR);
if (! isemptyp(rpc)) return(EINVAL);
if (isemptyp(rpp) || ! isemptyp(rpc)) return(EINVAL);
/* Copy parent 'proc' struct to child. */
/* Copy parent 'proc' struct to child. And reinitialize some fields. */
#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;
old_ldt_sel = rpc->p_ldt_sel; /* backup local descriptors */
*rpc = *rpp; /* copy 'proc' struct */
rpc->p_ldt_sel = old_ldt_sel; /* restore descriptors */
#else
*rpc = *rpp; /* copy 'proc' struct */
#endif
rpc->p_nr = m_ptr->PR_PROC_NR; /* this was obliterated by copy */
#if TEMP_CODE
rpc->p_ntf_q = NULL; /* remove pending notifications */
#endif
/* Only one in group should have SIGNALED, child doesn't inherit tracing. */
rpc->p_rts_flags |= NO_MAP; /* inhibit process from running */

View file

@ -6,8 +6,8 @@
* 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)
* m1_p2: I_VAL_PTR2 (second, optional pointer)
* m1_i2: I_VAL_LEN2 (second length or process nr)
*
* Author:
* Jorrit N. Herder <jnherder@cs.vu.nl>
@ -29,26 +29,26 @@ register message *m_ptr; /* pointer to request message */
phys_bytes dst_phys;
int proc_nr, nr;
/* Set source address and length based on request type. */
/* Set source address and length based on request type. */
switch (m_ptr->I_REQUEST) {
case GET_MACHINE: {
length = sizeof(struct machine);
src_phys = vir2phys(&machine);
break;
length = sizeof(struct machine);
src_phys = vir2phys(&machine);
break;
}
case GET_KINFO: {
length = sizeof(struct kinfo);
src_phys = vir2phys(&kinfo);
break;
length = sizeof(struct kinfo);
src_phys = vir2phys(&kinfo);
break;
}
case GET_IMAGE: {
length = sizeof(struct system_image) * NR_BOOT_PROCS;
src_phys = vir2phys(image);
length = sizeof(struct system_image) * NR_BOOT_PROCS;
src_phys = vir2phys(image);
break;
}
case GET_IRQHOOKS: {
length = sizeof(struct irq_hook) * NR_IRQ_HOOKS;
src_phys = vir2phys(irq_hooks);
length = sizeof(struct irq_hook) * NR_IRQ_HOOKS;
src_phys = vir2phys(irq_hooks);
break;
}
case GET_SCHEDINFO: {
@ -58,37 +58,36 @@ register message *m_ptr; /* pointer to request message */
*/
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);
dst_phys = numap_local(m_ptr->m_source, (vir_bytes) m_ptr->I_VAL_PTR2,
length);
if (src_phys == 0 || dst_phys == 0) return(EFAULT);
phys_copy(src_phys, dst_phys, length);
/* fall through */
}
case GET_PROCTAB: {
length = sizeof(struct proc) * (NR_PROCS + NR_TASKS);
src_phys = vir2phys(proc);
length = sizeof(struct proc) * (NR_PROCS + NR_TASKS);
src_phys = vir2phys(proc);
break;
}
case GET_PRIVTAB: {
length = sizeof(struct priv) * (NR_SYS_PROCS);
src_phys = vir2phys(priv);
length = sizeof(struct priv) * (NR_SYS_PROCS);
src_phys = vir2phys(priv);
break;
}
case GET_PROC: {
nr = (m_ptr->I_KEY_LEN == SELF) ? m_ptr->m_source : m_ptr->I_KEY_LEN;
if (! isokprocn(nr)) return(EINVAL); /* validate request */
length = sizeof(struct proc);
src_phys = vir2phys(proc_addr(nr));
nr = (m_ptr->I_VAL_LEN2 == SELF) ? m_ptr->m_source : m_ptr->I_VAL_LEN2;
if (! isokprocn(nr)) return(EINVAL); /* validate request */
length = sizeof(struct proc);
src_phys = vir2phys(proc_addr(nr));
break;
}
case GET_MONPARAMS: {
src_phys = kinfo.params_base; /* already is a physical */
length = kinfo.params_size;
break;
src_phys = kinfo.params_base; /* already is a physical */
length = kinfo.params_size;
break;
}
case GET_RANDOMNESS: {
static struct randomness copy; /* copy to keep counters */
static struct randomness copy; /* copy to keep counters */
int i;
copy = krandom;
@ -107,9 +106,9 @@ register message *m_ptr; /* pointer to request message */
}
#if DEBUG_TIME_LOCKS
case GET_LOCKTIMING: {
length = sizeof(timingdata);
src_phys = vir2phys(timingdata);
break;
length = sizeof(timingdata);
src_phys = vir2phys(timingdata);
break;
}
#endif
default:

View file

@ -1,20 +1,10 @@
/* The system call that is implemented in this file:
* SYS_SIGCTL # signal handling functionality
* m_type: SYS_GETKSIG
*
* The parameters and types for this system call are:
* SIG_REQUEST # request to perform (long)
* SIG_PROC # process to signal/ pending (int)
* SIG_CTXT_PTR # pointer to sigcontext structure (pointer)
* SIG_FLAGS # flags for S_SIGRETURN call (int)
* SIG_MAP # bit map with pending signals (long)
* SIG_NUMBER # signal number to send to process (int)
* The parameters for this system call are:
* m2_i1: SIG_PROC # process with pending signals
* m2_l1: SIG_MAP # bit map with pending signals
*
* Supported request types are in the parameter SIG_REQUEST:
* S_GETSIG # get a pending kernel signal
* S_ENDSIG # signal has been processed
* S_SENDSIG # deliver a POSIX-style signal
* S_SIGRETURN # return from a POSIX-style signal
* S_KILL # send a signal to a process
*/
#include "../system.h"
@ -32,16 +22,18 @@ message *m_ptr; /* pointer to request message */
/* PM is ready to accept signals and repeatedly does a system call to get
* one. Find a process with pending signals. If no signals are available,
* return NONE in the process number field.
* It is not sufficient to ready the process when PM is informed, because
* PM can block waiting for FS to do a core dump.
*/
register struct proc *rp;
/* Find the next process with pending signals. */
for (rp = BEG_USER_ADDR; rp < END_PROC_ADDR; rp++) {
if (rp->p_rts_flags & SIGNALED) {
m_ptr->SIG_PROC = rp->p_nr;
m_ptr->SIG_MAP = rp->p_pending;
sigemptyset(&rp->p_pending); /* ball is in PM's court */
rp->p_rts_flags &= ~SIGNALED; /* blocked by SIG_PENDING */
m_ptr->SIG_PROC = rp->p_nr; /* store signaled process */
m_ptr->SIG_MAP = rp->p_pending; /* pending signals map */
sigemptyset(&rp->p_pending); /* ball is in PM's court */
rp->p_rts_flags &= ~SIGNALED; /* blocked by SIG_PENDING */
return(OK);
}
}

View file

@ -37,15 +37,15 @@ register message *m_ptr; /* pointer to request message */
/* Enable or disable IRQs. This is straightforward. */
case IRQ_ENABLE:
case IRQ_DISABLE:
if (irq_hook_id >= NR_IRQ_HOOKS ||
irq_hooks[irq_hook_id].proc_nr == NONE) return(EINVAL);
if (irq_hook_id >= NR_IRQ_HOOKS ||
irq_hooks[irq_hook_id].proc_nr == NONE) return(EINVAL);
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;
/* 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.
@ -53,10 +53,7 @@ register message *m_ptr; /* pointer to request message */
case IRQ_SETPOLICY:
/* Check if IRQ line is acceptable. */
if (irq_vec < 0 || irq_vec >= NR_IRQ_VECTORS) {
kprintf("ST: irq line %d is not acceptable!\n", irq_vec);
return(EINVAL);
}
if (irq_vec < 0 || irq_vec >= NR_IRQ_VECTORS) return(EINVAL);
/* Find a free IRQ hook for this mapping. */
hook_ptr = NULL;
@ -77,18 +74,16 @@ register message *m_ptr; /* pointer to request message */
m_ptr->IRQ_HOOK_ID = irq_hook_id + 1;
break;
case IRQ_RMPOLICY:
if (irq_hook_id >= NR_IRQ_HOOKS ||
irq_hooks[irq_hook_id].proc_nr == NONE) {
r = EINVAL;
} else {
if (m_ptr->m_source != irq_hooks[irq_hook_id].proc_nr) {
r = EPERM;
} else {
r = rm_irq_handler(irq_vec, irq_hooks[irq_hook_id].id);
}
}
break;
case IRQ_RMPOLICY:
if (irq_hook_id >= NR_IRQ_HOOKS ||
irq_hooks[irq_hook_id].proc_nr == NONE) {
return(EINVAL);
} else if (m_ptr->m_source != irq_hooks[irq_hook_id].proc_nr) {
return(EPERM);
} else {
r = rm_irq_handler(irq_vec, irq_hooks[irq_hook_id].id);
}
break;
default:
r = EINVAL; /* invalid IRQ_REQUEST */

View file

@ -1,20 +1,9 @@
/* The system call that is implemented in this file:
* SYS_SIGCTL # signal handling functionality
* m_type: SYS_KILL
*
* The parameters and types for this system call are:
* SIG_REQUEST # request to perform (long)
* SIG_PROC # process to signal/ pending (int)
* SIG_CTXT_PTR # pointer to sigcontext structure (pointer)
* SIG_FLAGS # flags for S_SIGRETURN call (int)
* SIG_MAP # bit map with pending signals (long)
* SIG_NUMBER # signal number to send to process (int)
*
* Supported request types are in the parameter SIG_REQUEST:
* S_GETSIG # get a pending kernel signal
* S_ENDSIG # signal has been processed
* S_SENDSIG # deliver a POSIX-style signal
* S_SIGRETURN # return from a POSIX-style signal
* S_KILL # send a signal to a process
* The parameters for this system call are:
* m2_i1: SIG_PROC # process to signal/ pending
* m2_i2: SIG_NUMBER # signal number to send to process
*/
#include "../system.h"
@ -29,11 +18,27 @@
PUBLIC int do_kill(m_ptr)
message *m_ptr; /* pointer to request message */
{
/* Handle sys_kill(). Cause a signal to be sent to a process via PM.
* Note that this has nothing to do with the kill (2) system call, this
* is how the FS (and possibly other servers) get access to cause_sig.
/* Handle sys_kill(). Cause a signal to be sent to a process. The PM is the
* central server where all signals are processed and handler policies can
* be registered. Any request, except for PM requests, is added to the map
* of pending signals and the PM is informed about the new signal.
* Since system servers cannot use normal POSIX signal handlers (because they
* are usually blocked on a RECEIVE), they can request the PM to transform
* signals into messages. This is done by the PM with a call to sys_kill().
*/
cause_sig(m_ptr->SIG_PROC, m_ptr->SIG_NUMBER);
proc_nr_t proc_nr = m_ptr->SIG_PROC;
int sig_nr = m_ptr->SIG_NUMBER;
if (! isokprocn(proc_nr) || sig_nr > _NSIG) return(EINVAL);
if (m_ptr->m_source == PM_PROC_NR) {
/* Directly send signal notification to a system process. */
if (! (priv(proc_addr(proc_nr))->s_flags & SYS_PROC)) return(EPERM);
send_sig(proc_nr, sig_nr);
} else {
/* Set pending signal to be processed by the PM. */
cause_sig(proc_nr, sig_nr);
}
return(OK);
}

View file

@ -3,7 +3,7 @@
*
* 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)
* m1_p1: PR_MEM_PTR (pointer to the new memory map)
*/
#include "../system.h"
@ -16,24 +16,21 @@ PUBLIC int do_newmap(m_ptr)
message *m_ptr; /* pointer to request message */
{
/* Handle sys_newmap(). Fetch the memory map from PM. */
register struct proc *rp;
phys_bytes src_phys;
register struct proc *rp; /* process whose map is to be loaded */
int caller; /* whose space has the new map (usually PM) */
int k; /* process whose map is to be loaded */
int old_flags; /* value of flags before modification */
struct mem_map *map_ptr; /* virtual address of map inside caller (PM) */
phys_bytes src_phys; /* physical address of map at the PM */
int old_flags; /* value of flags before modification */
/* Extract message parameters and copy new memory map from PM. */
caller = m_ptr->m_source;
k = m_ptr->PR_PROC_NR;
map_ptr = (struct mem_map *) m_ptr->PR_MEM_PTR;
if (!isokprocn(k)) return(EINVAL);
rp = proc_addr(k); /* ptr to entry of user getting new map */
if (! isokprocn(m_ptr->PR_PROC_NR)) return(EINVAL);
rp = proc_addr(m_ptr->PR_PROC_NR);
/* Copy the map from PM. */
src_phys = umap_local(proc_addr(caller), D, (vir_bytes) map_ptr,
sizeof(rp->p_memmap));
sizeof(rp->p_memmap));
if (src_phys == 0) return(EFAULT);
phys_copy(src_phys,vir2phys(rp->p_memmap),(phys_bytes)sizeof(rp->p_memmap));

View file

@ -44,8 +44,8 @@ register message *m_ptr; /* pointer to request message */
}
} 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;
case DIO_BYTE: phys_outsb(port, phys_buf, count); break;
case DIO_WORD: phys_outsw(port, phys_buf, count); break;
default: return(EINVAL);
}
}

View file

@ -37,13 +37,13 @@ register message *m_ptr; /* pointer to request message */
rp = proc_addr(m_ptr->m_source);
index = -1;
for (i=0; i < NR_REMOTE_SEGS; i++) {
if (! rp->p_priv->s_farmem[i].in_use) {
index = i;
rp->p_priv->s_farmem[i].in_use = TRUE;
rp->p_priv->s_farmem[i].mem_phys = phys;
rp->p_priv->s_farmem[i].mem_len = size;
break;
}
if (! rp->p_priv->s_farmem[i].in_use) {
index = i;
rp->p_priv->s_farmem[i].in_use = TRUE;
rp->p_priv->s_farmem[i].mem_phys = phys;
rp->p_priv->s_farmem[i].mem_len = size;
break;
}
}
if (index < 0) return(ENOSPC);
@ -63,7 +63,7 @@ register message *m_ptr; /* pointer to request message */
USER_PRIVILEGE);
selector = ((EXTRA_LDT_INDEX+i)*0x08) | (1*0x04) | USER_PRIVILEGE;
offset = 0;
result = OK;
result = OK;
} else {
init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX+i], phys & ~0xFFFF, 0,
USER_PRIVILEGE);

View file

@ -1,20 +1,10 @@
/* The system call that is implemented in this file:
* SYS_SIGCTL # signal handling functionality
* m_type: SYS_SIGRETURN
*
* The parameters and types for this system call are:
* SIG_REQUEST # request to perform (long)
* SIG_PROC # process to signal/ pending (int)
* SIG_CTXT_PTR # pointer to sigcontext structure (pointer)
* SIG_FLAGS # flags for S_SIGRETURN call (int)
* SIG_MAP # bit map with pending signals (long)
* SIG_NUMBER # signal number to send to process (int)
* The parameters for this system call are:
* m2_i1: SIG_PROC # process returning from handler
* m2_p1: SIG_CTXT_PTR # pointer to sigcontext structure
*
* Supported request types are in the parameter SIG_REQUEST:
* S_GETSIG # get a pending kernel signal
* S_ENDSIG # signal has been processed
* S_SENDSIG # deliver a POSIX-style signal
* S_SIGRETURN # return from a POSIX-style signal
* S_KILL # send a signal to a process
*/
#include "../system.h"

View file

@ -1,20 +1,11 @@
/* The system call that is implemented in this file:
* SYS_SIGCTL # signal handling functionality
* m_type: SYS_SIGSEND
*
* The parameters and types for this system call are:
* SIG_REQUEST # request to perform (long)
* SIG_PROC # process to signal/ pending (int)
* SIG_CTXT_PTR # pointer to sigcontext structure (pointer)
* SIG_FLAGS # flags for S_SIGRETURN call (int)
* SIG_MAP # bit map with pending signals (long)
* SIG_NUMBER # signal number to send to process (int)
* The parameters for this system call are:
* m2_i1: SIG_PROC # process to call signal handler
* m2_p1: SIG_CTXT_PTR # pointer to sigcontext structure
* m2_i3: SIG_FLAGS # flags for S_SIGRETURN call
*
* Supported request types are in the parameter SIG_REQUEST:
* S_GETSIG # get a pending kernel signal
* S_ENDSIG # signal has been processed
* S_SENDSIG # deliver a POSIX-style signal
* S_SIGRETURN # return from a POSIX-style signal
* S_KILL # send a signal to a process
*/
#include "../system.h"

View file

@ -48,24 +48,24 @@ register message *m_ptr; /* pointer to request message */
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);
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. */

View file

@ -1,9 +1,5 @@
/* This file contains a collection of miscellaneous procedures:
* panic abort MINIX due to a fatal error
* safe_lock lock the kernel, use in combination with safe_unlock
* safe_unlock unlock the kernel, but prevent breaking nested locks
* alloc_bit bit map manipulation
* free_bit bit map manipulation
*/
#include "kernel.h"
@ -12,33 +8,6 @@
#include <minix/com.h>
PRIVATE int relock_count = 0;
/*===========================================================================*
* safe_lock *
*===========================================================================*/
PUBLIC void safe_lock(c,v)
int c;
char *v;
{
if(!(read_cpu_flags() & X86_FLAG_I)) {
relock_count++;
} else {
intr_disable();
}
}
/*===========================================================================*
* safe_unlock *
*===========================================================================*/
PUBLIC void safe_unlock(void)
{
if(! relock_count) {
intr_enable();
} else {
relock_count--;
}
}
/*===========================================================================*
* panic *
@ -49,8 +18,7 @@ int n;
{
/* The system has run aground of a fatal kernel error. Terminate execution. */
static int panicking = 0;
if (panicking ++) /* prevent recursive panics */
return;
if (panicking ++) return; /* prevent recursive panics */
if (s != NULL) {
kprintf("\nKernel panic: %s", karg(s));
@ -62,6 +30,7 @@ int n;
#if TEMP_CODE
/*===========================================================================*
* free_bit *
@ -113,3 +82,4 @@ bit_t nr_bits;
return(-1);
}
#endif