minix/crtso.h minix/debug.h minix/devio.h minix/dirent.h \
minix/dir.h minix/dl_eth.h minix/dmap.h minix/driver.h \
minix/drivers.h minix/drvlib.h minix/ds.h minix/endpoint.h \
- minix/fslib.h minix/ioctl.h minix/ipc.h minix/keymap.h \
- minix/minlib.h minix/mq.h minix/partition.h minix/paths.h \
- minix/portio.h minix/profile.h minix/queryparam.h \
+ minix/fslib.h minix/ioctl.h minix/ipc.h minix/ipcconst.h \
+ minix/keymap.h minix/minlib.h minix/mq.h minix/partition.h \
+ minix/paths.h minix/portio.h minix/profile.h minix/queryparam.h \
minix/rs.h minix/safecopies.h minix/sef.h minix/sound.h \
minix/sys_config.h minix/sysinfo.h minix/syslib.h \
minix/sysutil.h minix/tty.h minix/type.h minix/types.h \
* offset are used for the per-process notification bit maps.
*/
#define NOTIFY_MESSAGE 0x1000
-/* FIXME will be is_notify(a) ((a) == NOTIFY_MESSAGE) */
+/* FIXME the old is_notify(a) should be replaced by is_ipc_notify(status). */
+#define is_ipc_notify(status) (IPC_STATUS_CALL(status) == NOTIFY)
#define is_notify(a) ((unsigned) ((a) - NOTIFY_MESSAGE) < 0x100)
#define NOTIFY_FROM(p_nr) (NOTIFY_MESSAGE | ((p_nr) + NR_TASKS))
#ifndef _IPC_H
#define _IPC_H
+#include <minix/ipcconst.h>
#include <minix/type.h>
/*==========================================================================*
_PROTOTYPE( int echo, (message *m_ptr) );
_PROTOTYPE( int notify, (endpoint_t dest) );
_PROTOTYPE( int sendrec, (endpoint_t src_dest, message *m_ptr) );
-_PROTOTYPE( int receive, (endpoint_t src, message *m_ptr) );
+_PROTOTYPE( int receive, (endpoint_t src, message *m_ptr, int *status_ptr));
_PROTOTYPE( int send, (endpoint_t dest, message *m_ptr) );
_PROTOTYPE( int sendnb, (endpoint_t dest, message *m_ptr) );
_PROTOTYPE( int senda, (asynmsg_t *table, size_t count) );
--- /dev/null
+#ifndef _IPC_CONST_H
+#define _IPC_CONST_H
+
+ /* System call numbers that are passed when trapping to the kernel. */
+#define SEND 1 /* blocking send */
+#define RECEIVE 2 /* blocking receive */
+#define SENDREC 3 /* SEND + RECEIVE */
+#define NOTIFY 4 /* asynchronous notify */
+#define SENDNB 5 /* nonblocking send */
+#define SENDA 16 /* asynchronous send */
+
+/* Macros for IPC status code manipulation. */
+#define IPC_STATUS_CALL_SHIFT 0
+#define IPC_STATUS_CALL_MASK 0x3F
+#define IPC_STATUS_CALL(status) \
+ (((status) >> IPC_STATUS_CALL_SHIFT) & IPC_STATUS_CALL_MASK)
+#define IPC_STATUS_CALL_TO(call) \
+ (((call) & IPC_STATUS_CALL_MASK) << IPC_STATUS_CALL_SHIFT)
+
+#endif /* IPC_CONST_H */
/* SEF entry points for system processes. */
_PROTOTYPE( void sef_startup, (void) );
-_PROTOTYPE( int sef_receive, (endpoint_t src, message *m_ptr) );
+_PROTOTYPE( int sef_receive_status, (endpoint_t src, message *m_ptr,
+ int *status_ptr) );
_PROTOTYPE( void sef_exit, (int status) );
+#define sef_receive(src, m_ptr) sef_receive_status(src, m_ptr, NULL)
/* SEF Debug. */
#include <stdio.h>
*===========================================================================*/
/* What to intercept. */
#define INTERCEPT_SEF_PING_REQUESTS 1
-#define IS_SEF_PING_REQUEST(mp) (is_notify((mp)->m_type) \
+#define IS_SEF_PING_REQUEST(mp, status) (is_ipc_notify(status) \
&& (mp)->m_source == RS_PROC_NR)
/* Callback type definitions. */
*===========================================================================*/
/* What to intercept. */
#define INTERCEPT_SEF_LU_REQUESTS 1
-#define IS_SEF_LU_REQUEST(mp) ((mp)->m_type == RS_LU_PREPARE \
+#define IS_SEF_LU_REQUEST(mp, status) ((mp)->m_type == RS_LU_PREPARE \
&& (mp)->m_source == RS_PROC_NR)
/* Callback type definitions. */
*===========================================================================*/
/* What to intercept. */
#define INTERCEPT_SEF_SIGNAL_REQUESTS 1
-#define IS_SEF_SIGNAL_REQUEST(mp) \
+#define IS_SEF_SIGNAL_REQUEST(mp, status) \
(((mp)->m_type == SIGS_SIGNAL_RECEIVED && (mp)->m_source < INIT_PROC_NR) \
- || (is_notify((mp)->m_type) && (mp)->m_source == SYSTEM))
+ || (is_ipc_notify(status) && (mp)->m_source == SYSTEM))
/* Callback type definitions. */
typedef void(*sef_cb_signal_handler_t)(int signo);
/* Masks and flags for system calls. */
#define NON_BLOCKING 0x0080 /* do not block if target not ready */
-/* System call numbers that are passed when trapping to the kernel. */
-#define SEND 1 /* blocking send */
-#define RECEIVE 2 /* blocking receive */
-#define SENDREC 3 /* SEND + RECEIVE */
-#define NOTIFY 4 /* asynchronous notify */
-#define SENDNB 5 /* nonblocking send */
-#define SENDA 16 /* asynchronous send */
-
#define WILLRECEIVE(target, source_ep) \
((RTS_ISSET(target, RTS_RECEIVING) && !RTS_ISSET(target, RTS_SENDING)) && \
(target->p_getfrom_e == ANY || target->p_getfrom_e == source_ep))
+/* IPC status code macros. */
+#define IPC_STATUS_REG bx
+#define IPC_STATUS_GET(p) ((p)->p_reg.IPC_STATUS_REG)
+#define IPC_STATUS_SET(p, m) ((p)->p_reg.IPC_STATUS_REG = m)
+#define IPC_STATUS_CLEAR(p) IPC_STATUS_SET(p, 0)
+#define IPC_STATUS_ADD(p, m) ((p)->p_reg.IPC_STATUS_REG |= m)
#endif /* IPC_H */
caller_ptr->p_name, caller_ptr->p_endpoint);
}
+ /* Clear IPC status code. */
+ IPC_STATUS_CLEAR(caller_ptr);
+
/* Check destination. SENDA is special because its argument is a table and
* not a single destination. RECEIVE is the only call that accepts ANY (in
* addition to a real endpoint). The other calls (SEND, SENDREC,
* RTS_SENDING flag may be set when its SENDREC call blocked while sending.
*/
if (WILLRECEIVE(dst_ptr, caller_ptr->p_endpoint)) {
+ int call;
/* Destination is indeed waiting for this message. */
assert(!(dst_ptr->p_misc_flags & MF_DELIVERMSG));
if((r=QueueMess(caller_ptr->p_endpoint, linaddr, dst_ptr)) != OK)
return r;
+ call = (caller_ptr->p_misc_flags & MF_REPLY_PEND ? SENDREC
+ : (flags & NON_BLOCKING ? SENDNB : SEND));
+ IPC_STATUS_ADD(dst_ptr, IPC_STATUS_CALL_TO(call));
RTS_UNSET(dst_ptr, RTS_RECEIVING);
} else {
if(flags & NON_BLOCKING) {
if((r=QueueMess(hisep, vir2phys(&m), caller_ptr)) != OK) {
panic("mini_receive: local QueueMess failed");
}
+ IPC_STATUS_ADD(caller_ptr, IPC_STATUS_CALL_TO(NOTIFY));
return(OK); /* report success */
}
}
xpp = &caller_ptr->p_caller_q;
while (*xpp != NIL_PROC) {
if (src_e == ANY || src_p == proc_nr(*xpp)) {
+ int call;
assert(!RTS_ISSET(*xpp, RTS_SLOT_FREE));
assert(!RTS_ISSET(*xpp, RTS_NO_ENDPOINT));
assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
QueueMess((*xpp)->p_endpoint,
vir2phys(&(*xpp)->p_sendmsg), caller_ptr);
+ call = ((*xpp)->p_misc_flags & MF_REPLY_PEND ? SENDREC : SEND);
+ IPC_STATUS_ADD(caller_ptr, IPC_STATUS_CALL_TO(call));
if ((*xpp)->p_misc_flags & MF_SIG_DELAY)
sig_delay_done(*xpp);
RTS_UNSET(*xpp, RTS_SENDING);
else
r= try_async(caller_ptr);
- if (r == OK)
+ if (r == OK) {
+ IPC_STATUS_ADD(caller_ptr, IPC_STATUS_CALL_TO(SENDA));
return OK; /* Got a message */
+ }
}
}
if((r=QueueMess(caller_ptr->p_endpoint, vir2phys(&m), dst_ptr)) != OK) {
panic("mini_notify: local QueueMess failed");
}
+ IPC_STATUS_ADD(dst_ptr, IPC_STATUS_CALL_TO(NOTIFY));
RTS_UNSET(dst_ptr, RTS_RECEIVING);
return(OK);
}
tabent.result= QueueMess(caller_ptr->p_endpoint,
linaddr + (vir_bytes) &table[i].msg -
(vir_bytes) table, dst_ptr);
- if(tabent.result == OK)
+ if(tabent.result == OK) {
+ IPC_STATUS_ADD(dst_ptr,
+ IPC_STATUS_CALL_TO(SENDA));
RTS_UNSET(dst_ptr, RTS_RECEIVING);
+ }
A_INSERT(i, result);
tabent.flags= flags | AMF_DONE;
+#include <minix/ipcconst.h>
+
.globl __notify, __send, __senda, __sendnb, __receive, __sendrec, __do_kernel_call
-/* See src/kernel/ipc.h for C definitions */
- SEND = 1
- RECEIVE = 2
- SENDREC = 3
- NOTIFY = 4
- SENDNB = 5
IPCVEC = 33 /* ipc trap to kernel */
KERVEC = 32 /* syscall trap to kernel */
SRC_DST = 8 /* source/ destination process */
MESSAGE = 12 /* message pointer */
+ STATUS = 16 /* status pointer */
/**========================================================================* */
/* IPC assembly routines * */
/**========================================================================* */
-/* all message passing routines save ebp, but destroy eax and ecx. */
+/* all message passing routines save ebx, but destroy eax and ecx. */
.text
__send:
push %ebp
movl MESSAGE(%ebp), %ebx /* ebx = message pointer */
movl $RECEIVE, %ecx /* _receive(src, ptr) */
int $IPCVEC /* trap to the kernel */
+ movl STATUS(%ebp), %ecx /* ecx = status pointer */
+ movl %ebx, (%ecx)
pop %ebx
pop %ebp
ret
+#include <minix/ipcconst.h>
+
.globl __senda
- SENDA = 16
SYSVEC = 33
MSGTAB = 8 /* message table */
PUBLIC void sef_startup()
{
/* SEF startup interface for system services. */
- int r;
+ int r, status;
/* Get information about self. */
r = sys_whoami(&sef_self_endpoint, sef_self_name, SEF_SELF_NAME_MAXLEN);
else {
message m;
- if((r = receive(RS_PROC_NR, &m)) != OK) {
+ r = receive(RS_PROC_NR, &m, &status);
+ if(r != OK) {
panic("unable to receive from RS: %d", r);
}
if(IS_SEF_INIT_REQUEST(&m)) {
}
/*===========================================================================*
- * sef_receive *
+ * sef_receive_status *
*===========================================================================*/
-PUBLIC int sef_receive(endpoint_t src, message *m_ptr)
+PUBLIC int sef_receive_status(endpoint_t src, message *m_ptr, int *status_ptr)
{
/* SEF receive() interface for system services. */
- int r;
+ int r, status;
while(TRUE) {
#endif
/* Receive and return in case of error. */
- r = receive(src, m_ptr);
+ r = receive(src, m_ptr, &status);
+ if(status_ptr) *status_ptr = status;
if(r != OK) {
return r;
}
#if INTERCEPT_SEF_PING_REQUESTS
/* Intercept SEF Ping requests. */
- if(IS_SEF_PING_REQUEST(m_ptr)) {
+ if(IS_SEF_PING_REQUEST(m_ptr, status)) {
if(do_sef_ping_request(m_ptr) == OK) {
continue;
}
#if INTERCEPT_SEF_LU_REQUESTS
/* Intercept SEF Live update requests. */
- if(IS_SEF_LU_REQUEST(m_ptr)) {
+ if(IS_SEF_LU_REQUEST(m_ptr, status)) {
if(do_sef_lu_request(m_ptr) == OK) {
continue;
}
#if INTERCEPT_SEF_SIGNAL_REQUESTS
/* Intercept SEF Signal requests. */
- if(IS_SEF_SIGNAL_REQUEST(m_ptr)) {
+ if(IS_SEF_SIGNAL_REQUEST(m_ptr, status)) {
if(do_sef_signal_request(m_ptr) == OK) {
continue;
}
s = _kernel_call(SYS_SETALARM, &m);
if (s != OK) return(s);
- receive(CLOCK,&m_alarm); /* await synchronous alarm */
+ sef_receive(CLOCK,&m_alarm); /* await synchronous alarm */
/* Check if we must reschedule the current alarm. */
if (m.ALRM_TIME_LEFT > 0 && m.ALRM_TIME_LEFT != TMR_NEVER) {
struct boot_image **ip, struct boot_image_priv **pp,
struct boot_image_sys **sp, struct boot_image_dev **dp) );
FORWARD _PROTOTYPE(void catch_boot_init_ready, (endpoint_t endpoint) );
-FORWARD _PROTOTYPE(void get_work, (message *m) );
+FORWARD _PROTOTYPE(void get_work, (message *m_ptr, int *status_ptr) );
/* The buffer where the boot image is copied during initialization. */
PRIVATE int boot_image_buffer_size;
* sending the reply. The loop never terminates, unless a panic occurs.
*/
message m; /* request message */
+ int status; /* status code */
int call_nr, who_e,who_p; /* call number and caller */
int result; /* result to return */
while (TRUE) {
/* Wait for request message. */
- get_work(&m);
+ get_work(&m, &status);
who_e = m.m_source;
if(rs_isokendpt(who_e, &who_p) != OK) {
panic("message from bogus source: %d", who_e);
/* Notification messages are control messages and do not need a reply.
* These include heartbeat messages and system notifications.
*/
- if (is_notify(m.m_type)) {
+ if (is_ipc_notify(status)) {
switch (who_p) {
case CLOCK:
do_period(&m); /* check services status */
{
/* Block and catch an init ready message from the given source. */
int r;
+ int status;
message m;
struct rproc *rp;
int result;
/* Receive init ready message. */
- if ((r = receive(endpoint, &m)) != OK) {
+ if ((r = sef_receive_status(endpoint, &m, &status)) != OK) {
panic("unable to receive init reply: %d", r);
}
if(m.m_type != RS_INIT) {
/*===========================================================================*
* get_work *
*===========================================================================*/
-PRIVATE void get_work(m_in)
-message *m_in; /* pointer to message */
+PRIVATE void get_work(m_ptr, status_ptr)
+message *m_ptr; /* pointer to message */
+int *status_ptr; /* pointer to status */
{
- int s; /* receive status */
- if (OK != (s=sef_receive(ANY, m_in))) /* wait for message */
- panic("sef_receive failed: %d", s);
+ int r;
+ if (OK != (r=sef_receive_status(ANY, m_ptr, status_ptr)))
+ panic("sef_receive_status failed: %d", r);
}