AT driver is not modified (debugging only);
TTY: select and revive with new notify and FS call back; kernel: removed old notify code; removed ugly prepare_shutdown timer kputc: don't send to FS if PRINTF_PROC fails
This commit is contained in:
parent
28958cca35
commit
fe0dcb5c00
|
@ -14,7 +14,7 @@ MAKE = exec make
|
|||
CC = exec cc
|
||||
CFLAGS = -I$i
|
||||
LDFLAGS = -i
|
||||
LIBS = -lsys -lsysutil -ltimers
|
||||
LIBS = -lsysutil -lsys -ltimers
|
||||
|
||||
OBJ = at_wini.o
|
||||
LIBDRIVER = $d/libdriver/driver.o $d/libdriver/drvlib.o
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <minix/keymap.h>
|
||||
#include <sys/ioc_disk.h>
|
||||
|
||||
|
||||
#if ENABLE_AT_WINI
|
||||
|
||||
#define ATAPI_DEBUG 0 /* To debug ATAPI code. */
|
||||
|
|
|
@ -11,7 +11,7 @@ m = $i/minix
|
|||
CC = exec cc
|
||||
CFLAGS = -I$i
|
||||
LDFLAGS = -i
|
||||
LIBS = -lsys -lsysutil
|
||||
LIBS = -lsysutil -lsys
|
||||
|
||||
OBJECTS = driver.o drvlib.o
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "drvlib.h"
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
/* Extended partition? */
|
||||
#define ext_part(s) ((s) == 0x05 || (s) == 0x0F)
|
||||
|
||||
|
|
|
@ -194,6 +194,7 @@ int try;
|
|||
|
||||
/* Reply to the writer if all output is finished or if an error occured. */
|
||||
if (tp->tty_outleft == 0 || result != OK) {
|
||||
/* REVIVE is not possible. I/O on memory mapped consoles finishes. */
|
||||
tty_reply(tp->tty_outrepcode, tp->tty_outcaller, tp->tty_outproc,
|
||||
tp->tty_outcum);
|
||||
tp->tty_outcum = 0;
|
||||
|
|
|
@ -166,7 +166,6 @@ tty_t *tp;
|
|||
int try;
|
||||
{
|
||||
/* Process characters from the circular keyboard buffer. */
|
||||
|
||||
char buf[3];
|
||||
int scode;
|
||||
unsigned ch;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#define NEW_REVIVE 1
|
||||
/* This file contains the tesminal driver, both for the IBM console and regular
|
||||
* ASCII terminals. It handles only the device-independent part of a TTY, the
|
||||
* device dependent parts are in console.c, rs232.c, etc. This file contains
|
||||
|
@ -26,7 +27,7 @@
|
|||
* DEV_OPEN: a tty line has been opened
|
||||
* DEV_CLOSE: a tty line has been closed
|
||||
* DEV_SELECT: start select notification request
|
||||
* DEV_SELECT_CAN: cancel select notification
|
||||
* DEV_STATUS: FS wants to know status for SELECT or REVIVE
|
||||
* CANCEL: terminate a previous incomplete system call immediately
|
||||
*
|
||||
* m_type TTY_LINE PROC_NR COUNT TTY_SPEK TTY_FLAGS ADDRESS
|
||||
|
@ -45,6 +46,8 @@
|
|||
* |-------------+---------+---------+---------+---------+---------+---------|
|
||||
* | DEV_CLOSE |minor dev| proc nr | | | | |
|
||||
* |-------------+---------+---------+---------+---------+---------+---------|
|
||||
* | DEV_STATUS | | | | | | |
|
||||
* |-------------+---------+---------+---------+---------+---------+---------|
|
||||
* | CANCEL |minor dev| proc nr | | | | |
|
||||
* ---------------------------------------------------------------------------
|
||||
*
|
||||
|
@ -112,6 +115,7 @@ FORWARD _PROTOTYPE( void do_close, (tty_t *tp, message *m_ptr) );
|
|||
FORWARD _PROTOTYPE( void do_read, (tty_t *tp, message *m_ptr) );
|
||||
FORWARD _PROTOTYPE( void do_write, (tty_t *tp, message *m_ptr) );
|
||||
FORWARD _PROTOTYPE( void do_select, (tty_t *tp, message *m_ptr) );
|
||||
FORWARD _PROTOTYPE( void do_status, (message *m_ptr) );
|
||||
FORWARD _PROTOTYPE( void in_transfer, (tty_t *tp) );
|
||||
FORWARD _PROTOTYPE( int tty_echo, (tty_t *tp, int ch) );
|
||||
FORWARD _PROTOTYPE( void rawecho, (tty_t *tp, int ch) );
|
||||
|
@ -208,12 +212,10 @@ PUBLIC void main(void)
|
|||
sigset_t sigset = (sigset_t) tty_mess.NOTIFY_ARG;
|
||||
if (sigismember(&sigset, SIGKSTOP)) {
|
||||
cons_stop(); /* switch to primary console */
|
||||
#if DEAD_CODE
|
||||
if (irq_hook_id != -1) {
|
||||
sys_irqdisable(&irq_hook_id);
|
||||
sys_irqrmpolicy(KEYBOARD_IRQ, &irq_hook_id);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (sigismember(&sigset, SIGTERM)) cons_stop();
|
||||
if (sigismember(&sigset, SIGKMESS)) do_new_kmess(&tty_mess);
|
||||
|
@ -233,9 +235,14 @@ PUBLIC void main(void)
|
|||
; /* do nothing; end switch */
|
||||
}
|
||||
|
||||
/* Only device requests should get to this point.
|
||||
* Check the minor device number.
|
||||
/* Only device requests should get to this point. All requests,
|
||||
* except DEV_STATUS, have a minor device number. Check this
|
||||
* exception and get the minor device number otherwise.
|
||||
*/
|
||||
if (tty_mess.m_type == DEV_STATUS) {
|
||||
do_status(&tty_mess);
|
||||
continue;
|
||||
}
|
||||
line = tty_mess.TTY_LINE;
|
||||
if ((line - CONS_MINOR) < NR_CONS) {
|
||||
tp = tty_addr(line - CONS_MINOR);
|
||||
|
@ -283,6 +290,73 @@ PUBLIC void main(void)
|
|||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* do_status *
|
||||
*===========================================================================*/
|
||||
PRIVATE void do_status(m_ptr)
|
||||
message *m_ptr;
|
||||
{
|
||||
register struct tty *tp;
|
||||
int event_found;
|
||||
int status;
|
||||
int ops;
|
||||
|
||||
/* Check for select or revive events on any of the ttys. If we found an,
|
||||
* event return a single status message for it. The FS will make another
|
||||
* call to see if there is more.
|
||||
*/
|
||||
event_found = 0;
|
||||
for (tp = FIRST_TTY; tp < END_TTY; tp++) {
|
||||
if ((ops = select_try(tp, tp->tty_select_ops)) &&
|
||||
tp->tty_select_proc == m_ptr->m_source) {
|
||||
|
||||
/* I/O for a selected minor device is ready. */
|
||||
m_ptr->m_type = DEV_IO_READY;
|
||||
m_ptr->DEV_MINOR = tp->tty_index;
|
||||
m_ptr->DEV_SEL_OPS = ops;
|
||||
|
||||
tp->tty_select_ops &= ~ops; /* unmark select event */
|
||||
event_found = 1;
|
||||
break;
|
||||
}
|
||||
else if (tp->tty_inrevived && tp->tty_incaller == m_ptr->m_source) {
|
||||
|
||||
/* Suspended request finished. Send a REVIVE. */
|
||||
m_ptr->m_type = DEV_REVIVE;
|
||||
m_ptr->REP_PROC_NR = tp->tty_inproc;
|
||||
m_ptr->REP_STATUS = tp->tty_incum;
|
||||
|
||||
tp->tty_inleft = tp->tty_incum = 0;
|
||||
tp->tty_inrevived = 0; /* unmark revive event */
|
||||
event_found = 1;
|
||||
break;
|
||||
}
|
||||
else if (tp->tty_outrevived && tp->tty_outcaller == m_ptr->m_source) {
|
||||
|
||||
/* Suspended request finished. Send a REVIVE. */
|
||||
m_ptr->m_type = DEV_REVIVE;
|
||||
m_ptr->REP_PROC_NR = tp->tty_outproc;
|
||||
m_ptr->REP_STATUS = tp->tty_outcum;
|
||||
|
||||
tp->tty_outcum = 0;
|
||||
tp->tty_outrevived = 0; /* unmark revive event */
|
||||
event_found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! event_found) {
|
||||
/* No events of interest were found. Return an empty message. */
|
||||
m_ptr->m_type = DEV_NO_STATUS;
|
||||
}
|
||||
|
||||
/* Almost done. Send back the reply message to the caller. */
|
||||
if ((status = send(m_ptr->m_source, m_ptr)) != OK) {
|
||||
panic("TTY","send in do_status failed, status\n", status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* do_read *
|
||||
*===========================================================================*/
|
||||
|
@ -720,7 +794,7 @@ PUBLIC int select_try(struct tty *tp, int ops)
|
|||
{
|
||||
int ready_ops = 0;
|
||||
|
||||
/* special case. if line is hung up, no operations will block.
|
||||
/* Special case. If line is hung up, no operations will block.
|
||||
* (and it can be seen as an exceptional condition.)
|
||||
*/
|
||||
if (tp->tty_termios.c_ospeed == B0) {
|
||||
|
@ -758,6 +832,7 @@ PUBLIC int select_try(struct tty *tp, int ops)
|
|||
|
||||
PUBLIC int select_retry(struct tty *tp)
|
||||
{
|
||||
#if DEAD_CODE
|
||||
int ops;
|
||||
if((ops = select_try(tp, tp->tty_select_ops))) {
|
||||
message m;
|
||||
|
@ -767,6 +842,10 @@ PUBLIC int select_retry(struct tty *tp)
|
|||
notify(tp->tty_select_proc, &m);
|
||||
tp->tty_select_ops &= ~ops;
|
||||
}
|
||||
#else
|
||||
if (select_try(tp, tp->tty_select_ops))
|
||||
alert(tp->tty_select_proc);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
@ -812,9 +891,20 @@ tty_t *tp; /* TTY to check for events. */
|
|||
|
||||
/* Reply if enough bytes are available. */
|
||||
if (tp->tty_incum >= tp->tty_min && tp->tty_inleft > 0) {
|
||||
#if NEW_REVIVE
|
||||
if (tp->tty_inrepcode == REVIVE) {
|
||||
alert(tp->tty_incaller);
|
||||
tp->tty_inrevived = 1;
|
||||
} else {
|
||||
tty_reply(tp->tty_inrepcode, tp->tty_incaller,
|
||||
tp->tty_inproc, tp->tty_incum);
|
||||
tp->tty_inleft = tp->tty_incum = 0;
|
||||
}
|
||||
#else
|
||||
tty_reply(tp->tty_inrepcode, tp->tty_incaller, tp->tty_inproc,
|
||||
tp->tty_incum);
|
||||
tp->tty_inleft = tp->tty_incum = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -878,9 +968,20 @@ register tty_t *tp; /* pointer to terminal to read from */
|
|||
|
||||
/* Usually reply to the reader, possibly even if incum == 0 (EOF). */
|
||||
if (tp->tty_inleft == 0) {
|
||||
#if NEW_REVIVE
|
||||
if (tp->tty_inrepcode == REVIVE) {
|
||||
alert(tp->tty_incaller);
|
||||
tp->tty_inrevived = 1;
|
||||
} else {
|
||||
tty_reply(tp->tty_inrepcode, tp->tty_incaller,
|
||||
tp->tty_inproc, tp->tty_incum);
|
||||
tp->tty_inleft = tp->tty_incum = 0;
|
||||
}
|
||||
#else
|
||||
tty_reply(tp->tty_inrepcode, tp->tty_incaller, tp->tty_inproc,
|
||||
tp->tty_incum);
|
||||
tp->tty_inleft = tp->tty_incum = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1369,12 +1470,12 @@ int proc_nr; /* to whom should the reply go? */
|
|||
int status; /* reply code */
|
||||
{
|
||||
/* Send a reply to a process that wanted to read or write data. */
|
||||
|
||||
message tty_mess;
|
||||
|
||||
tty_mess.m_type = code;
|
||||
tty_mess.REP_PROC_NR = proc_nr;
|
||||
tty_mess.REP_STATUS = status;
|
||||
|
||||
if ((status = send(replyee, &tty_mess)) != OK) {
|
||||
panic("TTY","tty_reply failed, status\n", status);
|
||||
}
|
||||
|
|
|
@ -46,12 +46,14 @@ typedef struct tty {
|
|||
|
||||
/* Information about incomplete I/O requests is stored here. */
|
||||
char tty_inrepcode; /* reply code, TASK_REPLY or REVIVE */
|
||||
char tty_inrevived; /* set to 1 if revive callback is pending */
|
||||
char tty_incaller; /* process that made the call (usually FS) */
|
||||
char tty_inproc; /* process that wants to read from tty */
|
||||
vir_bytes tty_in_vir; /* virtual address where data is to go */
|
||||
int tty_inleft; /* how many chars are still needed */
|
||||
int tty_incum; /* # chars input so far */
|
||||
char tty_outrepcode; /* reply code, TASK_REPLY or REVIVE */
|
||||
char tty_outrevived; /* set to 1 if revive callback is pending */
|
||||
char tty_outcaller; /* process that made the call (usually FS) */
|
||||
char tty_outproc; /* process that wants to write to tty */
|
||||
vir_bytes tty_out_vir; /* virtual address where data comes from */
|
||||
|
@ -122,6 +124,7 @@ _PROTOTYPE( void tty_wakeup, (clock_t now) );
|
|||
_PROTOTYPE( void tty_reply, (int code, int replyee, int proc_nr,
|
||||
int status) );
|
||||
_PROTOTYPE( int tty_devnop, (struct tty *tp, int try) );
|
||||
_PROTOTYPE( int select_try, (struct tty *tp, int ops) );
|
||||
_PROTOTYPE( int select_retry, (struct tty *tp) );
|
||||
|
||||
/* rs232.c */
|
||||
|
|
|
@ -106,7 +106,7 @@
|
|||
* Directly sending it to TTY only displays the output. Sending it to the
|
||||
* log driver will cause the diagnostics to be buffered and displayed.
|
||||
*/
|
||||
#define PRINTF_PROC LOG_PROC_NR /* TTY or LOG_PROC_NR */
|
||||
#define PRINTF_PROC TTY /* TTY or LOG_PROC_NR */
|
||||
|
||||
/* NR_CONS, NR_RS_LINES, and NR_PTYS determine the number of terminals the
|
||||
* system can handle.
|
||||
|
|
|
@ -197,7 +197,7 @@ irq_hook_t *hook;
|
|||
*/
|
||||
if ((next_timeout <= realtime) || (proc_ptr->p_sched_ticks <= 0)) {
|
||||
prev_ptr = proc_ptr; /* store running process */
|
||||
lock_alert(HARDWARE, CLOCK); /* send notification */
|
||||
lock_notify(HARDWARE, CLOCK); /* send notification */
|
||||
}
|
||||
return(1); /* reenable interrupts */
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
/* Buffer to gather randomness. This is used to generate a random stream by
|
||||
* the MEMORY driver when reading from /dev/random.
|
||||
*/
|
||||
#define RANDOM_ELEMENTS 64
|
||||
#define RANDOM_ELEMENTS 32
|
||||
|
||||
|
||||
/* This section contains defines for valuable system resources that are used
|
||||
|
@ -70,10 +70,6 @@
|
|||
#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
|
||||
|
|
|
@ -33,12 +33,6 @@ 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)
|
||||
|
||||
|
|
|
@ -17,11 +17,9 @@
|
|||
#define SEND 1 /* 0 0 0 1 : blocking send */
|
||||
#define RECEIVE 2 /* 0 0 1 0 : blocking receive */
|
||||
#define SENDREC 3 /* 0 0 1 1 : SEND + RECEIVE */
|
||||
#define ALERT 4 /* 0 1 0 0 : nonblocking notify */
|
||||
#define NOTIFY 4 /* 0 1 0 0 : nonblocking notify */
|
||||
#define ECHO 8 /* 1 0 0 0 : echo a message */
|
||||
|
||||
#define NOTIFY 16 /* 1 0 0 0 0 : temp */
|
||||
|
||||
/* The following bit masks determine what checks that should be done. */
|
||||
#define CHECK_PTR 0x0B /* 1 0 1 1 : validate message buffer */
|
||||
#define CHECK_DST 0x05 /* 0 1 0 1 : validate message destination */
|
||||
|
|
|
@ -184,16 +184,12 @@ PRIVATE void announce(void)
|
|||
/*==========================================================================*
|
||||
* prepare_shutdown *
|
||||
*==========================================================================*/
|
||||
PUBLIC void prepare_shutdown(tp)
|
||||
timer_t *tp;
|
||||
PUBLIC void prepare_shutdown(how)
|
||||
int how;
|
||||
{
|
||||
/* This function prepares to shutdown MINIX. It is called by a watchdog
|
||||
* timer if this is a normal abort so that the sys_abort() call can return
|
||||
* first. The timer structure passes the shutdown status as an argument.
|
||||
*/
|
||||
/* This function prepares to shutdown MINIX. */
|
||||
register struct proc *rp;
|
||||
static timer_t shutdown_timer;
|
||||
int how = tmr_arg(tp)->ta_int;
|
||||
message m;
|
||||
|
||||
/* Show debugging dumps on panics. Make sure that the TTY task is still
|
||||
|
|
140
kernel/proc.c
140
kernel/proc.c
|
@ -13,7 +13,7 @@
|
|||
* lock_sched: a process has run too long; schedule another one
|
||||
*
|
||||
* Changes:
|
||||
* , 2005 better protection in sys_call() (Jorrit N. Herder)
|
||||
* Jul 25, 2005 better protection in sys_call() (Jorrit N. Herder)
|
||||
* May 26, 2005 optimized message passing functions (Jorrit N. Herder)
|
||||
* May 24, 2005 new, queued NOTIFY system call (Jorrit N. Herder)
|
||||
* Oct 28, 2004 new, non-blocking SEND and RECEIVE (Jorrit N. Herder)
|
||||
|
@ -52,9 +52,7 @@ FORWARD _PROTOTYPE( int mini_send, (struct proc *caller_ptr, int dst,
|
|||
message *m_ptr, unsigned flags) );
|
||||
FORWARD _PROTOTYPE( int mini_receive, (struct proc *caller_ptr, int src,
|
||||
message *m_ptr, unsigned flags) );
|
||||
FORWARD _PROTOTYPE( int mini_alert, (struct proc *caller_ptr, int dst) );
|
||||
FORWARD _PROTOTYPE( int mini_notify, (struct proc *caller_ptr, int dst,
|
||||
message *m_ptr ) );
|
||||
FORWARD _PROTOTYPE( int mini_notify, (struct proc *caller_ptr, int dst) );
|
||||
|
||||
FORWARD _PROTOTYPE( void ready, (struct proc *rp) );
|
||||
FORWARD _PROTOTYPE( void unready, (struct proc *rp) );
|
||||
|
@ -62,14 +60,6 @@ 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); \
|
||||
|
@ -168,7 +158,8 @@ message *m_ptr; /* pointer to message in the caller's space */
|
|||
*/
|
||||
switch(function) {
|
||||
case SENDREC:
|
||||
caller_ptr->p_priv->s_flags |= SENDREC_BUSY;
|
||||
/* A flag is set so that notifications cannot interrupt SENDREC. */
|
||||
priv(caller_ptr)->s_flags |= SENDREC_BUSY;
|
||||
/* fall through */
|
||||
case SEND:
|
||||
result = mini_send(caller_ptr, src_dst, m_ptr, flags);
|
||||
|
@ -176,15 +167,12 @@ message *m_ptr; /* pointer to message in the caller's space */
|
|||
break; /* done, or SEND failed */
|
||||
} /* fall through for SENDREC */
|
||||
case RECEIVE:
|
||||
if(function == RECEIVE)
|
||||
caller_ptr->p_priv->s_flags &= ~SENDREC_BUSY;
|
||||
if (function == RECEIVE)
|
||||
priv(caller_ptr)->s_flags &= ~SENDREC_BUSY;
|
||||
result = mini_receive(caller_ptr, src_dst, m_ptr, flags);
|
||||
break;
|
||||
case ALERT:
|
||||
result = mini_alert(caller_ptr, src_dst);
|
||||
break;
|
||||
case NOTIFY:
|
||||
result = mini_notify(caller_ptr, src_dst, m_ptr);
|
||||
result = mini_notify(caller_ptr, src_dst);
|
||||
break;
|
||||
case ECHO:
|
||||
CopyMess(caller_ptr->p_nr, caller_ptr, m_ptr, caller_ptr, m_ptr);
|
||||
|
@ -278,7 +266,7 @@ unsigned flags; /* system call flags */
|
|||
if (!(caller_ptr->p_rts_flags & SENDING)) {
|
||||
|
||||
/* Check if there are pending notifications, except for SENDREC. */
|
||||
if (! (caller_ptr->p_priv->s_flags & SENDREC_BUSY)) {
|
||||
if (! (priv(caller_ptr)->s_flags & SENDREC_BUSY)) {
|
||||
|
||||
map = &priv(caller_ptr)->s_notify_pending;
|
||||
for (chunk=&map->chunk[0]; chunk<&map->chunk[NR_SYS_CHUNKS]; chunk++) {
|
||||
|
@ -297,34 +285,12 @@ unsigned flags; /* system call flags */
|
|||
CopyMess(src_proc_nr, proc_addr(HARDWARE), &m, caller_ptr, m_ptr);
|
||||
return(OK); /* report success */
|
||||
}
|
||||
|
||||
#if TEMP_CODE
|
||||
ntf_q_pp = &caller_ptr->p_ntf_q; /* get pointer pointer */
|
||||
while (*ntf_q_pp != NULL) {
|
||||
if (src == ANY || src == (*ntf_q_pp)->n_source) {
|
||||
/* Found notification. Assemble and copy message. */
|
||||
BuildOldMess(m, *ntf_q_pp);
|
||||
if (m.m_source == HARDWARE) {
|
||||
m.NOTIFY_ARG = caller_ptr->p_priv->s_int_pending;
|
||||
caller_ptr->p_priv->s_int_pending = 0;
|
||||
}
|
||||
CopyMess((*ntf_q_pp)->n_source, proc_addr(HARDWARE), &m,
|
||||
caller_ptr, m_ptr);
|
||||
/* Remove notification from queue and bit map. */
|
||||
bit_nr = (int) (*ntf_q_pp - ¬ify_buffer[0]);
|
||||
*ntf_q_pp = (*ntf_q_pp)->n_next;/* remove from queue */
|
||||
free_bit(bit_nr, notify_bitmap, NR_NOTIFY_BUFS);
|
||||
return(OK); /* report success */
|
||||
}
|
||||
ntf_q_pp = &(*ntf_q_pp)->n_next; /* proceed to next */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check caller queue. Use pointer pointers to keep code simple. */
|
||||
xpp = &caller_ptr->p_caller_q;
|
||||
while (*xpp != NIL_PROC) {
|
||||
if (src == ANY || src == proc_nr(*xpp)) {
|
||||
if (src == ANY || src == proc_nr(*xpp)) {
|
||||
/* Found acceptable message. Copy it and update status. */
|
||||
CopyMess((*xpp)->p_nr, *xpp, (*xpp)->p_messbuf, caller_ptr, m_ptr);
|
||||
if (((*xpp)->p_rts_flags &= ~SENDING) == 0) ready(*xpp);
|
||||
|
@ -333,7 +299,6 @@ unsigned flags; /* system call flags */
|
|||
}
|
||||
xpp = &(*xpp)->p_q_link; /* proceed to next */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* No suitable message is available or the caller couldn't send in SENDREC.
|
||||
|
@ -352,9 +317,9 @@ unsigned flags; /* system call flags */
|
|||
|
||||
|
||||
/*===========================================================================*
|
||||
* mini_alert *
|
||||
* mini_notify *
|
||||
*===========================================================================*/
|
||||
PRIVATE int mini_alert(caller_ptr, dst)
|
||||
PRIVATE int mini_notify(caller_ptr, dst)
|
||||
register struct proc *caller_ptr; /* sender of the notification */
|
||||
int dst; /* which process to notify */
|
||||
{
|
||||
|
@ -366,7 +331,7 @@ int dst; /* which process to notify */
|
|||
* can be both sending and receiving during a SENDREC system call.
|
||||
*/
|
||||
if ((dst_ptr->p_rts_flags & (RECEIVING|SENDING)) == RECEIVING &&
|
||||
!(dst_ptr->p_priv->s_flags & SENDREC_BUSY) &&
|
||||
! (priv(dst_ptr)->s_flags & SENDREC_BUSY) &&
|
||||
(dst_ptr->p_getfrom == ANY || dst_ptr->p_getfrom == caller_ptr->p_nr)) {
|
||||
|
||||
/* Destination is indeed waiting for a message. Assemble a notification
|
||||
|
@ -391,83 +356,10 @@ int dst; /* which process to notify */
|
|||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* mini_notify *
|
||||
*===========================================================================*/
|
||||
PRIVATE int mini_notify(caller_ptr, dst, m_ptr)
|
||||
register struct proc *caller_ptr; /* process trying to notify */
|
||||
int dst; /* which process to notify */
|
||||
message *m_ptr; /* pointer to message buffer */
|
||||
{
|
||||
register struct proc *dst_ptr = proc_addr(dst);
|
||||
register struct notification *ntf_p ;
|
||||
register struct notification **ntf_q_pp;
|
||||
int ntf_index;
|
||||
message ntf_mess;
|
||||
|
||||
/* Check to see if target is blocked waiting for this message. A process
|
||||
* can be both sending and receiving during a SENDREC system call.
|
||||
*/
|
||||
if ((dst_ptr->p_rts_flags & (RECEIVING|SENDING)) == RECEIVING &&
|
||||
(dst_ptr->p_getfrom == ANY || dst_ptr->p_getfrom == caller_ptr->p_nr)) {
|
||||
|
||||
/* Destination is indeed waiting for this message. Check if the source
|
||||
* is HARDWARE; this is a special case that gets the map of pending
|
||||
* interrupts as an argument. Then deliver the notification message.
|
||||
*/
|
||||
if (proc_nr(caller_ptr) == HARDWARE) {
|
||||
m_ptr->NOTIFY_ARG = priv(dst_ptr)->s_int_pending;
|
||||
priv(dst_ptr)->s_int_pending = 0;
|
||||
}
|
||||
|
||||
CopyMess(proc_nr(caller_ptr), caller_ptr, m_ptr, dst_ptr, dst_ptr->p_messbuf);
|
||||
dst_ptr->p_rts_flags &= ~RECEIVING; /* deblock destination */
|
||||
if (dst_ptr->p_rts_flags == 0) ready(dst_ptr);
|
||||
return(OK);
|
||||
}
|
||||
|
||||
/* 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)) {
|
||||
CopyMess(proc_nr(caller_ptr), caller_ptr, m_ptr,
|
||||
proc_addr(HARDWARE), &ntf_mess);
|
||||
m_ptr = &ntf_mess;
|
||||
}
|
||||
|
||||
/* Enqueue the message. Existing notifications with the same source
|
||||
* and type are overwritten with newer ones. New notifications that
|
||||
* are not yet on the list are added to the end.
|
||||
*/
|
||||
ntf_q_pp = &dst_ptr->p_ntf_q;
|
||||
while (*ntf_q_pp != NULL) {
|
||||
/* Replace notifications with same source and type. */
|
||||
if ((*ntf_q_pp)->n_type == m_ptr->NOTIFY_TYPE &&
|
||||
(*ntf_q_pp)->n_source == proc_nr(caller_ptr)) {
|
||||
(*ntf_q_pp)->n_flags = m_ptr->NOTIFY_FLAGS;
|
||||
(*ntf_q_pp)->n_arg = m_ptr->NOTIFY_ARG;
|
||||
return(OK);
|
||||
}
|
||||
ntf_q_pp = &(*ntf_q_pp)->n_next;
|
||||
}
|
||||
|
||||
/* Add to end of queue (found above). Get a free notification buffer. */
|
||||
if ((ntf_index = alloc_bit(notify_bitmap, NR_NOTIFY_BUFS)) < 0)
|
||||
return(ENOSPC);
|
||||
ntf_p = ¬ify_buffer[ntf_index]; /* get pointer to buffer */
|
||||
ntf_p->n_source = proc_nr(caller_ptr);/* store notification data */
|
||||
ntf_p->n_type = m_ptr->NOTIFY_TYPE;
|
||||
ntf_p->n_flags = m_ptr->NOTIFY_FLAGS;
|
||||
ntf_p->n_arg = m_ptr->NOTIFY_ARG;
|
||||
*ntf_q_pp = ntf_p; /* add to end of queue */
|
||||
ntf_p->n_next = NULL; /* mark new end of queue */
|
||||
return(OK);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* lock_notify *
|
||||
*==========================================================================*/
|
||||
PUBLIC int lock_alert(src, dst)
|
||||
PUBLIC int lock_notify(src, dst)
|
||||
int src; /* sender of the notification */
|
||||
int dst; /* who is to be notified */
|
||||
{
|
||||
|
@ -481,13 +373,13 @@ int dst; /* who is to be notified */
|
|||
|
||||
/* Exception or interrupt occurred, thus already locked. */
|
||||
if (k_reenter >= 0) {
|
||||
result = mini_alert(proc_addr(src), dst);
|
||||
result = mini_notify(proc_addr(src), dst);
|
||||
}
|
||||
|
||||
/* Call from task level, locking is required. */
|
||||
else {
|
||||
lock(0, "alert");
|
||||
result = mini_alert(proc_addr(src), dst);
|
||||
lock(0, "notify");
|
||||
result = mini_notify(proc_addr(src), dst);
|
||||
unlock(0);
|
||||
}
|
||||
return(result);
|
||||
|
|
|
@ -17,17 +17,15 @@ _PROTOTYPE( void reset_timer, (struct timer *tp) );
|
|||
|
||||
/* main.c */
|
||||
_PROTOTYPE( void main, (void) );
|
||||
_PROTOTYPE( void prepare_shutdown, (struct timer *tp) );
|
||||
_PROTOTYPE( void prepare_shutdown, (int how) );
|
||||
|
||||
/* utility.c */
|
||||
_PROTOTYPE( void kprintf, (const char *fmt, ...) );
|
||||
_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) );
|
||||
|
||||
/* proc.c */
|
||||
_PROTOTYPE( int sys_call, (int function, int src_dest, message *m_ptr) );
|
||||
_PROTOTYPE( int lock_alert, (int src, int dst) );
|
||||
_PROTOTYPE( int lock_notify, (int src, int dst) );
|
||||
_PROTOTYPE( int lock_send, (int dst, message *m_ptr) );
|
||||
_PROTOTYPE( void lock_ready, (struct proc *rp) );
|
||||
_PROTOTYPE( void lock_sched, (struct proc *rp) );
|
||||
|
|
|
@ -201,7 +201,7 @@ int source;
|
|||
* the lowest bytes because the highest bytes won't differ that much.
|
||||
*/
|
||||
int r_next;
|
||||
unsigned long tsc_high;
|
||||
unsigned long tsc_high, tsc_low;
|
||||
|
||||
/* On machines with the RDTSC (cycle counter read instruction - pentium
|
||||
* and up), use that for high-resolution raw entropy gathering. Otherwise,
|
||||
|
@ -214,12 +214,15 @@ int source;
|
|||
*/
|
||||
source %= RANDOM_SOURCES;
|
||||
r_next= krandom.bin[source].r_next;
|
||||
if(machine.processor > 486 && 0)
|
||||
read_tsc(&tsc_high, &krandom.bin[source].r_buf[r_next]);
|
||||
else
|
||||
krandom.bin[source].r_buf[r_next] = read_clock();
|
||||
if (krandom.bin[source].r_size < RANDOM_ELEMENTS)
|
||||
if(machine.processor > 486) {
|
||||
read_tsc(&tsc_high, &tsc_low);
|
||||
krandom.bin[source].r_buf[r_next] = tsc_low;
|
||||
} else {
|
||||
krandom.bin[source].r_buf[r_next] = read_clock();
|
||||
}
|
||||
if (krandom.bin[source].r_size < RANDOM_ELEMENTS) {
|
||||
krandom.bin[source].r_size ++;
|
||||
}
|
||||
krandom.bin[source].r_next = (r_next + 1 ) % RANDOM_ELEMENTS;
|
||||
}
|
||||
|
||||
|
@ -247,7 +250,7 @@ irq_hook_t *hook;
|
|||
priv(proc_addr(hook->proc_nr))->s_int_pending |= (1 << hook->irq);
|
||||
|
||||
/* Build notification message and return. */
|
||||
lock_alert(HARDWARE, hook->proc_nr);
|
||||
lock_notify(HARDWARE, hook->proc_nr);
|
||||
return(hook->policy & IRQ_REENABLE);
|
||||
}
|
||||
|
||||
|
@ -267,7 +270,7 @@ int sig_nr; /* signal to be sent, 1 to _NSIG */
|
|||
|
||||
rp = proc_addr(proc_nr);
|
||||
sigaddset(&priv(rp)->s_sig_pending, sig_nr);
|
||||
lock_alert(SYSTEM, proc_nr);
|
||||
lock_notify(SYSTEM, proc_nr);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ message *m_ptr; /* pointer to request message */
|
|||
* or ESC after debugging dumps).
|
||||
*/
|
||||
int how = m_ptr->ABRT_HOW;
|
||||
timer_t *tp;
|
||||
|
||||
/* See if the monitor is to run the specified instructions. */
|
||||
if (how == RBT_MONITOR) {
|
||||
|
@ -40,13 +39,8 @@ message *m_ptr; /* pointer to request message */
|
|||
phys_copy(src_phys, kinfo.params_base, (phys_bytes) length);
|
||||
}
|
||||
|
||||
/* Set a watchdog timer to shut down, so that this call returns first.
|
||||
* The timer will expire at the next clock tick, which can be any moment.
|
||||
* The CLOCK task is only scheduled when the SYSTEM task is done, though.
|
||||
*/
|
||||
tp = &priv(proc_addr(KERNEL))->s_alarm_timer;
|
||||
tmr_arg(tp)->ta_int = how; /* pass status as timer argument */
|
||||
set_timer(tp, get_uptime(), prepare_shutdown);
|
||||
/* Now prepare to shutdown MINIX. */
|
||||
prepare_shutdown(how);
|
||||
return(OK); /* pro-forma (really EDISASTER) */
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ timer_t *tp;
|
|||
* alarm. The process number is stored in timer argument 'ta_int'. Notify that
|
||||
* process with a notification message from CLOCK.
|
||||
*/
|
||||
lock_alert(CLOCK, tmr_arg(tp)->ta_int);
|
||||
lock_notify(CLOCK, tmr_arg(tp)->ta_int);
|
||||
}
|
||||
|
||||
#endif /* USE_SETALARM */
|
||||
|
|
|
@ -27,19 +27,6 @@ struct memory {
|
|||
phys_clicks size; /* size of memory chunk */
|
||||
};
|
||||
|
||||
typedef unsigned long notify_mask_t; /* bit mask for notifications */
|
||||
typedef short notify_type_t; /* notification type */
|
||||
typedef char notify_flags_t; /* notification flags */
|
||||
typedef int notify_arg_t; /* notification argument */
|
||||
|
||||
struct notification {
|
||||
proc_nr_t n_source; /* sender of notification */
|
||||
notify_type_t n_type; /* notification type */
|
||||
notify_arg_t n_arg; /* notification argument */
|
||||
notify_flags_t n_flags; /* notification flags */
|
||||
struct notification* n_next; /* pointer to next notification */
|
||||
};
|
||||
|
||||
/* The kernel outputs diagnostic messages in a circular buffer. */
|
||||
struct kmessages {
|
||||
int km_next; /* next index to write */
|
||||
|
@ -51,7 +38,7 @@ struct randomness {
|
|||
struct {
|
||||
int r_next; /* next index to write */
|
||||
int r_size; /* number of random elements */
|
||||
unsigned long r_buf[RANDOM_ELEMENTS]; /* buffer for random info */
|
||||
unsigned short r_buf[RANDOM_ELEMENTS]; /* buffer for random info */
|
||||
} bin[RANDOM_SOURCES];
|
||||
};
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@ int nr;
|
|||
{
|
||||
/* The system has run aground of a fatal kernel error. Terminate execution. */
|
||||
static int panicking = 0;
|
||||
timer_t *tp;
|
||||
if (panicking ++) return; /* prevent recursive panics */
|
||||
|
||||
if (mess != NULL) {
|
||||
|
@ -43,12 +42,8 @@ int nr;
|
|||
kprintf("\n",NO_NUM);
|
||||
}
|
||||
|
||||
/* Make a direct call to shutdown. Interface requires to pass the shutdown
|
||||
* status by means of a timer.
|
||||
*/
|
||||
tp = &priv(proc_addr(KERNEL))->s_alarm_timer;
|
||||
tmr_arg(tp)->ta_int = RBT_PANIC;
|
||||
prepare_shutdown(tp);
|
||||
/* Abort MINIX. */
|
||||
prepare_shutdown(RBT_PANIC);
|
||||
}
|
||||
|
||||
|
||||
|
@ -148,57 +143,3 @@ int c; /* character to append */
|
|||
}
|
||||
|
||||
|
||||
|
||||
#if TEMP_CODE
|
||||
|
||||
/*===========================================================================*
|
||||
* free_bit *
|
||||
*===========================================================================*/
|
||||
PUBLIC void free_bit(bit_nr, bitmap, nr_bits)
|
||||
bit_t bit_nr;
|
||||
bitchunk_t *bitmap;
|
||||
bit_t nr_bits;
|
||||
{
|
||||
bitchunk_t *chunk;
|
||||
if (bit_nr >= nr_bits) {
|
||||
kprintf("Warning, free_bit: %d illegal index\n", bit_nr);
|
||||
return;
|
||||
}
|
||||
chunk = &bitmap[(bit_nr/BITCHUNK_BITS)];
|
||||
*chunk &= ~(1 << (bit_nr % BITCHUNK_BITS));
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* alloc_bit *
|
||||
*===========================================================================*/
|
||||
PUBLIC int alloc_bit(bitmap, nr_bits)
|
||||
bitchunk_t *bitmap;
|
||||
bit_t nr_bits;
|
||||
{
|
||||
bitchunk_t *chunk;
|
||||
int nr_chunks;
|
||||
int bit_nr;
|
||||
int i;
|
||||
|
||||
/* Iterate over the words in block. */
|
||||
nr_chunks = BITMAP_CHUNKS(nr_bits);
|
||||
for (chunk = &bitmap[0]; chunk < &bitmap[nr_chunks]; chunk++) {
|
||||
|
||||
/* Does this chunk contain a free bit? */
|
||||
if (*chunk == (bitchunk_t) ~0) continue;
|
||||
|
||||
/* Get bit number from the start of the bit map. */
|
||||
for (i = 0; (*chunk & (1 << i)) != 0; ++i) {}
|
||||
bit_nr = (chunk - &bitmap[0]) * BITCHUNK_BITS + i;
|
||||
|
||||
/* Don't allocate bits beyond the end of the map. */
|
||||
if (bit_nr >= nr_bits) break;
|
||||
|
||||
*chunk |= 1 << bit_nr % BITCHUNK_BITS;
|
||||
return(bit_nr);
|
||||
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
! See src/kernel/ipc.h for C definitions
|
||||
SEND = 1
|
||||
RECEIVE = 2
|
||||
SENDREC = 3 + 32 ! flags 0x20 to request fresh answer
|
||||
SENDREC = 3
|
||||
NOTIFY = 16
|
||||
ALERT = 4
|
||||
ECHO = 8
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
/* A server must occasionally print some message. It uses a simple version of
|
||||
* printf() found in the system lib that calls kputc() to output characters.
|
||||
* Printing is done with a call to the kernel, and not by going through FS.
|
||||
* This way system messages end up in the kernel messages buffer and can be
|
||||
* reviewed at a later time.
|
||||
*
|
||||
* This routine can only be used by servers and device drivers. The kernel
|
||||
* must define its own kputc(). Note that the log driver also defines its own
|
||||
|
@ -24,21 +22,23 @@ int c;
|
|||
message m;
|
||||
|
||||
if ((c == 0 && buf_count > 0) || buf_count == sizeof(print_buf)) {
|
||||
/* Send the buffer to the system task, or, if this process is not a
|
||||
* server yet, to standard error.
|
||||
*/
|
||||
|
||||
/* Send the buffer to the PRINTF_PROC driver. */
|
||||
m.DIAG_BUF_COUNT = buf_count;
|
||||
m.DIAG_PRINT_BUF = print_buf;
|
||||
m.DIAG_PROC_NR = SELF;
|
||||
m.m_type = DIAGNOSTICS;
|
||||
if (_sendrec(PRINTF_PROC, &m) != 0) {
|
||||
m.m1_i1 = 2;
|
||||
m.m1_i2 = buf_count;
|
||||
m.m1_p1 = print_buf;
|
||||
m.m_type = WRITE;
|
||||
(void) _sendrec(FS, &m);
|
||||
}
|
||||
(void) _sendrec(PRINTF_PROC, &m);
|
||||
buf_count = 0;
|
||||
|
||||
/* If the output fails, e.g., due to an ELOCKED, do not retry output
|
||||
* at the FS as if this were a normal user-land printf(). This may
|
||||
* result in even worse problems.
|
||||
*/
|
||||
}
|
||||
if (c != 0) {
|
||||
|
||||
/* Append a single character to the output buffer. */
|
||||
print_buf[buf_count++] = c;
|
||||
}
|
||||
if (c != 0) print_buf[buf_count++] = c;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue