*
* 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
#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 */
/*===========================================================================*
*===========================================================================*/
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. */
*/
unsigned count;
- /* lock(10, "read_clock"); */
outb(TIMER_MODE, LATCH_COUNT);
count = inb(TIMER0);
count |= (inb(TIMER0) << 8);
- /* unlock(10); */
return count;
}
#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 */
#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.
#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
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)
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);
}
}
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);
/* 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);
}
/*==========================================================================*
/* 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
/* 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 */
#include "kernel.h"
+#include <signal.h>
#include <minix/com.h>
#define isdigit(c) ((unsigned) ((c) - '0') < (unsigned) 10)
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);
}
}
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.
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 */
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.
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)
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
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;
* 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;
#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)
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) );
+++ /dev/null
-/* 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 */
-
*
* 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
/* 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 */
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. */
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 */
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 */
}
while (rc->p_ntf_q != NULL) {
i = (int) (rc->p_ntf_q - ¬ify_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;
}
}
+/*===========================================================================*
+ * 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 *
*===========================================================================*/
* 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;
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);
}
}
}
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;
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. */
#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) );
$(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) \
$(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
-#include "../system.h"
-#include <unistd.h>
-
-
/* The system call implemented in this file:
* m_type: SYS_ABORT
*
* 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
/*===========================================================================*
* 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;
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);
}
* 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"
/* 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 {
{
/* 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);
}
/* 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) &&
/* 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) );
/* 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"
*
* 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)
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)
#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 */
* 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>
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: {
*/
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;
}
#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:
/* 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"
/* 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);
}
}
/* 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.
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;
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 */
/* 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"
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);
}
*
* 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"
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));
}
} 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);
}
}
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);
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);
/* 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"
/* 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"
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. */
/* 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"
#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 *
{
/* 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));
+#if TEMP_CODE
/*===========================================================================*
* free_bit *
return(-1);
}
+#endif