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:
Jorrit Herder 2005-07-27 14:32:16 +00:00
parent 28958cca35
commit fe0dcb5c00
23 changed files with 172 additions and 267 deletions

View file

@ -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

View file

@ -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. */

View file

@ -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

View file

@ -8,6 +8,7 @@
#include "drvlib.h"
#include <unistd.h>
/* Extended partition? */
#define ext_part(s) ((s) == 0x05 || (s) == 0x0F)

View file

@ -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;

View file

@ -166,7 +166,6 @@ tty_t *tp;
int try;
{
/* Process characters from the circular keyboard buffer. */
char buf[3];
int scode;
unsigned ch;

View file

@ -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);
}

View file

@ -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 */

View file

@ -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.

View file

@ -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 */
}

View file

@ -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

View file

@ -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)

View file

@ -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 */

View file

@ -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

View file

@ -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 - &notify_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 = &notify_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);

View file

@ -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) );

View file

@ -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);
}

View file

@ -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) */
}

View file

@ -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 */

View file

@ -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];
};

View file

@ -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

View file

@ -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

View file

@ -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;
}