static u8_t dev_capptr;
static u8_t *table;
-static int init(void);
static int find_dev(int *devindp, u8_t *capaddrp);
static u32_t read_reg(int function, int index);
static void write_reg(int function, int index, u32_t value);
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
int main(void)
{
/* SEF local startup. */
sef_local_startup();
- printf("amddev: starting\n");
-
- init();
-
for(;;)
{
report_exceptions();
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_lu(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* Register live update callbacks. */
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard);
sef_startup();
}
-static int init()
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
+/* Initialize the amddev driver. */
int r, n_maps, n_domains, revision;
u16_t flags;
u32_t bits;
+ printf("amddev: starting\n");
+
r= find_dev(&dev_devind, &dev_capptr);
if (!r)
return r;
write_reg(DEVF_CR, 0, 0x10 | 0x8 | 0x4 | 1);
printf("after write: DEVF_CR: 0x%x\n", read_reg(DEVF_CR, 0));
+
+ return(OK);
}
static int find_dev(devindp, capaddrp)
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) );
EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) );
EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) );
*===========================================================================*/
PUBLIC int main(int argc, char *argv[])
{
- struct sigaction sa;
-
/* SEF local startup. */
+ env_setargs(argc, argv);
sef_local_startup();
- /* Install signal handlers. Ask PM to transform signal into message. */
- system_hz = sys_hz();
-
- init_buffer();
-
- w_identify_wakeup_ticks = WAKEUP_TICKS;
- wakeup_ticks = WAKEUP_TICKS;
-
- sa.sa_handler = SIG_MESS;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- if (sigaction(SIGTERM,&sa,NULL)<0) panic("AT","sigaction failed", errno);
-
- /* Set special disk parameters then call the generic main loop. */
- env_setargs(argc, argv);
- init_params();
- signal(SIGTERM, SIG_IGN);
+ /* Call the generic receive loop. */
driver_task(&w_dtab, DRIVER_STD);
+
return(OK);
}
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_lu(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* Register live update callbacks. */
sef_setcb_lu_prepare(sef_cb_lu_prepare);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the at_wini driver. */
+ struct sigaction sa;
+
+ /* Install signal handlers. Ask PM to transform signal into message. */
+ system_hz = sys_hz();
+
+ init_buffer();
+
+ w_identify_wakeup_ticks = WAKEUP_TICKS;
+ wakeup_ticks = WAKEUP_TICKS;
+
+ sa.sa_handler = SIG_MESS;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ if (sigaction(SIGTERM,&sa,NULL)<0) panic("AT","sigaction failed", errno);
+
+ /* Set special disk parameters. */
+ init_params();
+ signal(SIGTERM, SIG_IGN);
+
+ return(OK);
+}
+
/*===========================================================================*
* init_params *
*===========================================================================*/
{ 0x0000, 0x0000 }
};
+long instance;
+
/*===========================================================================*
* atl2_read_vpd *
*===========================================================================*/
}
/*===========================================================================*
- * sef_local_startup *
+ * sef_cb_init_fresh *
*===========================================================================*/
-PRIVATE void sef_local_startup(void)
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
- /* Initialize the System Event Framework.
- */
-
- /* No support for live update yet. */
- sef_startup();
-}
-
-/*===========================================================================*
- * main *
- *===========================================================================*/
-int main(int argc, char **argv)
-{
- /* Driver task.
- */
+/* Initialize the atl2 driver. */
u32_t inet_endpt;
- message m;
- sigset_t set;
int r, devind;
- long instance;
#if ATL2_FKEY
int fkeys, sfkeys;
#endif
- /* Initialize SEF. */
- sef_local_startup();
-
/* How many matching devices should we skip? */
instance = 0;
- env_setargs(argc, argv);
env_parse("atl2_instance", "d", 0, &instance, 0, 32);
/* Try to find a recognized device. */
printf("ATL2: warning, could not map Shift+F11 key (%d)\n", r);
#endif
+ return(OK);
+}
+
+/*===========================================================================*
+ * sef_local_startup *
+ *===========================================================================*/
+PRIVATE void sef_local_startup(void)
+{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
+ /* No support for live update yet. */
+
+ /* Let SEF perform startup. */
+ sef_startup();
+}
+
+/*===========================================================================*
+ * main *
+ *===========================================================================*/
+int main(int argc, char **argv)
+{
+ /* Driver task.
+ */
+ message m;
+ sigset_t set;
+ int r;
+
+ /* Initialize SEF. */
+ env_setargs(argc, argv);
+ sef_local_startup();
+
while (TRUE) {
if ((r = sef_receive(ANY, &m)) != OK)
panic("atl2", "sef_receive failed", r);
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) );
EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) );
EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) );
/* SEF local startup. */
sef_local_startup();
- drv_init();
-
/* Here is the main loop of the dma driver. It waits for a message,
carries it out, and sends a reply. */
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_lu(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* Register live update callbacks. */
sef_setcb_lu_prepare(sef_cb_lu_prepare);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the audio driver framework. */
+ return init_driver();
+}
+
PRIVATE int init_driver(void) {
u32_t i; char irq;
static int executed = 0;
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
/*===========================================================================*
* bios_winchester_task *
*===========================================================================*/
PUBLIC int main()
{
- long v;
-
/* SEF local startup. */
sef_local_startup();
- v= 0;
- env_parse("bios_remap_first", "d", 0, &v, 0, 1);
- remap_first= v;
-
-/* Set special disk parameters then call the generic main loop. */
+ /* Call the generic receive loop. */
driver_task(&w_dtab, DRIVER_STD);
+
return(OK);
}
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_lu(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* Register live update callbacks. */
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard);
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the bios_wini driver. */
+ long v;
+
+ v = 0;
+ env_parse("bios_remap_first", "d", 0, &v, 0, 1);
+ remap_first = v;
+
+ return(OK);
+}
+
/*===========================================================================*
* w_prepare *
*===========================================================================*/
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
+EXTERN int env_argc;
+EXTERN char **env_argv;
/*===========================================================================*
* dpeth_task *
int main(int argc, char *argv[])
{
message m;
- int i, r, tasknr;
- dpeth_t *dep;
- long v;
+ int r;
/* SEF local startup. */
- sef_local_startup();
-
- system_hz = sys_hz();
-
- if (argc < 1)
- {
- panic("DP8390",
- "A head which at this time has no name", NO_NUM);
- }
- (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
-
env_setargs(argc, argv);
-
- for (i= 0, dep= de_table; i<DE_PORT_NR; i++, dep++)
- {
- strcpy(dep->de_name, "dp8390#0");
- dep->de_name[7] += i;
- }
-
- v= 0;
- (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
- eth_ign_proto= htons((u16_t) v);
-
- /* Try to notify inet that we are present (again) */
- r = _pm_findproc("inet", &tasknr);
- if (r == OK)
- notify(tasknr);
+ sef_local_startup();
while (TRUE)
{
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* No live update support for now. */
/* Let SEF perform startup. */
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the dp8390 driver. */
+ int i, r, tasknr;
+ dpeth_t *dep;
+ long v;
+
+ system_hz = sys_hz();
+
+ if (env_argc < 1)
+ {
+ panic("DP8390",
+ "A head which at this time has no name", NO_NUM);
+ }
+ (progname=strrchr(env_argv[0],'/')) ? progname++
+ : (progname=env_argv[0]);
+
+ for (i= 0, dep= de_table; i<DE_PORT_NR; i++, dep++)
+ {
+ strcpy(dep->de_name, "dp8390#0");
+ dep->de_name[7] += i;
+ }
+
+ v= 0;
+ (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
+ eth_ign_proto= htons((u16_t) v);
+
+ /* Try to notify inet that we are present (again) */
+ r = _pm_findproc("inet", &tasknr);
+ if (r == OK)
+ notify(tasknr);
+
+ return(OK);
+}
+
#if 0
/*===========================================================================*
* dp8390_dump *
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
+EXTERN int env_argc;
+EXTERN char **env_argv;
/*
** Name: int dpeth_task(void)
{
message m;
dpeth_t *dep;
- int rc, fkeys, sfkeys, tasknr;
+ int rc;
/* SEF local startup. */
- sef_local_startup();
-
- (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
-
env_setargs(argc, argv);
-
- /* Request function key for debug dumps */
- fkeys = sfkeys = 0; bit_set(sfkeys, 8);
- if ((fkey_map(&fkeys, &sfkeys)) != OK)
- printf("%s: couldn't program Shift+F8 key (%d)\n", DevName, errno);
-
-#ifdef ETH_IGN_PROTO
- {
- static u16_t eth_ign_proto = 0;
- long val;
- val = 0xFFFF;
- env_parse("ETH_IGN_PROTO", "x", 0, &val, 0x0000L, 0xFFFFL);
- eth_ign_proto = htons((u16_t) val);
- }
-#endif
-
- /* Try to notify inet that we are present (again) */
- rc = _pm_findproc("inet", &tasknr);
- if (rc == OK)
- notify(tasknr);
+ sef_local_startup();
while (TRUE) {
if ((rc = sef_receive(ANY, &m)) != OK) panic(dep->de_name, RecvErrMsg, rc);
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* No live update support for now. */
/* Let SEF perform startup. */
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the dpeth driver. */
+ dpeth_t *dep;
+ int rc, fkeys, sfkeys, tasknr;
+
+ (progname=strrchr(env_argv[0],'/')) ? progname++ : (progname=env_argv[0]);
+
+ /* Request function key for debug dumps */
+ fkeys = sfkeys = 0; bit_set(sfkeys, 8);
+ if ((fkey_map(&fkeys, &sfkeys)) != OK)
+ printf("%s: couldn't program Shift+F8 key (%d)\n", DevName, errno);
+
+#ifdef ETH_IGN_PROTO
+ {
+ static u16_t eth_ign_proto = 0;
+ long val;
+ val = 0xFFFF;
+ env_parse("ETH_IGN_PROTO", "x", 0, &val, 0x0000L, 0xFFFFL);
+ eth_ign_proto = htons((u16_t) val);
+ }
+#endif
+
+ /* Try to notify inet that we are present (again) */
+ rc = _pm_findproc("inet", &tasknr);
+ if (rc == OK)
+ notify(tasknr);
+
+ return(OK);
+}
+
/** dp.c **/
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
+EXTERN int env_argc;
+EXTERN char **env_argv;
/*===========================================================================*
* main *
int main(int argc, char *argv[])
{
message m;
- int i, r;
- u32_t tasknr;
- e1000_t *e;
- long v;
+ int r;
/* SEF local startup. */
+ env_setargs(argc, argv);
sef_local_startup();
- /* Verify command-line arguments. */
- if (argc < 1)
- {
- panic("e1000", "no program name given in argc/argv", NO_NUM);
- }
- else
- (progname = strrchr(argv[0],'/')) ? progname++ : (progname = argv[0]);
-
- /* Clear state. */
- memset(e1000_table, 0, sizeof(e1000_table));
-
- /* Perform calibration. */
- if((r = micro_delay_calibrate()) != OK)
- {
- panic("e1000", "rmicro_delay_calibrate failed", r);
- }
- /* Try to notify inet that we are present (again) */
- if ((r = ds_retrieve_u32("inet", &tasknr)) == OK)
- {
- notify(tasknr);
- }
- else if (r != ESRCH)
- {
- printf("e1000: ds_retrieve_u32 failed for 'inet': %d\n", r);
- }
-
/*
* Enter the main driver loop.
*/
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* No live update support for now. */
/* Let SEF perform startup. */
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the e1000 driver. */
+ int r;
+ u32_t tasknr;
+
+ /* Verify command-line arguments. */
+ if (env_argc < 1)
+ {
+ panic("e1000", "no program name given in argc/argv", NO_NUM);
+ }
+ else
+ (progname = strrchr(env_argv[0],'/')) ? progname++
+ : (progname = env_argv[0]);
+
+ /* Clear state. */
+ memset(e1000_table, 0, sizeof(e1000_table));
+
+ /* Perform calibration. */
+ if((r = micro_delay_calibrate()) != OK)
+ {
+ panic("e1000", "rmicro_delay_calibrate failed", r);
+ }
+ /* Try to notify inet that we are present (again) */
+ if ((r = ds_retrieve_u32("inet", &tasknr)) == OK)
+ {
+ notify(tasknr);
+ }
+ else if (r != ESRCH)
+ {
+ printf("e1000: ds_retrieve_u32 failed for 'inet': %d\n", r);
+ }
+
+ return(OK);
+}
+
/*===========================================================================*
* e1000_init *
*===========================================================================*/
/* Data buffers. */
static char *buf_array, *buffer; /* contiguous buffer */
+/* SEF functions and variables. */
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
+EXTERN int env_argc;
+EXTERN char **env_argv;
+
/*===========================================================================*
* carry *
*===========================================================================*/
exit(0);
}
-/*===========================================================================*
- * sef_local_startup *
- *===========================================================================*/
-static void sef_local_startup(void)
-{
- /* No live update support for now. */
-
- /* Let SEF perform startup. */
- sef_startup();
-}
-
/*===========================================================================*
* main *
*===========================================================================*/
int r;
/* SEF local startup. */
+ env_setargs(argc, argv);
sef_local_startup();
- r = parse_arguments(argc, argv);
- if(r != OK) {
- printf("Filter: wrong argument!\n");
- return 1;
- }
-
- if ((buf_array = flt_malloc(BUF_SIZE, NULL, 0)) == NULL)
- panic(__FILE__, "no memory available", NO_NUM);
-
- sum_init();
-
- driver_init();
-
for (;;) {
/* Wait for request. */
if(sef_receive(ANY, &m_in) != OK) {
return 0;
}
+
+/*===========================================================================*
+ * sef_local_startup *
+ *===========================================================================*/
+PRIVATE void sef_local_startup(void)
+{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
+ /* No live update support for now. */
+
+ /* Let SEF perform startup. */
+ sef_startup();
+}
+
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the filter driver. */
+ int r;
+
+ r = parse_arguments(env_argc, env_argv);
+ if(r != OK) {
+ printf("Filter: wrong argument!\n");
+ return 1;
+ }
+
+ if ((buf_array = flt_malloc(BUF_SIZE, NULL, 0)) == NULL)
+ panic(__FILE__, "no memory available", NO_NUM);
+
+ sum_init();
+
+ driver_init();
+
+ return(OK);
+}
+
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) );
EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) );
EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) );
/*===========================================================================*
* floppy_task *
*===========================================================================*/
-PUBLIC void main()
+PUBLIC int main()
{
- struct floppy *fp;
- int s;
-
/* SEF local startup. */
sef_local_startup();
+ /* Call the generic receive loop. */
+ driver_task(&f_dtab, DRIVER_STD);
+
+ return(OK);
+}
+
+/*===========================================================================*
+ * sef_local_startup *
+ *===========================================================================*/
+PRIVATE void sef_local_startup()
+{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_lu(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
+ /* Register live update callbacks. */
+ sef_setcb_lu_prepare(sef_cb_lu_prepare);
+ sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
+ sef_setcb_lu_state_dump(sef_cb_lu_state_dump);
+
+ /* Let SEF perform startup. */
+ sef_startup();
+}
+
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the floppy driver. */
+ struct floppy *fp;
+ int s;
+
/* Initialize the floppy structure and the timers. */
system_hz = sys_hz();
/* Ignore signals */
signal(SIGHUP, SIG_IGN);
- driver_task(&f_dtab, DRIVER_STD);
-}
-
-/*===========================================================================*
- * sef_local_startup *
- *===========================================================================*/
-PRIVATE void sef_local_startup()
-{
- /* Register live update callbacks. */
- sef_setcb_lu_prepare(sef_cb_lu_prepare);
- sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
- sef_setcb_lu_state_dump(sef_cb_lu_state_dump);
-
- /* Let SEF perform startup. */
- sef_startup();
+ return(OK);
}
/*===========================================================================*
#include "../libdriver/driver.h"
#include "../libdriver/drvlib.h"
-_PROTOTYPE(void main, (void));
+_PROTOTYPE(int main, (void));
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
+EXTERN int env_argc;
+EXTERN char **env_argv;
/*===========================================================================*
* main *
int main(int argc, char *argv[])
{
message m;
- int i, r;
- u32_t tasknr;
- long v;
- vir_bytes ft = sizeof(*fxp_table)*FXP_PORT_NR;
+ int r;
/* SEF local startup. */
+ env_setargs(argc, argv);
sef_local_startup();
- system_hz = sys_hz();
-
- if (argc < 1)
- panic("FXP", "A head which at this time has no name", NO_NUM);
- (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
-
- v= 0;
-#if 0
- (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
-#endif
- eth_ign_proto= htons((u16_t) v);
-
- if(!(fxp_table = alloc_contig(ft, 0, &fxp_table_phys)))
- panic("FXP","couldn't allocate table", r);
-
- memset(fxp_table, 0, ft);
-
- if((r=micro_delay_calibrate()) != OK)
- panic("FXP","rmicro_delay_calibrate failed", r);
-
- /* Try to notify inet that we are present (again) */
- r= ds_retrieve_u32("inet", &tasknr);
- if (r == OK)
- notify(tasknr);
- else if (r != ESRCH)
- printf("fxp: ds_retrieve_u32 failed for 'inet': %d\n", r);
-
-
while (TRUE)
{
if ((r= sef_receive(ANY, &m)) != OK)
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* No live update support for now. */
/* Let SEF perform startup. */
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the fxp driver. */
+ int r;
+ u32_t tasknr;
+ long v;
+ vir_bytes ft;
+
+ ft = sizeof(*fxp_table)*FXP_PORT_NR;
+ system_hz = sys_hz();
+
+ if (env_argc < 1)
+ panic("FXP", "A head which at this time has no name", NO_NUM);
+ (progname=strrchr(env_argv[0],'/')) ? progname++
+ : (progname=env_argv[0]);
+
+ v= 0;
+#if 0
+ (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
+#endif
+ eth_ign_proto= htons((u16_t) v);
+
+ if(!(fxp_table = alloc_contig(ft, 0, &fxp_table_phys)))
+ panic("FXP","couldn't allocate table", r);
+
+ memset(fxp_table, 0, ft);
+
+ if((r=micro_delay_calibrate()) != OK)
+ panic("FXP","rmicro_delay_calibrate failed", r);
+
+ /* Try to notify inet that we are present (again) */
+ r= ds_retrieve_u32("inet", &tasknr);
+ if (r == OK)
+ notify(tasknr);
+ else if (r != ESRCH)
+ printf("fxp: ds_retrieve_u32 failed for 'inet': %d\n", r);
+
+ return(OK);
+}
+
/*===========================================================================*
* fxp_init *
*===========================================================================*/
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
+EXTERN int env_argc;
+EXTERN char **env_argv;
/*===========================================================================*
* main *
{
message m;
int i,irq,r;
- u32_t tasknr;
ether_card_t *ec;
- long v;
-#if LANCE_FKEY
- int fkeys, sfkeys;
-#endif
/* SEF local startup. */
+ env_setargs(argc, argv);
sef_local_startup();
- (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
-
- env_setargs( argc, argv );
-
-#if LANCE_FKEY
- fkeys = sfkeys = 0;
- bit_set( sfkeys, 7 );
- if ( (r = fkey_map(&fkeys, &sfkeys)) != OK )
- printf("Warning: lance couldn't observe Shift+F7 key: %d\n",r);
-#endif
-
- v= 0;
- (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
- eth_ign_proto= htons((u16_t) v);
-
- /* Try to notify inet that we are present (again) */
- r= ds_retrieve_u32("inet", &tasknr);
- if (r == OK)
- notify(tasknr);
- else if (r != ESRCH)
- printf("lance: ds_retrieve_u32 failed for 'inet': %d\n", r);
-
while (TRUE)
{
for (i=0;i<EC_PORT_NR_MAX;++i)
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* No live update support for now. */
/* Let SEF perform startup. */
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the lance driver. */
+ int r;
+ u32_t tasknr;
+ long v;
+#if LANCE_FKEY
+ int fkeys, sfkeys;
+#endif
+
+ (progname=strrchr(env_argv[0],'/')) ? progname++ : (progname=env_argv[0]);
+
+#if LANCE_FKEY
+ fkeys = sfkeys = 0;
+ bit_set( sfkeys, 7 );
+ if ( (r = fkey_map(&fkeys, &sfkeys)) != OK )
+ printf("Warning: lance couldn't observe Shift+F7 key: %d\n",r);
+#endif
+
+ v= 0;
+ (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
+ eth_ign_proto= htons((u16_t) v);
+
+ /* Try to notify inet that we are present (again) */
+ r= ds_retrieve_u32("inet", &tasknr);
+ if (r == OK)
+ notify(tasknr);
+ else if (r != ESRCH)
+ printf("lance: ds_retrieve_u32 failed for 'inet': %d\n", r);
+
+ return(OK);
+}
+
/*===========================================================================*
* lance_dump *
*===========================================================================*/
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) );
EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) );
EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) );
*===========================================================================*/
PUBLIC int main(void)
{
- int i;
-
/* SEF local startup. */
sef_local_startup();
- /* Initialize log devices. */
- for(i = 0; i < NR_DEVS; i++) {
- log_geom[i].dv_size = cvul64(LOG_SIZE);
- log_geom[i].dv_base = cvul64((long)logdevices[i].log_buffer);
- logdevices[i].log_size = logdevices[i].log_read =
- logdevices[i].log_write =
- logdevices[i].log_select_alerted =
- logdevices[i].log_selected =
- logdevices[i].log_select_ready_ops = 0;
- logdevices[i].log_proc_nr = 0;
- logdevices[i].log_revive_alerted = 0;
- }
+ /* Call the generic receive loop. */
driver_task(&log_dtab, DRIVER_ASYN);
+
return(OK);
}
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_lu(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* Register live update callbacks. */
sef_setcb_lu_prepare(sef_cb_lu_prepare);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the log driver. */
+ int i;
+
+ /* Initialize log devices. */
+ for(i = 0; i < NR_DEVS; i++) {
+ log_geom[i].dv_size = cvul64(LOG_SIZE);
+ log_geom[i].dv_base = cvul64((long)logdevices[i].log_buffer);
+ logdevices[i].log_size = logdevices[i].log_read =
+ logdevices[i].log_write =
+ logdevices[i].log_select_alerted =
+ logdevices[i].log_selected =
+ logdevices[i].log_select_ready_ops = 0;
+ logdevices[i].log_proc_nr = 0;
+ logdevices[i].log_revive_alerted = 0;
+ }
+
+ return(OK);
+}
+
/*===========================================================================*
* log_name *
*===========================================================================*/
u64_t position, iovec_t *iov, unsigned nr_req) );
FORWARD _PROTOTYPE( int m_do_open, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( int m_do_close, (struct driver *dp, message *m_ptr) );
-FORWARD _PROTOTYPE( void m_init, (void) );
FORWARD _PROTOTYPE( int m_ioctl, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void m_geometry, (struct partition *entry) );
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
/*===========================================================================*
* main *
*===========================================================================*/
PUBLIC int main(void)
{
-/* Main program. Initialize the memory driver and start the main loop. */
- struct sigaction sa;
-
/* SEF local startup. */
sef_local_startup();
- sa.sa_handler = SIG_MESS;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- if (sigaction(SIGTERM,&sa,NULL)<0) panic("MEM","sigaction failed", errno);
-
- m_init();
+ /* Call the generic receive loop. */
driver_task(&m_dtab, DRIVER_STD);
+
return(OK);
}
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_lu(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* Register live update callbacks. */
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard);
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the memory driver. */
+ struct sigaction sa;
+ u32_t ramdev_size;
+ int i, s;
+
+ sa.sa_handler = SIG_MESS;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ if (sigaction(SIGTERM,&sa,NULL)<0) panic("MEM","sigaction failed", errno);
+
+ /* Initialize all minor devices one by one. */
+ if (OK != (s=sys_getkinfo(&kinfo))) {
+ panic("MEM","Couldn't get kernel information.",s);
+ }
+
+#if 0
+ /* Map in kernel memory for /dev/kmem. */
+ m_geom[KMEM_DEV].dv_base = cvul64(kinfo.kmem_base);
+ m_geom[KMEM_DEV].dv_size = cvul64(kinfo.kmem_size);
+ if((m_vaddrs[KMEM_DEV] = vm_map_phys(SELF, (void *) kinfo.kmem_base,
+ kinfo.kmem_size)) == MAP_FAILED) {
+ printf("MEM: Couldn't map in /dev/kmem.");
+ }
+#endif
+
+ /* Ramdisk image built into the memory driver */
+ m_geom[IMGRD_DEV].dv_base= cvul64(0);
+ m_geom[IMGRD_DEV].dv_size= cvul64(imgrd_size);
+ m_vaddrs[IMGRD_DEV] = (vir_bytes) imgrd;
+
+ /* Initialize /dev/zero. Simply write zeros into the buffer. */
+ for (i=0; i<ZERO_BUF_SIZE; i++) {
+ dev_zero[i] = '\0';
+ }
+
+ for(i = 0; i < NR_DEVS; i++)
+ openct[i] = 0;
+
+ /* Set up memory range for /dev/mem. */
+ m_geom[MEM_DEV].dv_base = cvul64(0);
+ m_geom[MEM_DEV].dv_size = cvul64(0xffffffff);
+
+ m_vaddrs[MEM_DEV] = (vir_bytes) MAP_FAILED; /* we are not mapping this in. */
+
+ return(OK);
+}
+
/*===========================================================================*
* m_name *
*===========================================================================*/
return(OK);
}
-
-/*===========================================================================*
- * m_init *
- *===========================================================================*/
-PRIVATE void m_init()
-{
- /* Initialize this task. All minor devices are initialized one by one. */
- u32_t ramdev_size;
- int i, s;
-
- if (OK != (s=sys_getkinfo(&kinfo))) {
- panic("MEM","Couldn't get kernel information.",s);
- }
-
-#if 0
- /* Map in kernel memory for /dev/kmem. */
- m_geom[KMEM_DEV].dv_base = cvul64(kinfo.kmem_base);
- m_geom[KMEM_DEV].dv_size = cvul64(kinfo.kmem_size);
- if((m_vaddrs[KMEM_DEV] = vm_map_phys(SELF, (void *) kinfo.kmem_base,
- kinfo.kmem_size)) == MAP_FAILED) {
- printf("MEM: Couldn't map in /dev/kmem.");
- }
-#endif
-
- /* Ramdisk image built into the memory driver */
- m_geom[IMGRD_DEV].dv_base= cvul64(0);
- m_geom[IMGRD_DEV].dv_size= cvul64(imgrd_size);
- m_vaddrs[IMGRD_DEV] = (vir_bytes) imgrd;
-
- /* Initialize /dev/zero. Simply write zeros into the buffer. */
- for (i=0; i<ZERO_BUF_SIZE; i++) {
- dev_zero[i] = '\0';
- }
-
- for(i = 0; i < NR_DEVS; i++)
- openct[i] = 0;
-
- /* Set up memory range for /dev/mem. */
- m_geom[MEM_DEV].dv_base = cvul64(0);
- m_geom[MEM_DEV].dv_size = cvul64(0xffffffff);
-
- m_vaddrs[MEM_DEV] = (vir_bytes) MAP_FAILED; /* we are not mapping this in. */
-}
-
/*===========================================================================*
* m_ioctl *
*===========================================================================*/
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
+EXTERN int env_argc;
+EXTERN char **env_argv;
/*****************************************************************************
* main *
* The main function of the driver, receiving and processing messages *
*****************************************************************************/
int main(int argc, char *argv[]) {
- int fkeys, sfkeys, r, i, ret;
- u32_t inet_proc_nr;
- long v = 0;
- t_or *orp;
+ int r;
/* SEF local startup. */
- sef_local_startup();
-
- system_hz = sys_hz();
-
- (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
-
env_setargs(argc, argv);
-
- /* Observe some function key for debug dumps. */
- fkeys = sfkeys = 0; bit_set(sfkeys, 11);
- if ((r=fkey_map(&fkeys, &sfkeys)) != OK)
- printf("Warning: orinoco couldn't observe F-key(s): %d\n",r);
-
- /* Try to notify INET that we are present (again). If INET cannot
- * be found, assume this is the first time we started and INET is
- * not yet alive. */
- r = ds_retrieve_u32("inet", &inet_proc_nr);
- if (r == OK)
- notify(inet_proc_nr);
- else if (r != ESRCH)
- printf("orinoco: ds_retrieve_u32 failed for 'inet': %d\n", r);
+ sef_local_startup();
while (TRUE) {
if ((r = sef_receive (ANY, &m)) != OK)
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* No live update support for now. */
/* Let SEF perform startup. */
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the orinoco driver. */
+ int fkeys, sfkeys, r;
+ u32_t inet_proc_nr;
+
+ system_hz = sys_hz();
+
+ (progname=strrchr(env_argv[0],'/')) ? progname++
+ : (progname=env_argv[0]);
+
+ /* Observe some function key for debug dumps. */
+ fkeys = sfkeys = 0; bit_set(sfkeys, 11);
+ if ((r=fkey_map(&fkeys, &sfkeys)) != OK)
+ printf("Warning: orinoco couldn't observe F-key(s): %d\n",r);
+
+ /* Try to notify INET that we are present (again). If INET cannot
+ * be found, assume this is the first time we started and INET is
+ * not yet alive. */
+ r = ds_retrieve_u32("inet", &inet_proc_nr);
+ if (r == OK)
+ notify(inet_proc_nr);
+ else if (r != ESRCH)
+ printf("orinoco: ds_retrieve_u32 failed for 'inet': %d\n", r);
+
+ return(OK);
+}
+
/*****************************************************************************
* check_int_events *
* *
#include "pci.h"
-#define NR_DRIVERS NR_SYS_PROCS
-
-PRIVATE struct acl
-{
- int inuse;
- struct rs_pci acl;
-} acl[NR_DRIVERS];
+PUBLIC struct pci_acl pci_acl[NR_DRIVERS];
FORWARD _PROTOTYPE( void do_init, (message *mp) );
FORWARD _PROTOTYPE( void do_first_dev, (message *mp) );
/* SEF local startup. */
sef_local_startup();
- pci_init();
-
for(;;)
{
r= sef_receive(ANY, &m);
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_lu(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* Register live update callbacks. */
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard);
int r;
#if DEBUG
- printf("PCI: pci_init: called by '%d'\n", mp->m_source);
+ printf("PCI: do_init: called by '%d'\n", mp->m_source);
#endif
mp->m_type= 0;
for (i= 0; i<NR_DRIVERS; i++)
{
- if (!acl[i].inuse)
+ if (!pci_acl[i].inuse)
break;
}
if (i >= NR_DRIVERS)
gid= mp->m1_i1;
- r= sys_safecopyfrom(mp->m_source, gid, 0, (vir_bytes)&acl[i].acl,
- sizeof(acl[i].acl), D);
+ r= sys_safecopyfrom(mp->m_source, gid, 0, (vir_bytes)&pci_acl[i].acl,
+ sizeof(pci_acl[i].acl), D);
if (r != OK)
{
printf("PCI: do_set_acl: safecopyfrom failed\n");
reply(mp, r);
return;
}
- acl[i].inuse= 1;
+ pci_acl[i].inuse= 1;
if(debug)
printf("PCI: do_acl: setting ACL for %d ('%s') at entry %d\n",
- acl[i].acl.rsp_endpoint, acl[i].acl.rsp_label,
+ pci_acl[i].acl.rsp_endpoint, pci_acl[i].acl.rsp_label,
i);
reply(mp, OK);
for (i= 0; i<NR_DRIVERS; i++)
{
- if (!acl[i].inuse)
+ if (!pci_acl[i].inuse)
continue;
- if (acl[i].acl.rsp_endpoint == proc_nr)
+ if (pci_acl[i].acl.rsp_endpoint == proc_nr)
break;
}
return;
}
- acl[i].inuse= 0;
+ pci_acl[i].inuse= 0;
#if 0
printf("do_acl: deleting ACL for %d ('%s') at entry %d\n",
- acl[i].acl.rsp_endpoint, acl[i].acl.rsp_label, i);
+ pci_acl[i].acl.rsp_endpoint, pci_acl[i].acl.rsp_label, i);
#endif
/* Also release all devices held by this process */
/* Find ACL entry for caller */
for (i= 0; i<NR_DRIVERS; i++)
{
- if (!acl[i].inuse)
+ if (!pci_acl[i].inuse)
continue;
- if (acl[i].acl.rsp_endpoint == endpoint)
- return &acl[i].acl;
+ if (pci_acl[i].acl.rsp_endpoint == endpoint)
+ return &pci_acl[i].acl;
}
return NULL;
}
#include <ibm/pci.h>
#include <sys/vm_i386.h>
#include <minix/com.h>
-#include <minix/rs.h>
#include <minix/syslib.h>
#include "pci.h"
int pd_bar_nr;
} pcidev[NR_PCIDEV];
+EXTERN struct pci_acl *pci_acl;
+
/* pb_flags */
#define PBF_IO 1 /* I/O else memory */
#define PBF_INCOMPLETE 2 /* not allocated */
FORWARD _PROTOTYPE( int visible, (struct rs_pci *aclp, int devind) );
FORWARD _PROTOTYPE( void print_hyper_cap, (int devind, U8_t capptr) );
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PUBLIC int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the pci driver. */
+ long v;
+ int i, r;
+ struct rprocpub rprocpub[NR_BOOT_PROCS];
+
+ v= 0;
+ env_parse("pci_debug", "d", 0, &v, 0, 1);
+ debug= v;
+
+ /* Only Intel (compatible) PCI controllers are supported at the
+ * moment.
+ */
+ pci_intel_init();
+
+ /* Map all the services in the boot image. */
+ if((r = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0,
+ (vir_bytes) rprocpub, sizeof(rprocpub), S)) != OK) {
+ panic("pci", "sys_safecopyfrom failed", r);
+ }
+ for(i=0;i < NR_BOOT_PROCS;i++) {
+ if(rprocpub[i].in_use) {
+ if((r = map_service(&rprocpub[i])) != OK) {
+ panic("pci", "unable to map service", r);
+ }
+ }
+ }
+
+ return(OK);
+}
+
+/*===========================================================================*
+ * map_service *
+ *===========================================================================*/
+PUBLIC int map_service(rpub)
+struct rprocpub *rpub;
+{
+/* Map a new service by registering a new acl entry if required. */
+ int i;
+
+ /* Stop right now if no pci device or class is found. */
+ if(rpub->pci_acl.rsp_nr_device == 0
+ && rpub->pci_acl.rsp_nr_class == 0) {
+ return(OK);
+ }
+
+ /* Find a free acl slot. */
+ for (i= 0; i<NR_DRIVERS; i++)
+ {
+ if (!pci_acl[i].inuse)
+ break;
+ }
+ if (i >= NR_DRIVERS)
+ {
+ printf("PCI: map_service: table is full\n");
+ return ENOMEM;
+ }
+
+ /* Initialize acl slot. */
+ pci_acl[i].inuse = 1;
+ pci_acl[i].acl = rpub->pci_acl;
+
+ return(OK);
+}
+
/*===========================================================================*
* helper functions for I/O *
*===========================================================================*/
printf("PCI: warning, sys_outl failed: %d\n", s);
}
-/*===========================================================================*
- * pci_init *
- *===========================================================================*/
-PUBLIC void pci_init()
-{
- static int first_time= 1;
-
- long v;
-
- if (!first_time)
- return;
-
- v= 0;
- env_parse("pci_debug", "d", 0, &v, 0, 1);
- debug= v;
-
- /* We don't expect to interrupted */
- assert(first_time == 1);
- first_time= -1;
-
- /* Only Intel (compatible) PCI controllers are supported at the
- * moment.
- */
- pci_intel_init();
-
- first_time= 0;
-}
-
/*===========================================================================*
* pci_find_dev *
*===========================================================================*/
Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
*/
+#include <minix/rs.h>
+
/* tempory functions: to be replaced later (see pci_intel.h) */
_PROTOTYPE( unsigned pci_inb, (U16_t port) );
_PROTOTYPE( unsigned pci_inw, (U16_t port) );
int type;
};
+struct pci_acl
+{
+ int inuse;
+ struct rs_pci acl;
+};
+
+#define NR_DRIVERS NR_SYS_PROCS
+
#define PCI_IB_PIIX 1 /* Intel PIIX compatible ISA bridge */
#define PCI_IB_VIA 2 /* VIA compatible ISA bridge */
#define PCI_IB_AMD 3 /* AMD compatible ISA bridge */
extern struct pci_isabridge pci_isabridge[];
extern struct pci_pcibridge pci_pcibridge[];
-/* Utility functions */
+/* Function prototypes. */
+_PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
+_PROTOTYPE( int map_service, (struct rprocpub *rpub) );
_PROTOTYPE( int pci_reserve2, (int devind, endpoint_t proc) );
_PROTOTYPE( void pci_release, (endpoint_t proc) );
_PROTOTYPE( int pci_first_dev_a, (struct rs_pci *aclp, int *devindp,
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) );
EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) );
EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) );
{
/* Main routine of the printer task. */
message pr_mess; /* buffer for all incoming messages */
- struct sigaction sa;
- int s;
/* SEF local startup. */
sef_local_startup();
- /* Install signal handlers. Ask PM to transform signal into message. */
- sa.sa_handler = SIG_MESS;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- if (sigaction(SIGTERM,&sa,NULL)<0) panic("PRN","sigaction failed", errno);
-
while (TRUE) {
sef_receive(ANY, &pr_mess);
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_lu(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* Register live update callbacks. */
sef_setcb_lu_prepare(sef_cb_lu_prepare);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the printer driver. */
+ struct sigaction sa;
+
+ /* Install signal handlers. Ask PM to transform signal into message. */
+ sa.sa_handler = SIG_MESS;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ if (sigaction(SIGTERM,&sa,NULL)<0) panic("PRN","sigaction failed", errno);
+
+ return(OK);
+}
+
/*===========================================================================*
* do_signal *
*===========================================================================*/
FORWARD _PROTOTYPE( int r_transfer, (int proc_nr, int opcode, u64_t position,
iovec_t *iov, unsigned nr_req) );
FORWARD _PROTOTYPE( int r_do_open, (struct driver *dp, message *m_ptr) );
-FORWARD _PROTOTYPE( void r_init, (void) );
FORWARD _PROTOTYPE( int r_ioctl, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void r_geometry, (struct partition *entry) );
FORWARD _PROTOTYPE( void r_random, (struct driver *dp, message *m_ptr) );
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
/*===========================================================================*
* main *
/* SEF local startup. */
sef_local_startup();
- r_init(); /* initialize the memory driver */
- driver_task(&r_dtab, DRIVER_ASYN); /* start driver's main loop */
+ /* Call the generic receive loop. */
+ driver_task(&r_dtab, DRIVER_ASYN);
+
return(OK);
}
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_lu(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* Register live update callbacks. */
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard);
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the random driver. */
+ static struct k_randomness krandom;
+ int i, s;
+
+ random_init();
+ r_random(NULL, NULL); /* also set periodic timer */
+
+ /* Retrieve first randomness buffer with parameters. */
+ if (OK != (s=sys_getrandomness(&krandom))) {
+ report("RANDOM", "sys_getrandomness failed", s);
+ exit(1);
+ }
+
+ /* Do sanity check on parameters. */
+ if(krandom.random_sources != RANDOM_SOURCES ||
+ krandom.random_elements != RANDOM_ELEMENTS) {
+ printf("random: parameters (%d, %d) don't match kernel's (%d, %d)\n",
+ RANDOM_SOURCES, RANDOM_ELEMENTS,
+ krandom.random_sources, krandom.random_elements);
+ exit(1);
+ }
+
+ /* Feed initial batch. */
+ for(i = 0; i < RANDOM_SOURCES; i++)
+ r_updatebin(i, &krandom.bin[i]);
+
+ return(OK);
+}
+
/*===========================================================================*
* r_name *
*===========================================================================*/
return(OK);
}
-/*===========================================================================*
- * r_init *
- *===========================================================================*/
-PRIVATE void r_init()
-{
- static struct k_randomness krandom;
- int i, s;
-
- random_init();
- r_random(NULL, NULL); /* also set periodic timer */
-
- /* Retrieve first randomness buffer with parameters. */
- if (OK != (s=sys_getrandomness(&krandom))) {
- report("RANDOM", "sys_getrandomness failed", s);
- exit(1);
- }
-
- /* Do sanity check on parameters. */
- if(krandom.random_sources != RANDOM_SOURCES ||
- krandom.random_elements != RANDOM_ELEMENTS) {
- printf("random: parameters (%d, %d) don't match kernel's (%d, %d)\n",
- RANDOM_SOURCES, RANDOM_ELEMENTS,
- krandom.random_sources, krandom.random_elements);
- exit(1);
- }
-
- /* Feed initial batch. */
- for(i = 0; i < RANDOM_SOURCES; i++)
- r_updatebin(i, &krandom.bin[i]);
-}
-
/*===========================================================================*
* r_ioctl *
*===========================================================================*/
#include <minix/type.h>
#include <minix/const.h>
#include <minix/syslib.h>
+#include <minix/sysutil.h>
#include <minix/com.h>
#include <minix/portio.h>
#include <ibm/cmos.h>
struct sysgetenv sysgetenv;
/* SEF local startup. */
+ env_setargs(argc, argv);
sef_local_startup();
if((s=sys_readbios(MACH_ID_ADDR, &mach_id, sizeof(mach_id))) != OK) {
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) );
EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) );
EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) );
+EXTERN int env_argc;
+EXTERN char **env_argv;
/*===========================================================================*
- * main *
+ * main *
*===========================================================================*/
int main(int argc, char *argv[])
{
- int fkeys, sfkeys;
- u32_t inet_proc_nr;
- int i, r;
- re_t *rep;
- long v;
+ int r;
/* SEF local startup. */
- sef_local_startup();
-
- system_hz = sys_hz();
-
- (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
-
env_setargs(argc, argv);
-
- v= 0;
- (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
- eth_ign_proto= htons((u16_t) v);
-
- /* Observe some function key for debug dumps. */
- fkeys = sfkeys = 0; bit_set(sfkeys, 9);
- if ((r=fkey_map(&fkeys, &sfkeys)) != OK)
- printf("Warning: RTL8139 couldn't observe Shift+F9 key: %d\n",r);
-
- /* Claim buffer memory now under Minix, before MM takes it all. */
- for (rep= &re_table[0]; rep < re_table+RE_PORT_NR; rep++)
- rl_init_buf(rep);
-
- /* Try to notify INET that we are present (again). If INET cannot
- * be found, assume this is the first time we started and INET is
- * not yet alive.
- */
- r= ds_retrieve_u32("inet", &inet_proc_nr);
- if (r == OK)
- notify(inet_proc_nr);
- else if (r != ESRCH)
- printf("rtl8139: ds_retrieve_u32 failed for 'inet': %d\n", r);
+ sef_local_startup();
while (TRUE)
{
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_lu(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* Register live update callbacks. */
sef_setcb_lu_prepare(sef_cb_lu_prepare);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the rtl8139 driver. */
+ int fkeys, sfkeys;
+ u32_t inet_proc_nr;
+ int r;
+ re_t *rep;
+ long v;
+
+ system_hz = sys_hz();
+
+ (progname=strrchr(env_argv[0],'/')) ? progname++
+ : (progname=env_argv[0]);
+
+ v= 0;
+ (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
+ eth_ign_proto= htons((u16_t) v);
+
+ /* Observe some function key for debug dumps. */
+ fkeys = sfkeys = 0; bit_set(sfkeys, 9);
+ if ((r=fkey_map(&fkeys, &sfkeys)) != OK)
+ printf("Warning: RTL8139 couldn't observe Shift+F9 key: %d\n",r);
+
+ /* Claim buffer memory now under Minix, before MM takes it all. */
+ for (rep= &re_table[0]; rep < re_table+RE_PORT_NR; rep++)
+ rl_init_buf(rep);
+
+ /* Try to notify INET that we are present (again). If INET cannot
+ * be found, assume this is the first time we started and INET is
+ * not yet alive.
+ */
+ r= ds_retrieve_u32("inet", &inet_proc_nr);
+ if (r == OK)
+ notify(inet_proc_nr);
+ else if (r != ESRCH)
+ printf("rtl8139: ds_retrieve_u32 failed for 'inet': %d\n", r);
+
+ return(OK);
+}
+
/*===========================================================================*
* check_int_events *
*===========================================================================*/
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
+EXTERN int env_argc;
+EXTERN char **env_argv;
/*===========================================================================*
* main *
*===========================================================================*/
int main(int argc, char *argv[])
{
- u32_t inet_proc_nr;
int r;
- re_t *rep;
- long v;
/* SEF local startup. */
- sef_local_startup();
-
- system_hz = sys_hz();
-
- (progname = strrchr(argv[0], '/')) ? progname++ : (progname = argv[0]);
-
env_setargs(argc, argv);
+ sef_local_startup();
- v = 0;
- (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
- eth_ign_proto = htons((u16_t) v);
-
- /* Claim buffer memory now under Minix, before MM takes it all. */
- for (rep = &re_table[0]; rep < re_table + RE_PORT_NR; rep++)
- rl_init_buf(rep);
-
- /*
- * Try to notify INET that we are present (again). If INET cannot
- * be found, assume this is the first time we started and INET is
- * not yet alive.
- */
-#if 0
- r = ds_retrieve_u32("inet", &inet_proc_nr);
- if (r == OK)
- notify(inet_proc_nr);
- else if (r != ESRCH)
- printf("rtl8169: ds_retrieve_u32 failed for 'inet': %d\n", r);
-#endif
while (TRUE) {
if ((r = sef_receive(ANY, &m)) != OK)
panic("rtl8169", "sef_receive failed", r);
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* No live update support for now. */
/* Let SEF perform startup. */
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the rtl8169 driver. */
+ u32_t inet_proc_nr;
+ int r;
+ re_t *rep;
+ long v;
+
+ system_hz = sys_hz();
+
+ (progname = strrchr(env_argv[0], '/')) ? progname++
+ : (progname = env_argv[0]);
+
+ v = 0;
+ (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL);
+ eth_ign_proto = htons((u16_t) v);
+
+ /* Claim buffer memory now under Minix, before MM takes it all. */
+ for (rep = &re_table[0]; rep < re_table + RE_PORT_NR; rep++)
+ rl_init_buf(rep);
+
+ /*
+ * Try to notify INET that we are present (again). If INET cannot
+ * be found, assume this is the first time we started and INET is
+ * not yet alive.
+ */
+#if 0
+ r = ds_retrieve_u32("inet", &inet_proc_nr);
+ if (r == OK)
+ notify(inet_proc_nr);
+ else if (r != ESRCH)
+ printf("rtl8169: ds_retrieve_u32 failed for 'inet': %d\n", r);
+#endif
+
+ return(OK);
+}
+
static void mdio_write(U16_t port, int regaddr, int value)
{
int i;
FORWARD _PROTOTYPE( void dsp_status, (message *m_ptr) );
FORWARD _PROTOTYPE( void reply, (int code, int replyee, int process, int status) );
-FORWARD _PROTOTYPE( void init_buffer, (void) );
FORWARD _PROTOTYPE( int dsp_init, (void) );
FORWARD _PROTOTYPE( int dsp_reset, (void) );
FORWARD _PROTOTYPE( int dsp_command, (int value) );
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) );
EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) );
EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) );
*===========================================================================*/
PUBLIC void main()
{
- int r, caller, proc_nr, s;
+ int r, caller, proc_nr;
message mess;
/* SEF local startup. */
sef_local_startup();
- dprint("sb16_dsp.c: main()\n");
-
- /* Get a DMA buffer. */
- init_buffer();
-
while(TRUE) {
/* Wait for an incoming message */
sef_receive(ANY, &mess);
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_lu(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* Register live update callbacks. */
sef_setcb_lu_prepare(sef_cb_lu_prepare);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the rtl8169 driver. */
+ unsigned left;
+
+ /* Select a buffer that can safely be used for dma transfers.
+ * Its absolute address is 'DmaPhys', the normal address is 'DmaPtr'.
+ */
+#if (CHIP == INTEL)
+ DmaPtr = DmaBuffer;
+ sys_umap(SELF, D, (vir_bytes)DmaBuffer, (phys_bytes)sizeof(DmaBuffer), &DmaPhys);
+
+ if((left = dma_bytes_left(DmaPhys)) < DMA_SIZE) {
+ /* First half of buffer crosses a 64K boundary, can't DMA into that */
+ DmaPtr += left;
+ DmaPhys += left;
+ }
+#else /* CHIP != INTEL */
+ panic("SB16DSP","initialization failed, CHIP != INTEL", 0);
+#endif /* CHIP == INTEL */
+
+ return(OK);
+}
+
/*===========================================================================*
* dsp_open
*===========================================================================*/
send(replyee, &m);
}
-
-/*===========================================================================*
- * init_buffer
- *===========================================================================*/
-PRIVATE void init_buffer()
-{
-/* Select a buffer that can safely be used for dma transfers.
- * Its absolute address is 'DmaPhys', the normal address is 'DmaPtr'.
- */
-
-#if (CHIP == INTEL)
- unsigned left;
-
- DmaPtr = DmaBuffer;
- sys_umap(SELF, D, (vir_bytes)DmaBuffer, (phys_bytes)sizeof(DmaBuffer), &DmaPhys);
-
- if((left = dma_bytes_left(DmaPhys)) < DMA_SIZE) {
- /* First half of buffer crosses a 64K boundary, can't DMA into that */
- DmaPtr += left;
- DmaPhys += left;
- }
-#else /* CHIP != INTEL */
- panic("SB16DSP","init_buffer() failed, CHIP != INTEL", 0);
-#endif /* CHIP == INTEL */
-}
-
-
/*===========================================================================*
* dsp_init
*===========================================================================*/
* main
*===========================================================================*/
PUBLIC void main() {
-message mess;
+ message mess;
int err, caller, proc_nr;
/* SEF local startup. */
PRIVATE char *progname;
PRIVATE int debug;
-FORWARD _PROTOTYPE( void init, (void) );
FORWARD _PROTOTYPE( void hw_init, (struct port *pp) );
FORWARD _PROTOTYPE( void map_regs, (struct port *pp, u32_t base) );
FORWARD _PROTOTYPE( void do_int, (struct port *pp) );
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
+EXTERN int env_argc;
+EXTERN char **env_argv;
+/*===========================================================================*
+ * main *
+ *===========================================================================*/
int main(int argc, char *argv[])
{
- int c, r;
+ int r;
message m;
/* SEF local startup. */
+ env_setargs(argc, argv);
sef_local_startup();
- (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
-
- if((r=micro_delay_calibrate()) != OK)
- panic("ti1225", "micro_delay_calibrate failed", r);
-
- debug= 0;
- while (c= getopt(argc, argv, "d?"), c != -1)
- {
- switch(c)
- {
- case '?': panic("ti1225", "Usage: ti1225 [-d]", NO_NUM);
- case 'd': debug++; break;
- default: panic("ti1225", "getopt failed", NO_NUM);
- }
- }
-
- init();
-
for (;;)
{
r= sef_receive(ANY, &m);
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_lu(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* Register live update callbacks. */
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard);
sef_startup();
}
-PRIVATE void init()
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
- int i, r, first, devind, port;
+/* Initialize the ti1225 driver. */
+ int c, i, r, first, devind, port;
u16_t vid, did;
+ (progname=strrchr(env_argv[0],'/')) ? progname++
+ : (progname=env_argv[0]);
+
+ if((r=micro_delay_calibrate()) != OK)
+ panic("ti1225", "micro_delay_calibrate failed", r);
+
+ debug= 0;
+ while (c= getopt(env_argc, env_argv, "d?"), c != -1)
+ {
+ switch(c)
+ {
+ case '?': panic("ti1225", "Usage: ti1225 [-d]", NO_NUM);
+ case 'd': debug++; break;
+ default: panic("ti1225", "getopt failed", NO_NUM);
+ }
+ }
+
pci_init1(progname);
first= 1;
continue;
hw_init(&ports[i]);
}
+
+ return(OK);
}
PRIVATE void hw_init(pp)
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
/*===========================================================================*
* tty_task *
message tty_mess; /* buffer for all incoming messages */
unsigned line;
- int r, s;
+ int r;
register tty_t *tp;
/* SEF local startup. */
sef_local_startup();
- /* Get kernel environment (protected_mode, pc_at and ega are needed). */
- if (OK != (s=sys_getmachine(&machine))) {
- panic("TTY","Couldn't obtain kernel environment.", s);
- }
-
- /* Initialize the TTY driver. */
- tty_init();
-
- /* Final one-time keyboard initialization. */
- kb_init_once();
-
while (TRUE) {
int adflag = 0;
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* No live update support for now. */
/* Let SEF perform startup. */
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the tty driver. */
+ int r;
+
+ /* Get kernel environment (protected_mode, pc_at and ega are needed). */
+ if (OK != (r=sys_getmachine(&machine))) {
+ panic("TTY","Couldn't obtain kernel environment.", r);
+ }
+
+ /* Initialize the TTY driver. */
+ tty_init();
+
+ /* Final one-time keyboard initialization. */
+ kb_init_once();
+
+ return(OK);
+}
+
/*===========================================================================*
* got_signal *
*===========================================================================*/
# define SYS_RUNCTL (KERNEL_CALL + 46) /* sys_runctl() */
#define NR_SYS_CALLS 47 /* number of system calls */
+#define SYS_CALL_MASK_SIZE BITMAP_CHUNKS(NR_SYS_CALLS)
/* Field names for SYS_MEMSET. */
#define MEM_PTR m2_p1 /* base */
#define RS_LOOKUP (RS_RQ_BASE + 8) /* lookup server name */
+#define RS_INIT (RS_RQ_BASE + 20) /* service init message */
#define RS_LU_PREPARE (RS_RQ_BASE + 21) /* prepare to update message */
# define RS_CMD_ADDR m1_p1 /* command string */
# define RS_NAME m1_p1 /* name */
# define RS_NAME_LEN m1_i1 /* namelen */
+# define RS_INIT_RESULT m1_i1 /* init result */
+# define RS_INIT_TYPE m1_i2 /* init type */
+# define RS_INIT_RPROCTAB_GID m1_i3 /* init rproc table gid */
+
# define RS_LU_RESULT m1_i1 /* live update result */
# define RS_LU_STATE m1_i2 /* state required to update */
# define RS_LU_PREPARE_MAXTIME m1_i3 /* the max time to prepare */
#define VCTLP_STATS_EP 2
/* Total. */
-#define VM_NCALLS 41
+#define NR_VM_CALLS 41
+#define VM_CALL_MASK_SIZE BITMAP_CHUNKS(NR_VM_CALLS)
+
+/* Basic vm calls allowed to every process. */
+#define VM_BASIC_CALLS \
+ VM_MMAP, VM_MUNMAP, VM_MUNMAP_TEXT, VM_MAP_PHYS, VM_UNMAP_PHYS
/*===========================================================================*
* Messages for IPC server *
*/
#define NR_PROCS _NR_PROCS
#define NR_SYS_PROCS _NR_SYS_PROCS
+#define NR_SYS_CHUNKS BITMAP_CHUNKS(NR_SYS_PROCS)
/* Number of controller tasks (/dev/cN device classes). */
#define NR_CTRLRS 2
*/
#include <minix/bitmap.h>
+#include <minix/com.h>
+/* RSS definitions. */
#define RSS_NR_IRQ 16
#define RSS_NR_IO 16
-#define RSS_NR_PCI_ID 32
-#define RSS_NR_PCI_CLASS 4
-#define RSS_NR_SYSTEM 2
-#define RSS_NR_CONTROL 8
+
+/* RSS flags. */
+#define RSS_COPY 0x01 /* Copy the brinary into RS to make it possible
+ * to restart the driver without accessing FS
+ */
+#define RSS_IPC_VALID 0x02 /* rss_ipc and rss_ipclen are valid */
+#define RSS_REUSE 0x04 /* Try to reuse previously copied binary */
+
+/* Common definitions. */
+#define RS_SYS_CALL_MASK_SIZE 2
+#define RS_NR_CONTROL 8
+#define RS_NR_PCI_DEVICE 32
+#define RS_NR_PCI_CLASS 4
+#define RS_MAX_LABEL_LEN 16
/* Labels are copied over separately. */
struct rss_label
int rss_nr_io;
struct { unsigned base; unsigned len; } rss_io[RSS_NR_IO];
int rss_nr_pci_id;
- struct { u16_t vid; u16_t did; } rss_pci_id[RSS_NR_PCI_ID];
+ struct { u16_t vid; u16_t did; } rss_pci_id[RS_NR_PCI_DEVICE];
int rss_nr_pci_class;
- struct { u32_t class; u32_t mask; } rss_pci_class[RSS_NR_PCI_CLASS];
- u32_t rss_system[RSS_NR_SYSTEM];
+ struct { u32_t class; u32_t mask; } rss_pci_class[RS_NR_PCI_CLASS];
+ u32_t rss_system[RS_SYS_CALL_MASK_SIZE];
struct rss_label rss_label;
char *rss_ipc;
size_t rss_ipclen;
-#define RSS_VM_CALL_SIZE BITMAP_CHUNKS(VM_NCALLS)
- bitchunk_t rss_vm[RSS_VM_CALL_SIZE];
+ bitchunk_t rss_vm[VM_CALL_MASK_SIZE];
int rss_nr_control;
- struct rss_label rss_control[RSS_NR_CONTROL];
+ struct rss_label rss_control[RS_NR_CONTROL];
};
-#define RF_COPY 0x01 /* Copy the brinary into RS to make it possible
- * to restart the driver without accessing FS
- */
-#define RF_IPC_VALID 0x02 /* rss_ipc and rss_ipclen are valid */
-#define RF_REUSE 0x04 /* Try to reuse previously copied binary */
-
-#define RSP_LABEL_SIZE 16
-#define RSP_NR_DEVICE 32
-#define RSP_NR_CLASS 4
-
/* ACL information for access to PCI devices */
struct rs_pci
{
- char rsp_label[RSP_LABEL_SIZE]; /* Name of the driver */
+ char rsp_label[RS_MAX_LABEL_LEN];
int rsp_endpoint;
int rsp_nr_device;
- struct { u16_t vid; u16_t did; } rsp_device[RSP_NR_DEVICE];
+ struct { u16_t vid; u16_t did; } rsp_device[RS_NR_PCI_DEVICE];
int rsp_nr_class;
- struct { u32_t class; u32_t mask; } rsp_class[RSP_NR_CLASS];
+ struct { u32_t class; u32_t mask; } rsp_class[RS_NR_PCI_CLASS];
+};
+
+/* Definition of a public entry of the system process table. */
+struct rprocpub {
+ short in_use; /* set when the entry is in use */
+ unsigned sys_flags; /* sys flags */
+ endpoint_t endpoint; /* process endpoint number */
+
+ dev_t dev_nr; /* major device number */
+ int dev_style; /* device style */
+ long period; /* heartbeat period (or zero) */
+
+ char label[RS_MAX_LABEL_LEN]; /* label of this service */
+ char proc_name[RS_MAX_LABEL_LEN]; /* process name of this service */
+
+ bitchunk_t vm_call_mask[VM_CALL_MASK_SIZE]; /* vm call mask */
+
+ struct rs_pci pci_acl; /* pci acl */
};
_PROTOTYPE( int minix_rs_lookup, (const char *name, endpoint_t *value));
#define sef_debug_begin() (void)(NULL)
#define sef_debug_end() fflush(stdout)
+/*===========================================================================*
+ * SEF Init *
+ *===========================================================================*/
+/* What to intercept. */
+#define INTERCEPT_SEF_INIT_REQUESTS 1
+#define IS_SEF_INIT_REQUEST(mp) ((mp)->m_type == RS_INIT \
+ && (mp)->m_source == RS_PROC_NR)
+
+/* Type definitions. */
+typedef struct {
+ int rproctab_gid;
+} sef_init_info_t;
+
+/* Callback type definitions. */
+typedef int(*sef_cb_init_fresh_t)(int type, sef_init_info_t *info);
+typedef int(*sef_cb_init_lu_t)(int type, sef_init_info_t *info);
+typedef int(*sef_cb_init_restart_t)(int type, sef_init_info_t *info);
+
+/* Callback registration helpers. */
+_PROTOTYPE( void sef_setcb_init_fresh, (sef_cb_init_fresh_t cb));
+_PROTOTYPE( void sef_setcb_init_lu, (sef_cb_init_lu_t cb));
+_PROTOTYPE( void sef_setcb_init_restart, (sef_cb_init_restart_t cb));
+
+/* Predefined callback implementations. */
+_PROTOTYPE( int sef_cb_init_fresh_null, (int type, sef_init_info_t *info) );
+_PROTOTYPE( int sef_cb_init_lu_null, (int type, sef_init_info_t *info) );
+_PROTOTYPE( int sef_cb_init_restart_null, (int type, sef_init_info_t *info) );
+
+_PROTOTYPE( int sef_cb_init_restart_fail, (int type, sef_init_info_t *info) );
+
+/* Macros for predefined callback implementations. */
+#define SEF_CB_INIT_FRESH_NULL sef_cb_init_fresh_null
+#define SEF_CB_INIT_LU_NULL sef_cb_init_lu_null
+#define SEF_CB_INIT_RESTART_NULL sef_cb_init_restart_null
+
+#define SEF_CB_INIT_FRESH_DEFAULT sef_cb_init_fresh_null
+#define SEF_CB_INIT_LU_DEFAULT sef_cb_init_lu_null
+#define SEF_CB_INIT_RESTART_DEFAULT sef_cb_init_restart_null
+
+/* Init types. */
+#define SEF_INIT_FRESH 0 /* init fresh */
+#define SEF_INIT_LU 1 /* init after live update */
+#define SEF_INIT_RESTART 2 /* init after restart */
+
+/* Debug. */
+#define SEF_INIT_DEBUG_DEFAULT 0
+
+#ifndef SEF_INIT_DEBUG
+#define SEF_INIT_DEBUG SEF_INIT_DEBUG_DEFAULT
+#endif
+
+#define sef_init_dprint sef_dprint
+#define sef_init_debug_begin sef_debug_begin
+#define sef_init_debug_end sef_debug_end
+
/*===========================================================================*
* SEF Ping *
*===========================================================================*/
#define SI_KPROC_TAB 7 /* copy of kernel process table */
#define SI_CALL_STATS 8 /* system call statistics */
#define SI_PCI_INFO 9 /* get kernel info via PM */
+#define SI_PROCPUB_TAB 10 /* copy of public entries of process table */
/* NULL must be defined in <unistd.h> according to POSIX Sec. 2.7.1. */
#define NULL ((void *)0)
( MAP_CHUNK(map.chunk,bit) |= (1 << CHUNK_OFFSET(bit) )
#define unset_sys_bit(map,bit) \
( MAP_CHUNK(map.chunk,bit) &= ~(1 << CHUNK_OFFSET(bit) )
-#define NR_SYS_CHUNKS BITMAP_CHUNKS(NR_SYS_PROCS)
#define reallock do { int d; d = intr_disabled(); intr_disable(); locklevel++; if(d && locklevel == 1) { minix_panic("reallock while interrupts disabled first time", __LINE__); } } while(0)
}
/* Fill in kernel call mask. */
- for(j = 0; j < CALL_MASK_SIZE; j++) {
+ for(j = 0; j < SYS_CALL_MASK_SIZE; j++) {
priv(rp)->s_k_call_mask[j] = (kcalls == NO_C ? 0 : (~0));
}
}
sys_map_t s_ipc_to; /* allowed destination processes */
/* allowed kernel calls */
-#define CALL_MASK_SIZE BITMAP_CHUNKS(NR_SYS_CALLS)
- bitchunk_t s_k_call_mask[CALL_MASK_SIZE];
+ bitchunk_t s_k_call_mask[SYS_CALL_MASK_SIZE];
sys_map_t s_notify_pending; /* bit map with pending notifications */
irq_id_t s_int_pending; /* pending hardware interrupts */
priv(rp)->s_id = priv_id; /* restore privilege id */
priv(rp)->s_proc_nr = proc_nr; /* reassociate process nr */
- for (i=0; i< BITMAP_CHUNKS(NR_SYS_PROCS); i++) /* remove pending: */
+ for (i=0; i< NR_SYS_CHUNKS; i++) /* remove pending: */
priv(rp)->s_notify_pending.chunk[i] = 0; /* - notifications */
priv(rp)->s_int_pending = 0; /* - interrupts */
sigemptyset(&priv(rp)->s_sig_pending); /* - signals */
priv(rp)->s_trap_mask= DEF_SYS_T; /* allowed traps */
ipc_to_m = DEF_SYS_M; /* allowed targets */
kcalls = DEF_SYS_KC; /* allowed kernel calls */
- for(i = 0; i < CALL_MASK_SIZE; i++) {
+ for(i = 0; i < SYS_CALL_MASK_SIZE; i++) {
priv(rp)->s_k_call_mask[i] = (kcalls == NO_C ? 0 : (~0));
}
/* Verify actual grantee. */
if(g.cp_u.cp_indirect.cp_who_to != grantee &&
- grantee != ANY) {
+ grantee != ANY &&
+ g.cp_u.cp_indirect.cp_who_to != ANY) {
kprintf(
"verify_grant: indirect grant verify "
"failed: bad grantee\n");
}
/* Verify actual grantee. */
- if(g.cp_u.cp_direct.cp_who_to != grantee && grantee != ANY) {
+ if(g.cp_u.cp_direct.cp_who_to != grantee && grantee != ANY
+ && g.cp_u.cp_direct.cp_who_to != ANY) {
kprintf(
"verify_grant: direct grant verify failed: bad grantee\n");
return EPERM;
}
/* Verify actual grantee. */
- if(g.cp_u.cp_magic.cp_who_to != grantee && grantee != ANY) {
+ if(g.cp_u.cp_magic.cp_who_to != grantee && grantee != ANY
+ && g.cp_u.cp_direct.cp_who_to != ANY) {
kprintf(
"verify_grant: magic grant verify failed: bad grantee\n");
return EPERM;
sef.c \
sef_liveupdate.c \
sef_ping.c \
+ sef_init.c \
sys_abort.c \
sys_cprof.c \
sys_endsig.c \
} \
}
+#define NR_STATIC_GRANTS 2
+PRIVATE cp_grant_t static_grants[NR_STATIC_GRANTS];
PRIVATE cp_grant_t *grants = NULL;
PRIVATE int ngrants = 0;
cp_grant_id_t g;
int new_size;
- new_size = (1+ngrants)*2;
- assert(new_size > ngrants);
+ if(!ngrants) {
+ /* Use statically allocated grants the first time. */
+ new_size = NR_STATIC_GRANTS;
+ new_grants = static_grants;
+ }
+ else {
+ new_size = (1+ngrants)*2;
+ assert(new_size > ngrants);
- /* Allocate a block of new size. */
- if(!(new_grants=malloc(new_size * sizeof(grants[0])))) {
- return;
+ /* Allocate a block of new size. */
+ if(!(new_grants=malloc(new_size * sizeof(grants[0])))) {
+ return;
+ }
}
/* Copy old block to new block. */
/* Inform kernel about new size (and possibly new location). */
if((sys_setgrant(new_grants, new_size))) {
- free(new_grants);
+ if(new_grants != static_grants) free(new_grants);
return; /* Failed - don't grow then. */
}
/* Update internal data. */
- if(grants && ngrants > 0) free(grants);
+ if(grants && ngrants > 0 && grants != static_grants) free(grants);
grants = new_grants;
ngrants = new_size;
}
FORWARD _PROTOTYPE( void sef_debug_refresh_params, (void) );
PUBLIC _PROTOTYPE( char* sef_debug_header, (void) );
+/* SEF Init prototypes. */
+EXTERN _PROTOTYPE( int do_sef_rs_init, (void) );
+EXTERN _PROTOTYPE( int do_sef_init_request, (message *m_ptr) );
+
/* SEF Live update prototypes. */
EXTERN _PROTOTYPE( void do_sef_lu_before_receive, (void) );
EXTERN _PROTOTYPE( int do_sef_lu_request, (message *m_ptr) );
sef_self_endpoint = SELF;
sprintf(sef_self_name, "%s", "Unknown");
}
+
+#if INTERCEPT_SEF_INIT_REQUESTS
+ /* Intercept SEF Init requests. */
+ if(sef_self_endpoint == RS_PROC_NR) {
+ if((r = do_sef_rs_init()) != OK) {
+ panic("SEF", "unable to complete init", r);
+ }
+ }
+ else {
+ message m;
+
+ if((r = receive(RS_PROC_NR, &m)) != OK) {
+ panic("SEF", "unable to receive from RS", r);
+ }
+ if(IS_SEF_INIT_REQUEST(&m)) {
+ if((r = do_sef_init_request(&m)) != OK) {
+ panic("SEF", "unable to process init request", r);
+ }
+ }
+ else {
+ panic("SEF", "unable to receive init request", NO_NUM);
+ }
+ }
+#endif
}
/*===========================================================================*
--- /dev/null
+#include "syslib.h"
+#include <assert.h>
+#include <minix/sysutil.h>
+
+/* SEF Init callbacks. */
+PRIVATE struct sef_cbs {
+ sef_cb_init_fresh_t sef_cb_init_fresh;
+ sef_cb_init_lu_t sef_cb_init_lu;
+ sef_cb_init_restart_t sef_cb_init_restart;
+} sef_cbs = {
+ SEF_CB_INIT_FRESH_DEFAULT,
+ SEF_CB_INIT_LU_DEFAULT,
+ SEF_CB_INIT_RESTART_DEFAULT
+};
+
+/* SEF Init prototypes for sef_startup(). */
+PUBLIC _PROTOTYPE( int do_sef_rs_init, (void) );
+PUBLIC _PROTOTYPE( int do_sef_init_request, (message *m_ptr) );
+
+/* Debug. */
+EXTERN _PROTOTYPE( char* sef_debug_header, (void) );
+
+/*===========================================================================*
+ * do_sef_rs_init *
+ *===========================================================================*/
+PUBLIC int do_sef_rs_init()
+{
+/* Special SEF Init for RS. */
+ return sef_cbs.sef_cb_init_fresh(SEF_INIT_FRESH, NULL);
+}
+
+/*===========================================================================*
+ * do_sef_init_request *
+ *===========================================================================*/
+PUBLIC int do_sef_init_request(message *m_ptr)
+{
+/* Handle a SEF Init request. */
+ int r;
+ int type;
+ sef_init_info_t info;
+
+ /* Debug. */
+#if SEF_INIT_DEBUG
+ sef_init_debug_begin();
+ sef_init_dprint("%s. Got a SEF Init request of type: %d. About to init.\n",
+ sef_debug_header(), m_ptr->RS_INIT_TYPE);
+ sef_init_debug_end();
+#endif
+
+ /* Let the callback code handle the request. */
+ type = m_ptr->RS_INIT_TYPE;
+ info.rproctab_gid = m_ptr->RS_INIT_RPROCTAB_GID;
+ switch(type) {
+ case SEF_INIT_FRESH:
+ r = sef_cbs.sef_cb_init_fresh(type, &info);
+ break;
+ case SEF_INIT_LU:
+ r = sef_cbs.sef_cb_init_lu(type, &info);
+ break;
+ case SEF_INIT_RESTART:
+ r = sef_cbs.sef_cb_init_restart(type, &info);
+ break;
+
+ default:
+ /* Not a valid SEF init type. */
+ r = EINVAL;
+ break;
+ }
+
+ /* Report back to RS. XXX FIXME: we should use send, but this would cause
+ * a deadlock due to the current blocking nature of mapdriver().
+ */
+ m_ptr->RS_INIT_RESULT = r;
+ r = asynsend(RS_PROC_NR, m_ptr);
+
+ return r;
+}
+
+/*===========================================================================*
+ * sef_setcb_init_fresh *
+ *===========================================================================*/
+PUBLIC void sef_setcb_init_fresh(sef_cb_init_fresh_t cb)
+{
+ assert(cb != NULL);
+ sef_cbs.sef_cb_init_fresh = cb;
+}
+
+/*===========================================================================*
+ * sef_setcb_init_lu *
+ *===========================================================================*/
+PUBLIC void sef_setcb_init_lu(sef_cb_init_lu_t cb)
+{
+ assert(cb != NULL);
+ sef_cbs.sef_cb_init_lu = cb;
+}
+
+/*===========================================================================*
+ * sef_setcb_init_restart *
+ *===========================================================================*/
+PUBLIC void sef_setcb_init_restart(sef_cb_init_restart_t cb)
+{
+ assert(cb != NULL);
+ sef_cbs.sef_cb_init_restart = cb;
+}
+
+/*===========================================================================*
+ * sef_cb_init_fresh_null *
+ *===========================================================================*/
+PUBLIC int sef_cb_init_fresh_null(int type, sef_init_info_t *info)
+{
+ return(OK);
+}
+
+/*===========================================================================*
+ * sef_cb_init_lu_null *
+ *===========================================================================*/
+PUBLIC int sef_cb_init_lu_null(int type, sef_init_info_t *info)
+{
+ return(OK);
+}
+
+/*===========================================================================*
+ * sef_cb_init_restart_null *
+ *===========================================================================*/
+PUBLIC int sef_cb_init_restart_null(int type, sef_init_info_t *info)
+{
+ return(OK);
+}
+
+/*===========================================================================*
+ * sef_cb_init_restart_fail *
+ *===========================================================================*/
+PUBLIC int sef_cb_init_restart_fail(int type, sef_init_info_t *info)
+{
+ return(ENOSYS);
+}
+
#include <minix/config.h>
#include <string.h>
-PRIVATE int argc = 0;
-PRIVATE char **argv = NULL;
+PUBLIC int env_argc = 0;
+PUBLIC char **env_argv = NULL;
FORWARD _PROTOTYPE( char *find_key, (const char *params, const char *key));
int arg_c;
char *arg_v[];
{
- argc= arg_c;
- argv= arg_v;
+ env_argc= arg_c;
+ env_argv= arg_v;
}
/*===========================================================================*
return EINVAL;
keylen= strlen(key);
- for (i= 1; i<argc; i++)
+ for (i= 1; i<env_argc; i++)
{
- if (strncmp(argv[i], key, keylen) != 0)
+ if (strncmp(env_argv[i], key, keylen) != 0)
continue;
- if (strlen(argv[i]) <= keylen)
+ if (strlen(env_argv[i]) <= keylen)
continue;
- if (argv[i][keylen] != '=')
+ if (env_argv[i][keylen] != '=')
continue;
- key_value= argv[i]+keylen+1;
+ key_value= env_argv[i]+keylen+1;
if (strlen(key_value)+1 > max_len)
return(E2BIG);
strcpy(value, key_value);
#include <minix/sysutil.h>
#include <minix/keymap.h>
#include <minix/bitmap.h>
+#include <minix/rs.h>
#include <stdlib.h>
#include <stdio.h>
extern int errno; /* error number set by system library */
/* Declare some local functions. */
-FORWARD _PROTOTYPE(void init_server, (int argc, char **argv) );
FORWARD _PROTOTYPE(void exit_server, (void) );
FORWARD _PROTOTYPE(void sig_handler, (void) );
FORWARD _PROTOTYPE(void get_work, (message *m_ptr) );
sigset_t sigset;
/* SEF local startup. */
+ env_setargs(argc, argv);
sef_local_startup();
- /* Initialize the server, then go to work. */
- init_server(argc, argv);
-
/* Main loop - get work and do it, forever. */
while (TRUE) {
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_restart_fail);
+
/* No live update support for now. */
/* Let SEF perform startup. */
sef_startup();
}
-/*===========================================================================*
- * init_server *
- *===========================================================================*/
-PRIVATE void init_server(int argc, char **argv)
-{
-/* Initialize the data store server. */
- int i, s;
- struct sigaction sigact;
-
- /* Initialize DS. */
- ds_init();
-}
-
/*===========================================================================*
* sig_handler *
*===========================================================================*/
_PROTOTYPE(int do_subscribe, (message *m_ptr));
_PROTOTYPE(int do_check, (message *m_ptr));
_PROTOTYPE(int do_getsysinfo, (message *m_ptr));
-_PROTOTYPE(void ds_init, (void));
+_PROTOTYPE(int sef_cb_init_fresh, (int type, sef_init_info_t *info));
+_PROTOTYPE(int map_service, (struct rprocpub *rpub));
+
/*===========================================================================*
- * ds_init *
+ * sef_cb_init_fresh *
*===========================================================================*/
-PUBLIC void ds_init(void)
+PUBLIC int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
- int i;
+/* Initialize the data store server. */
+ int i, r;
+ struct rprocpub rprocpub[NR_BOOT_PROCS];
/* Reset data store: data and subscriptions. */
-
for(i = 0; i < NR_DS_KEYS; i++) {
int b;
ds_store[i].ds_flags = 0;
for(i = 0; i < NR_DS_SUBS; i++)
ds_subs[i].sub_flags = 0;
- return;
+ /* Map all the services in the boot image. */
+ if((r = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0,
+ (vir_bytes) rprocpub, sizeof(rprocpub), S)) != OK) {
+ panic("DS", "sys_safecopyfrom failed", r);
+ }
+ for(i=0;i < NR_BOOT_PROCS;i++) {
+ if(rprocpub[i].in_use) {
+ if((r = map_service(&rprocpub[i])) != OK) {
+ panic("DS", "unable to map service", r);
+ }
+ }
+ }
+
+ return(OK);
+}
+
+/*===========================================================================*
+ * map_service *
+ *===========================================================================*/
+PUBLIC int map_service(rpub)
+struct rprocpub *rpub;
+{
+/* Map a new service by registering its label. */
+ struct data_store *dsp;
+
+ dsp = &ds_store[nr_in_use]; /* new slot found */
+ strcpy(dsp->ds_key, rpub->label);
+ dsp->ds_flags = DS_IN_USE | DS_TYPE_U32; /* initialize slot */
+ nr_in_use++;
+
+ dsp->ds_val.ds_val_u32 = (u32_t) rpub->endpoint; /* store data */
+
+ /* If anyone has a matching subscription, update them. */
+ check_subscribers(dsp);
+
+ return(OK);
}
PRIVATE int set_owner(dsp, auth)
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
PUBLIC void main()
{
mq_t *mq;
int r;
- int source, m_type, timerand, fd;
- u32_t tasknr;
- struct fssignon device;
- u8_t randbits[32];
- struct timeval tv;
+ int source, m_type;
/* SEF local startup. */
sef_local_startup();
-#if DEBUG
- printf("Starting inet...\n");
- printf("%s\n", version);
-#endif
-
-#if HZ_DYNAMIC
- system_hz = sys_hz();
-#endif
-
- /* Read configuration. */
- nw_conf();
-
- /* Get a random number */
- timerand= 1;
- fd= open(RANDOM_DEV_NAME, O_RDONLY | O_NONBLOCK);
- if (fd != -1)
- {
- r= read(fd, randbits, sizeof(randbits));
- if (r == sizeof(randbits))
- timerand= 0;
- else
- {
- printf("inet: unable to read random data from %s: %s\n",
- RANDOM_DEV_NAME, r == -1 ? strerror(errno) :
- r == 0 ? "EOF" : "not enough data");
- }
- close(fd);
- }
- else
- {
- printf("inet: unable to open random device %s: %s\n",
- RANDOM_DEV_NAME, strerror(errno));
- }
- if (timerand)
- {
- printf("inet: using current time for random-number seed\n");
- r= gettimeofday(&tv, NULL);
- if (r == -1)
- {
- printf("sysutime failed: %s\n", strerror(errno));
- exit(1);
- }
- memcpy(randbits, &tv, sizeof(tv));
- }
- init_rand256(randbits);
-
- /* Our new identity as a server. */
- r= ds_retrieve_u32("inet", &tasknr);
- if (r != OK)
- ip_panic(("inet: ds_retrieve_u32 failed for 'inet': %d", r));
- this_proc= tasknr;
-
- /* Register the device group. */
- device.dev= ip_dev;
- device.style= STYLE_CLONE;
- if (svrctl(FSSIGNON, (void *) &device) == -1) {
- printf("inet: error %d on registering ethernet devices\n",
- errno);
- pause();
- }
-
-#ifdef BUF_CONSISTENCY_CHECK
- inet_buf_debug= (getenv("inetbufdebug") &&
- (strcmp(getenv("inetbufdebug"), "on") == 0));
- inet_buf_debug= 100;
- if (inet_buf_debug)
- {
- ip_warning(( "buffer consistency check enabled" ));
- }
-#endif
-
- if (getenv("killerinet"))
- {
- ip_warning(( "killer inet active" ));
- killer_inet= 1;
- }
-
- nw_init();
while (TRUE)
{
#ifdef BUF_CONSISTENCY_CHECK
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_restart_fail);
+
/* No live update support for now. */
/* Let SEF perform startup. */
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the inet server. */
+ int r;
+ int timerand, fd;
+ u32_t tasknr;
+ struct fssignon device;
+ u8_t randbits[32];
+ struct timeval tv;
+
+#if DEBUG
+ printf("Starting inet...\n");
+ printf("%s\n", version);
+#endif
+
+#if HZ_DYNAMIC
+ system_hz = sys_hz();
+#endif
+
+ /* Read configuration. */
+ nw_conf();
+
+ /* Get a random number */
+ timerand= 1;
+ fd= open(RANDOM_DEV_NAME, O_RDONLY | O_NONBLOCK);
+ if (fd != -1)
+ {
+ r= read(fd, randbits, sizeof(randbits));
+ if (r == sizeof(randbits))
+ timerand= 0;
+ else
+ {
+ printf("inet: unable to read random data from %s: %s\n",
+ RANDOM_DEV_NAME, r == -1 ? strerror(errno) :
+ r == 0 ? "EOF" : "not enough data");
+ }
+ close(fd);
+ }
+ else
+ {
+ printf("inet: unable to open random device %s: %s\n",
+ RANDOM_DEV_NAME, strerror(errno));
+ }
+ if (timerand)
+ {
+ printf("inet: using current time for random-number seed\n");
+ r= gettimeofday(&tv, NULL);
+ if (r == -1)
+ {
+ printf("sysutime failed: %s\n", strerror(errno));
+ exit(1);
+ }
+ memcpy(randbits, &tv, sizeof(tv));
+ }
+ init_rand256(randbits);
+
+ /* Our new identity as a server. */
+ r= ds_retrieve_u32("inet", &tasknr);
+ if (r != OK)
+ ip_panic(("inet: ds_retrieve_u32 failed for 'inet': %d", r));
+ this_proc= tasknr;
+
+ /* Register the device group. */
+ device.dev= ip_dev;
+ device.style= STYLE_CLONE;
+ if (svrctl(FSSIGNON, (void *) &device) == -1) {
+ printf("inet: error %d on registering ethernet devices\n",
+ errno);
+ pause();
+ }
+
+#ifdef BUF_CONSISTENCY_CHECK
+ inet_buf_debug= (getenv("inetbufdebug") &&
+ (strcmp(getenv("inetbufdebug"), "on") == 0));
+ inet_buf_debug= 100;
+ if (inet_buf_debug)
+ {
+ ip_warning(( "buffer consistency check enabled" ));
+ }
+#endif
+
+ if (getenv("killerinet"))
+ {
+ ip_warning(( "killer inet active" ));
+ killer_inet= 1;
+ }
+
+ nw_init();
+
+ return(OK);
+}
+
PRIVATE void nw_conf()
{
read_conf();
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
PUBLIC int main(int argc, char *argv[])
{
message m;
/* SEF local startup. */
+ env_setargs(argc, argv);
sef_local_startup();
- SELF_E = getprocnr();
-
- if(verbose)
- printf("IPC: self: %d\n", SELF_E);
-
while (TRUE) {
int r;
int i;
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* No live update support for now. */
/* Let SEF perform startup. */
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the ipc server. */
+
+ SELF_E = getprocnr();
+
+ if(verbose)
+ printf("IPC: self: %d\n", SELF_E);
+
+ return(OK);
+}
+
#include "../rs/const.h"
#include "../rs/type.h"
+PUBLIC struct rprocpub rprocpub[NR_SYS_PROCS];
PUBLIC struct rproc rproc[NR_SYS_PROCS];
FORWARD _PROTOTYPE( char *s_flags_str, (int flags) );
PUBLIC void rproc_dmp()
{
struct rproc *rp;
+ struct rprocpub *rpub;
int i,j, n=0;
static int prev_i=0;
+ getsysinfo(RS_PROC_NR, SI_PROCPUB_TAB, rprocpub);
getsysinfo(RS_PROC_NR, SI_PROC_TAB, rproc);
printf("Reincarnation Server (RS) system process table dump\n");
printf("----label---- endpoint- -pid- flags -dev- -T- alive_tm starts command\n");
for (i=prev_i; i<NR_SYS_PROCS; i++) {
rp = &rproc[i];
+ rpub = &rprocpub[i];
if (! rp->r_flags & RS_IN_USE) continue;
if (++n > 22) break;
printf("%13s %9d %5d %5s %3d/%1d %3u %8u %5dx %s",
- rp->r_label, rp->r_proc_nr_e, rp->r_pid,
- s_flags_str(rp->r_flags), rp->r_dev_nr, rp->r_dev_style,
- rp->r_period, rp->r_alive_tm, rp->r_restarts,
+ rpub->label, rpub->endpoint, rp->r_pid,
+ s_flags_str(rp->r_flags), rpub->dev_nr, rpub->dev_style,
+ rpub->period, rp->r_alive_tm, rp->r_restarts,
rp->r_cmd
);
printf("\n");
{
static char str[10];
str[0] = (flags & RS_IN_USE) ? 'U' : '-';
- str[1] = (flags & RS_EXITING) ? 'E' : '-';
- str[2] = (flags & RS_REFRESHING) ? 'R' : '-';
- str[3] = (flags & RS_NOPINGREPLY) ? 'N' : '-';
- str[4] = (flags & RS_UPDATING) ? 'u' : '-';
+ str[1] = (flags & RS_INITIALIZING) ? 'I' : '-';
+ str[2] = (flags & RS_UPDATING) ? 'u' : '-';
+ str[3] = (flags & RS_EXITING) ? 'E' : '-';
+ str[4] = (flags & RS_NOPINGREPLY) ? 'N' : '-';
str[5] = '\0';
return(str);
extern int errno; /* error number set by system library */
/* Declare some local functions. */
-FORWARD _PROTOTYPE(void init_server, (int argc, char **argv) );
FORWARD _PROTOTYPE(void sig_handler, (void) );
FORWARD _PROTOTYPE(void get_work, (void) );
FORWARD _PROTOTYPE(void reply, (int whom, int result) );
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
/*===========================================================================*
* main *
sigset_t sigset;
/* SEF local startup. */
+ env_setargs(argc, argv);
sef_local_startup();
- /* Initialize the server, then go to work. */
- init_server(argc, argv);
-
/* Main loop - get work and do it, forever. */
while (TRUE) {
/* Wait for incoming message, sets 'callnr' and 'who'. */
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_lu(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_fresh);
+
/* Register live update callbacks. */
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard);
}
/*===========================================================================*
- * init_server *
+ * sef_cb_init_fresh *
*===========================================================================*/
-PRIVATE void init_server(int argc, char **argv)
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
-/* Initialize the information service. */
+/* Initialize the information server. */
struct sigaction sigact;
/* Install signal handler. Ask PM to transform signal into message. */
/* Set key mappings. */
map_unmap_fkeys(TRUE /*map*/);
+
+ return(OK);
}
/*===========================================================================*
#include "glo.h"
/* Declare some local functions. */
-FORWARD _PROTOTYPE(void init_server, (void) );
FORWARD _PROTOTYPE(void get_work, (message *m_in) );
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
/*===========================================================================*
* main *
/* SEF local startup. */
sef_local_startup();
- /* Initialize the server, then go to work. */
- init_server();
-
- fs_m_in.m_type = FS_READY;
-
- if (send(FS_PROC_NR, &fs_m_in) != OK) {
- printf("ISOFS (%d): Error sending login to VFS\n", SELF_E);
- return -1;
- }
-
for (;;) {
/* Wait for request message. */
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_restart_fail);
+
/* No live update support for now. */
/* Let SEF perform startup. */
}
/*===========================================================================*
- * init_server *
+ * sef_cb_init_fresh *
*===========================================================================*/
-PRIVATE void init_server(void)
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
- int i;
+/* Initialize the iso9660fs server. */
+ int i, r;
/* Init driver mapping */
for (i = 0; i < NR_DEVICES; ++i)
SELF_E = getprocnr();
/* hash_init(); */ /* Init the table with the ids */
setenv("TZ","",1); /* Used to calculate the time */
+
+ fs_m_in.m_type = FS_READY;
+
+ if ((r = send(FS_PROC_NR, &fs_m_in)) != OK) {
+ panic("ISOFS", "Error sending login to VFS", r);
+ }
+
+ return(OK);
}
/*===========================================================================*
/* Declare some local functions. */
-FORWARD _PROTOTYPE(void init_server, (void) );
FORWARD _PROTOTYPE(void get_work, (message *m_in) );
FORWARD _PROTOTYPE(void cch_check, (void) );
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
/*===========================================================================*
* main *
message m;
/* SEF local startup. */
+ env_setargs(argc, argv);
sef_local_startup();
- /* Initialize the server, then go to work. */
- init_server();
-
- fs_m_in.m_type = FS_READY;
-
- if (send(FS_PROC_NR, &fs_m_in) != OK) {
- printf("MFS(%d): Error sending login to VFS\n", SELF_E);
- return(-1);
- }
-
while(!unmountdone || !exitsignaled) {
endpoint_t src;
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_restart_fail);
+
/* No live update support for now. */
/* Let SEF perform startup. */
}
/*===========================================================================*
- * init_server *
+ * sef_cb_init_fresh *
*===========================================================================*/
-PRIVATE void init_server(void)
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
- int i;
+/* Initialize the Minix file server. */
+ int i, r;
/* Init inode table */
for (i = 0; i < NR_INODES; ++i) {
SELF_E = getprocnr();
buf_pool();
fs_block_size = _MIN_BLOCK_SIZE;
+
+ fs_m_in.m_type = FS_READY;
+
+ if ((r = send(FS_PROC_NR, &fs_m_in)) != OK) {
+ panic("MFS", "Error sending login to VFS", r);
+ }
+
+ return(OK);
}
r = ds_retrieve_u32(fs_dev_label, &tasknr);
if (r != OK) {
printf("%s:%d fs_readsuper: ds_retrieve_u32 failed for '%s': %d\n",
- fs_dev_label, __FILE__, __LINE__, r);
+ __FILE__, __LINE__, fs_dev_label, r);
return(EINVAL);
}
#include "inode.h"
#include "drivers.h"
-FORWARD _PROTOTYPE(void init_server, (void) );
FORWARD _PROTOTYPE(void get_work, (message *m_in) );
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
/*===========================================================================*
* main *
message m;
/* SEF local startup. */
+ env_setargs(argc, argv);
sef_local_startup();
- /* Initialize the server, then go to work. */
- init_server();
-
while(!exitsignaled || busy) {
endpoint_t src;
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_restart_fail);
+
/* No live update support for now. */
/* Let SEF perform startup. */
}
/*===========================================================================*
- * init_server *
+ * sef_cb_init_fresh *
*===========================================================================*/
-PRIVATE void init_server(void)
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
+/* Initialize the pipe file server. */
int i;
/* Initialize main loop parameters. */
SELF_E = getprocnr();
buf_pool();
+
+ return(OK);
}
#endif
FORWARD _PROTOTYPE( void get_work, (void) );
-FORWARD _PROTOTYPE( void pm_init, (void) );
FORWARD _PROTOTYPE( int get_nice_value, (int queue) );
FORWARD _PROTOTYPE( void handle_fs_reply, (void) );
#define click_to_round_k(n) \
((unsigned) ((((unsigned long) (n) << CLICK_SHIFT) + 512) / 1024))
+extern int unmap_ok;
+
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
/*===========================================================================*
* main *
/* SEF local startup. */
sef_local_startup();
- pm_init(); /* initialize process manager tables */
-
/* This is PM's main loop- get work and do it, forever and forever. */
while (TRUE) {
get_work(); /* wait for an PM system call */
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_restart_fail);
+
/* No live update support for now. */
/* Let SEF perform startup. */
}
/*===========================================================================*
- * get_work *
- *===========================================================================*/
-PRIVATE void get_work()
-{
-/* Wait for the next message and extract useful information from it. */
- if (sef_receive(ANY, &m_in) != OK)
- panic(__FILE__,"PM sef_receive error", NO_NUM);
- who_e = m_in.m_source; /* who sent the message */
- if(pm_isokendpt(who_e, &who_p) != OK)
- panic(__FILE__, "PM got message from invalid endpoint", who_e);
- call_nr = m_in.m_type; /* system call number */
-
- /* Process slot of caller. Misuse PM's own process slot if the kernel is
- * calling. This can happen in case of synchronous alarms (CLOCK) or or
- * event like pending kernel signals (SYSTEM).
- */
- mp = &mproc[who_p < 0 ? PM_PROC_NR : who_p];
- if(who_p >= 0 && mp->mp_endpoint != who_e) {
- panic(__FILE__, "PM endpoint number out of sync with source",
- mp->mp_endpoint);
- }
-}
-
-/*===========================================================================*
- * setreply *
- *===========================================================================*/
-PUBLIC void setreply(proc_nr, result)
-int proc_nr; /* process to reply to */
-int result; /* result of call (usually OK or error #) */
-{
-/* Fill in a reply message to be sent later to a user process. System calls
- * may occasionally fill in other fields, this is only for the main return
- * value, and for setting the "must send reply" flag.
- */
- register struct mproc *rmp = &mproc[proc_nr];
-
- if(proc_nr < 0 || proc_nr >= NR_PROCS)
- panic(__FILE__,"setreply arg out of range", proc_nr);
-
- rmp->mp_reply.reply_res = result;
- rmp->mp_flags |= REPLY; /* reply pending */
-}
-
-extern int unmap_ok;
-
-/*===========================================================================*
- * pm_init *
+ * sef_cb_init_fresh *
*===========================================================================*/
-PRIVATE void pm_init()
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
/* Initialize the process manager.
* Memory use info is collected from the boot monitor, the kernel, and
*/
unmap_ok = 1;
_minix_unmapzero();
+
+ return(OK);
+}
+
+/*===========================================================================*
+ * get_work *
+ *===========================================================================*/
+PRIVATE void get_work()
+{
+/* Wait for the next message and extract useful information from it. */
+ if (sef_receive(ANY, &m_in) != OK)
+ panic(__FILE__,"PM sef_receive error", NO_NUM);
+ who_e = m_in.m_source; /* who sent the message */
+ if(pm_isokendpt(who_e, &who_p) != OK)
+ panic(__FILE__, "PM got message from invalid endpoint", who_e);
+ call_nr = m_in.m_type; /* system call number */
+
+ /* Process slot of caller. Misuse PM's own process slot if the kernel is
+ * calling. This can happen in case of synchronous alarms (CLOCK) or or
+ * event like pending kernel signals (SYSTEM).
+ */
+ mp = &mproc[who_p < 0 ? PM_PROC_NR : who_p];
+ if(who_p >= 0 && mp->mp_endpoint != who_e) {
+ panic(__FILE__, "PM endpoint number out of sync with source",
+ mp->mp_endpoint);
+ }
+}
+
+/*===========================================================================*
+ * setreply *
+ *===========================================================================*/
+PUBLIC void setreply(proc_nr, result)
+int proc_nr; /* process to reply to */
+int result; /* result of call (usually OK or error #) */
+{
+/* Fill in a reply message to be sent later to a user process. System calls
+ * may occasionally fill in other fields, this is only for the main return
+ * value, and for setting the "must send reply" flag.
+ */
+ register struct mproc *rmp = &mproc[proc_nr];
+
+ if(proc_nr < 0 || proc_nr >= NR_PROCS)
+ panic(__FILE__,"setreply arg out of range", proc_nr);
+
+ rmp->mp_reply.reply_res = result;
+ rmp->mp_flags |= REPLY; /* reply pending */
}
/*===========================================================================*
/* Space reserved for program and arguments. */
#define MAX_COMMAND_LEN 512 /* maximum argument string length */
-#define MAX_LABEL_LEN 16 /* Unique name of (this instance of)
- * the service
- */
#define MAX_SCRIPT_LEN 256 /* maximum restart script name length */
#define MAX_NR_ARGS 4 /* maximum number of arguments */
#define MAX_IPC_LIST 256 /* Max size of list for IPC target
* process names
*/
-#define MAX_VM_LIST 256
/* Flag values. */
#define RS_IN_USE 0x001 /* set when process slot is in use */
#define RS_CRASHED 0x040 /* service crashed */
#define RS_LATEREPLY 0x080 /* no reply sent to RS_DOWN caller yet */
#define RS_SIGNALED 0x100 /* service crashed */
-#define RS_UPDATING 0x200 /* set when update must be done */
+#define RS_INITIALIZING 0x200 /* set when init is in progress */
+#define RS_UPDATING 0x400 /* set when update is in progress */
/* Sys flag values. */
-#define SF_CORE_PROC 0x001 /* set for core system processes
+#define SF_CORE_SRV 0x001 /* set for core system services
* XXX FIXME: This should trigger a system
- * panic when a CORE_PROC service cannot
+ * panic when a CORE_SRV service cannot
* be restarted. We need better error-handling
* in RS to change this.
*/
+#define SF_SYNCH_BOOT 0X002 /* set when process needs synch boot init */
#define SF_NEED_COPY 0x004 /* set when process needs copy to restart */
#define SF_USE_COPY 0x008 /* set when process has a copy in memory */
/* Constants determining RS period and binary exponential backoff. */
+#define RS_INIT_T 600 /* allow T ticks for init */
#define RS_DELTA_T 60 /* check every T ticks */
#define BACKOFF_BITS (sizeof(long)*8) /* bits in backoff field */
#define MAX_BACKOFF 30 /* max backoff in RS_DELTA_T */
/* Definitions for boot info tables. */
#define NULL_BOOT_NR NR_BOOT_PROCS /* marks a null boot entry */
#define DEFAULT_BOOT_NR NR_BOOT_PROCS /* marks the default boot entry */
-#define SYS_ALL_C (NR_SYS_CALLS+0) /* specifies all calls */
-#define SYS_NULL_C (NR_SYS_CALLS+1) /* marks a null call entry */
+#define SYS_ALL_C (-1) /* specifies all calls */
+#define SYS_NULL_C (-2) /* marks a null call entry */
/* Define privilege flags for the various process types. */
#define SRV_F (SYS_PROC | PREEMPTIBLE) /* system services */
| spi_to(VM_PROC_NR) ) /* root user proc */
/* Define sys flags for the various process types. */
-#define SRV_SF (SF_CORE_PROC | SF_NEED_COPY) /* system services */
+#define SRV_SF (SF_CORE_SRV | SF_NEED_COPY) /* system services */
#define SRVC_SF (SRV_SF | SF_USE_COPY) /* system services with a copy */
#define DSRV_SF (0) /* dynamic system services */
+#define VM_SF (SRV_SF | SF_SYNCH_BOOT) /* vm */
#endif /* RS_CONST_H */
* services (servers and drivers), and thus is not directly indexed by
* slot number.
*/
+EXTERN struct rprocpub rprocpub[NR_SYS_PROCS]; /* public entries */
EXTERN struct rproc rproc[NR_SYS_PROCS];
EXTERN struct rproc *rproc_ptr[NR_PROCS]; /* mapping for fast access */
*/
EXTERN int exec_pipe[2];
+/* Global init descriptor. This descriptor holds data to initialize system
+ * services.
+ */
+EXTERN sef_init_info_t rinit;
+
/* Global update descriptor. This descriptor holds data when a live update
* is in progress.
*/
struct boot_image *image,
struct boot_image **ip, struct boot_image_priv **pp,
struct boot_image_sys **sp, struct boot_image_dev **dp) );
-FORWARD _PROTOTYPE(void fill_call_mask, ( int *calls, int tot_nr_calls,
- bitchunk_t *call_mask, int call_base) );
-FORWARD _PROTOTYPE(void init_server, (void) );
+FORWARD _PROTOTYPE(void catch_boot_init_ready, (endpoint_t endpoint) );
FORWARD _PROTOTYPE(void sig_handler, (void) );
FORWARD _PROTOTYPE(void get_work, (message *m) );
FORWARD _PROTOTYPE(void reply, (int whom, message *m_out) );
PRIVATE int boot_image_buffer_size;
PRIVATE char *boot_image_buffer;
-/* Macro to identify a system service in the boot image. This rules out
- * kernel tasks and the root system process (RS).
- */
-#define isbootsrvprocn(n) (!iskerneln((n)) && !isrootsysn((n)))
-
/* Flag set when memory unmapping can be done. */
EXTERN int unmap_ok;
/* SEF functions and variables. */
-FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
/*===========================================================================*
* main *
message m; /* request message */
int call_nr, who_e,who_p; /* call number and caller */
int result; /* result to return */
- sigset_t sigset; /* system signal set */
- int s;
/* SEF local startup. */
sef_local_startup();
- /* Initialize the server, then go to work. */
- init_server();
-
/* Main loop - get work and do it, forever. */
while (TRUE) {
/* Now determine what to do. Four types of requests are expected:
* - Heartbeat messages (notifications from registered system services)
* - System notifications (POSIX signals or synchronous alarm)
- * - Ready to update messages (reply messages from registered services)
* - User requests (control messages to manage system services)
+ * - Ready messages (reply messages from registered services)
*/
/* Notification messages are control messages and do not need a reply.
}
}
- /* See if this is a ready to update message.
- * If the message was expected, update the originating process
- */
- else if(call_nr == RS_LU_PREPARE) {
- result = do_upd_ready(&m);
-
- /* Send reply only if something went wrong. */
- if (result != OK) {
- m.m_type = result;
- reply(who_e, &m);
- }
- }
-
- /* If this is neither a ready to update message nor a notification
- * message, it is a normal request.
+ /* If we get this far, this is a normal request.
* Handle the request and send a reply to the caller.
*/
else {
/* Handler functions are responsible for permission checking. */
switch(call_nr) {
+ /* User requests. */
case RS_UP: result = do_up(&m); break;
case RS_DOWN: result = do_down(&m); break;
case RS_REFRESH: result = do_refresh(&m); break;
case RS_UPDATE: result = do_update(&m); break;
case GETSYSINFO: result = do_getsysinfo(&m); break;
case RS_LOOKUP: result = do_lookup(&m); break;
+ /* Ready messages. */
+ case RS_INIT: result = do_init_ready(&m); break;
+ case RS_LU_PREPARE: result = do_upd_ready(&m); break;
default:
printf("Warning, RS got unexpected request %d from %d\n",
m.m_type, m.m_source);
*===========================================================================*/
PRIVATE void sef_local_startup()
{
- /* No live update support for now. */
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh); /* RS can only start fresh. */
/* Let SEF perform startup. */
sef_startup();
}
/*===========================================================================*
- * exec_image_copy *
- *===========================================================================*/
-PRIVATE void exec_image_copy(boot_proc_idx, ip, rp)
-int boot_proc_idx;
-struct boot_image *ip;
-struct rproc *rp;
-{
-/* Copy the executable image of the given boot process. */
- int s;
- struct exec header;
- static char *boot_image_ptr = NULL;
-
- if(boot_image_ptr == NULL) {
- boot_image_ptr = boot_image_buffer;
- }
- s = NO_NUM;
-
- /* Get a.out header. */
- if(boot_image_buffer+boot_image_buffer_size - boot_image_ptr < sizeof(header)
- || (s = sys_getaoutheader(&header, boot_proc_idx)) != OK) {
- panic("RS", "unable to get copy of a.out header", s);
- }
- memcpy(boot_image_ptr, &header, header.a_hdrlen);
- boot_image_ptr += header.a_hdrlen;
-
- /* Get text segment. */
- if(boot_image_buffer+boot_image_buffer_size - boot_image_ptr < header.a_text
- || (s = rs_startup_segcopy(ip->endpoint, T, D, (vir_bytes) boot_image_ptr,
- header.a_text)) != OK) {
- panic("RS", "unable to get copy of text segment", s);
- }
- boot_image_ptr += header.a_text;
-
- /* Get data segment. */
- if(boot_image_buffer+boot_image_buffer_size - boot_image_ptr < header.a_data
- || (s = rs_startup_segcopy(ip->endpoint, D, D, (vir_bytes) boot_image_ptr,
- header.a_data)) != OK) {
- panic("RS", "unable to get copy of data segment", s);
- }
- boot_image_ptr += header.a_data;
-
- /* Set the executable image for the given boot process. */
- rp->r_exec_len = header.a_hdrlen + header.a_text + header.a_data;
- rp->r_exec = boot_image_ptr - rp->r_exec_len;
-}
-
-/*===========================================================================*
- * boot_image_info_lookup *
- *===========================================================================*/
-PRIVATE void boot_image_info_lookup(endpoint, image, ip, pp, sp, dp)
-endpoint_t endpoint;
-struct boot_image *image;
-struct boot_image **ip;
-struct boot_image_priv **pp;
-struct boot_image_sys **sp;
-struct boot_image_dev **dp;
-{
-/* Lookup entries in boot image tables. */
- int i;
-
- /* When requested, locate the corresponding entry in the boot image table
- * or panic if not found.
- */
- if(ip) {
- for (i=0; i < NR_BOOT_PROCS; i++) {
- if(image[i].endpoint == endpoint) {
- *ip = &image[i];
- break;
- }
- }
- if(i == NR_BOOT_PROCS) {
- panic("RS", "boot image table lookup failed", NO_NUM);
- }
- }
-
- /* When requested, locate the corresponding entry in the boot image priv table
- * or panic if not found.
- */
- if(pp) {
- for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) {
- if(boot_image_priv_table[i].endpoint == endpoint) {
- *pp = &boot_image_priv_table[i];
- break;
- }
- }
- if(i == NULL_BOOT_NR) {
- panic("RS", "boot image priv table lookup failed", NO_NUM);
- }
- }
-
- /* When requested, locate the corresponding entry in the boot image sys table
- * or resort to the default entry if not found.
- */
- if(sp) {
- for (i=0; boot_image_sys_table[i].endpoint != DEFAULT_BOOT_NR; i++) {
- if(boot_image_sys_table[i].endpoint == endpoint) {
- *sp = &boot_image_sys_table[i];
- break;
- }
- }
- if(boot_image_sys_table[i].endpoint == DEFAULT_BOOT_NR) {
- *sp = &boot_image_sys_table[i]; /* accept the default entry */
- }
- }
-
- /* When requested, locate the corresponding entry in the boot image dev table
- * or resort to the default entry if not found.
- */
- if(dp) {
- for (i=0; boot_image_dev_table[i].endpoint != DEFAULT_BOOT_NR; i++) {
- if(boot_image_dev_table[i].endpoint == endpoint) {
- *dp = &boot_image_dev_table[i];
- break;
- }
- }
- if(boot_image_dev_table[i].endpoint == DEFAULT_BOOT_NR) {
- *dp = &boot_image_dev_table[i]; /* accept the default entry */
- }
- }
-}
-
-/*===========================================================================*
- * fill_call_mask *
+ * sef_cb_init_fresh *
*===========================================================================*/
-PRIVATE void fill_call_mask(calls, tot_nr_calls, call_mask, call_base)
-int *calls; /* the unordered set of calls */
-int tot_nr_calls; /* the total number of calls */
-bitchunk_t *call_mask; /* the call mask to fill in */
-int call_base; /* the base offset for the calls */
-{
-/* Fill a call mask from an unordered set of calls. */
- int i;
- bitchunk_t fv;
- int call_mask_size, nr_calls;
-
- call_mask_size = BITMAP_CHUNKS(tot_nr_calls);
-
- /* Count the number of calls to fill in. */
- nr_calls = 0;
- for(i=0; calls[i] != SYS_NULL_C; i++) {
- nr_calls++;
- }
-
- /* See if all calls are allowed and call mask must be completely filled. */
- fv = 0;
- if(nr_calls == 1 && calls[0] == SYS_ALL_C) {
- fv = (~0);
- }
-
- /* Fill or clear call mask. */
- for(i=0; i < call_mask_size; i++) {
- call_mask[i] = fv;
- }
-
- /* Not all calls allowed? Enter calls bit by bit. */
- if(!fv) {
- for(i=0; i < nr_calls; i++) {
- SET_BIT(call_mask, calls[i] - call_base);
- }
- }
-}
-
-/*===========================================================================*
- * init_server *
- *===========================================================================*/
-PRIVATE void init_server(void)
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
/* Initialize the reincarnation server. */
struct sigaction sa;
struct boot_image *ip;
int s,i,j;
- int nr_image_srvs, nr_image_priv_srvs;
+ int nr_image_srvs, nr_image_priv_srvs, nr_uncaught_init_srvs;
struct rproc *rp;
+ struct rprocpub *rpub;
struct boot_image image[NR_BOOT_PROCS];
struct mproc mproc[NR_PROCS];
struct exec header;
/* See if we run in verbose mode. */
env_parse("rs_verbose", "d", 0, &rs_verbose, 0, 1);
+ /* Initialize the global init descriptor. */
+ rinit.rproctab_gid = cpf_grant_direct(ANY, (vir_bytes) rprocpub,
+ sizeof(rprocpub), CPF_READ);
+ if(!GRANT_VALID(rinit.rproctab_gid)) {
+ panic("RS", "unable to create rprocpub table grant", rinit.rproctab_gid);
+ }
+
/* Initialize the global update descriptor. */
rupdate.flags = 0;
ip = &image[i];
/* System services only. */
- if(!isbootsrvprocn(_ENDPOINT_P(ip->endpoint))) {
+ if(iskerneln(_ENDPOINT_P(ip->endpoint))) {
continue;
}
nr_image_srvs++;
boot_image_priv = &boot_image_priv_table[i];
/* System services only. */
- if(!isbootsrvprocn(_ENDPOINT_P(boot_image_priv->endpoint))) {
+ if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) {
continue;
}
nr_image_priv_srvs++;
}
}
- /* Initialize the system process table in 3 steps, each of them following
+ /* Reset the system process table. */
+ for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
+ rp->r_flags = 0;
+ rp->r_pub = &rprocpub[rp - rproc];
+ rp->r_pub->in_use = FALSE;
+ }
+
+ /* Initialize the system process table in 4 steps, each of them following
* the appearance of system services in the boot image priv table.
* - Step 1: get a copy of the executable image of every system service that
* requires it while it is not yet running.
boot_image_priv = &boot_image_priv_table[i];
/* System services only. */
- if(!isbootsrvprocn(_ENDPOINT_P(boot_image_priv->endpoint))) {
+ if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) {
continue;
}
boot_image_info_lookup(boot_image_priv->endpoint, image,
&ip, NULL, &boot_image_sys, &boot_image_dev);
rp = &rproc[boot_image_priv - boot_image_priv_table];
+ rpub = rp->r_pub;
/*
* Get a copy of the executable image if required.
/*
* Set privileges.
- * XXX FIXME: We should also let RS set vm calls allowed for each sys
- * service by using vm_set_priv(). We need a more uniform privilege
- * management scheme in VM for this change.
*/
/* Get label. */
- strcpy(rp->r_label, boot_image_priv->label);
-
- /* Force a static privilege id for system services in the boot image. */
- rp->r_priv.s_id = static_priv_id(_ENDPOINT_P(boot_image_priv->endpoint));
-
- /* Initialize privilege bitmaps. */
- rp->r_priv.s_flags = boot_image_priv->flags; /* privilege flags */
- rp->r_priv.s_trap_mask = boot_image_priv->trap_mask; /* allowed traps */
- memcpy(&rp->r_priv.s_ipc_to, &boot_image_priv->ipc_to,
- sizeof(rp->r_priv.s_ipc_to)); /* allowed targets */
-
- /* Initialize call mask bitmap from unordered set. */
- fill_call_mask(boot_image_priv->k_calls, NR_SYS_CALLS,
- rp->r_priv.s_k_call_mask, KERNEL_CALL);
-
- /* Set the privilege structure. */
- if ((s = sys_privctl(ip->endpoint, SYS_PRIV_SET_SYS, &(rp->r_priv)))
- != OK) {
- panic("RS", "unable to set privilege structure", s);
+ strcpy(rpub->label, boot_image_priv->label);
+
+ if(boot_image_priv->endpoint != RS_PROC_NR) {
+ /* Force a static priv id for system services in the boot image. */
+ rp->r_priv.s_id = static_priv_id(
+ _ENDPOINT_P(boot_image_priv->endpoint));
+
+ /* Initialize privilege bitmaps. */
+ rp->r_priv.s_flags = boot_image_priv->flags; /* priv flags */
+ rp->r_priv.s_trap_mask = boot_image_priv->trap_mask; /* traps */
+ memcpy(&rp->r_priv.s_ipc_to, &boot_image_priv->ipc_to,
+ sizeof(rp->r_priv.s_ipc_to)); /* targets */
+
+ /* Initialize kernel call mask bitmap from unordered set. */
+ fill_call_mask(boot_image_priv->k_calls, NR_SYS_CALLS,
+ rp->r_priv.s_k_call_mask, KERNEL_CALL, TRUE);
+
+ /* Set the privilege structure. */
+ if ((s = sys_privctl(ip->endpoint, SYS_PRIV_SET_SYS, &(rp->r_priv)))
+ != OK) {
+ panic("RS", "unable to set privilege structure", s);
+ }
}
/* Synch the privilege structure with the kernel. */
/*
* Set sys properties.
*/
- rp->r_sys_flags = boot_image_sys->flags; /* sys flags */
+ rpub->sys_flags = boot_image_sys->flags; /* sys flags */
/*
* Set dev properties.
*/
- rp->r_dev_nr = boot_image_dev->dev_nr; /* major device number */
- rp->r_dev_style = boot_image_dev->dev_style; /* device style */
- rp->r_period = boot_image_dev->period; /* heartbeat period */
+ rpub->dev_nr = boot_image_dev->dev_nr; /* major device number */
+ rpub->dev_style = boot_image_dev->dev_style; /* device style */
+ rpub->period = boot_image_dev->period; /* heartbeat period */
/* Get process name. */
- strcpy(rp->r_proc_name, ip->proc_name);
+ strcpy(rpub->proc_name, ip->proc_name);
/* Get command settings. */
rp->r_cmd[0]= '\0';
rp->r_argc = 1;
rp->r_script[0]= '\0';
+ /* Initialize vm call mask bitmap from unordered set. */
+ fill_call_mask(boot_image_priv->vm_calls, NR_VM_CALLS,
+ rpub->vm_call_mask, VM_RQ_BASE, TRUE);
+
/* Get some settings from the boot image table. */
rp->r_nice = ip->priority;
- rp->r_proc_nr_e = ip->endpoint;
+ rpub->endpoint = ip->endpoint;
/* Set some defaults. */
rp->r_uid = 0; /* root */
/* Mark as in use. */
rp->r_flags = RS_IN_USE;
- rproc_ptr[_ENDPOINT_P(rp->r_proc_nr_e)]= rp;
+ rproc_ptr[_ENDPOINT_P(rpub->endpoint)]= rp;
+ rpub->in_use = TRUE;
}
/* - Step 2: allow every system service in the boot image to run.
*/
+ nr_uncaught_init_srvs = 0;
for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) {
boot_image_priv = &boot_image_priv_table[i];
/* System services only. */
- if(!isbootsrvprocn(_ENDPOINT_P(boot_image_priv->endpoint))) {
+ if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) {
continue;
}
- /* Lookup the corresponding entry in the boot image table. */
- boot_image_info_lookup(boot_image_priv->endpoint, image,
- &ip, NULL, NULL, NULL);
+ /* Ignore RS. */
+ if(boot_image_priv->endpoint == RS_PROC_NR) {
+ continue;
+ }
+
+ /* Lookup the corresponding slot in the system process table. */
+ rp = &rproc[boot_image_priv - boot_image_priv_table];
+ rpub = rp->r_pub;
/* Allow the service to run. */
- if ((s = sys_privctl(ip->endpoint, SYS_PRIV_ALLOW, NULL)) != OK) {
+ if ((s = sys_privctl(rpub->endpoint, SYS_PRIV_ALLOW, NULL)) != OK) {
panic("RS", "unable to initialize privileges", s);
}
+
+ /* Initialize service. We assume every service will always get
+ * back to us here at boot time.
+ */
+ if(boot_image_priv->flags & SYS_PROC) {
+ if ((s = init_service(rp, SEF_INIT_FRESH)) != OK) {
+ panic("RS", "unable to initialize service", s);
+ }
+ if(rpub->sys_flags & SF_SYNCH_BOOT) {
+ /* Catch init ready message now to synchronize. */
+ catch_boot_init_ready(rpub->endpoint);
+ }
+ else {
+ /* Catch init ready message later. */
+ nr_uncaught_init_srvs++;
+ }
+ }
+ }
+
+ /* - Step 3: let every system service complete initialization by
+ * catching all the init ready messages left.
+ */
+ while(nr_uncaught_init_srvs) {
+ catch_boot_init_ready(ANY);
+ nr_uncaught_init_srvs--;
}
- /* - Step 3: all the system services in the boot image are now running.
+ /* - Step 4: all the system services in the boot image are now running.
* Complete the initialization of the system process table in collaboration
* with other system processes.
*/
boot_image_priv = &boot_image_priv_table[i];
/* System services only. */
- if(!isbootsrvprocn(_ENDPOINT_P(boot_image_priv->endpoint))) {
+ if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) {
continue;
}
/* Lookup the corresponding slot in the system process table. */
rp = &rproc[boot_image_priv - boot_image_priv_table];
+ rpub = rp->r_pub;
/* Get pid from PM process table. */
rp->r_pid = NO_PID;
for (j = 0; j < NR_PROCS; j++) {
- if (mproc[j].mp_endpoint == rp->r_proc_nr_e) {
+ if (mproc[j].mp_endpoint == rpub->endpoint) {
rp->r_pid = mproc[j].mp_pid;
break;
}
if(j == NR_PROCS) {
panic("RS", "unable to get pid", NO_NUM);
}
-
- /* Publish the new system service.
- * XXX FIXME. Possible race condition. We should publish labels before
- * allowing other processes to run.
- */
- s = publish_service(rp);
- if (s != OK) {
- panic("RS", "unable to publish boot system service", s);
- }
}
/*
*/
unmap_ok = 1;
_minix_unmapzero();
+
+ return(OK);
+}
+
+/*===========================================================================*
+ * exec_image_copy *
+ *===========================================================================*/
+PRIVATE void exec_image_copy(boot_proc_idx, ip, rp)
+int boot_proc_idx;
+struct boot_image *ip;
+struct rproc *rp;
+{
+/* Copy the executable image of the given boot process. */
+ int s;
+ struct exec header;
+ static char *boot_image_ptr = NULL;
+
+ if(boot_image_ptr == NULL) {
+ boot_image_ptr = boot_image_buffer;
+ }
+ s = NO_NUM;
+
+ /* Get a.out header. */
+ if(boot_image_buffer+boot_image_buffer_size - boot_image_ptr < sizeof(header)
+ || (s = sys_getaoutheader(&header, boot_proc_idx)) != OK) {
+ panic("RS", "unable to get copy of a.out header", s);
+ }
+ memcpy(boot_image_ptr, &header, header.a_hdrlen);
+ boot_image_ptr += header.a_hdrlen;
+
+ /* Get text segment. */
+ if(boot_image_buffer+boot_image_buffer_size - boot_image_ptr < header.a_text
+ || (s = rs_startup_segcopy(ip->endpoint, T, D, (vir_bytes) boot_image_ptr,
+ header.a_text)) != OK) {
+ panic("RS", "unable to get copy of text segment", s);
+ }
+ boot_image_ptr += header.a_text;
+
+ /* Get data segment. */
+ if(boot_image_buffer+boot_image_buffer_size - boot_image_ptr < header.a_data
+ || (s = rs_startup_segcopy(ip->endpoint, D, D, (vir_bytes) boot_image_ptr,
+ header.a_data)) != OK) {
+ panic("RS", "unable to get copy of data segment", s);
+ }
+ boot_image_ptr += header.a_data;
+
+ /* Set the executable image for the given boot process. */
+ rp->r_exec_len = header.a_hdrlen + header.a_text + header.a_data;
+ rp->r_exec = boot_image_ptr - rp->r_exec_len;
+}
+
+/*===========================================================================*
+ * boot_image_info_lookup *
+ *===========================================================================*/
+PRIVATE void boot_image_info_lookup(endpoint, image, ip, pp, sp, dp)
+endpoint_t endpoint;
+struct boot_image *image;
+struct boot_image **ip;
+struct boot_image_priv **pp;
+struct boot_image_sys **sp;
+struct boot_image_dev **dp;
+{
+/* Lookup entries in boot image tables. */
+ int i;
+
+ /* When requested, locate the corresponding entry in the boot image table
+ * or panic if not found.
+ */
+ if(ip) {
+ for (i=0; i < NR_BOOT_PROCS; i++) {
+ if(image[i].endpoint == endpoint) {
+ *ip = &image[i];
+ break;
+ }
+ }
+ if(i == NR_BOOT_PROCS) {
+ panic("RS", "boot image table lookup failed", NO_NUM);
+ }
+ }
+
+ /* When requested, locate the corresponding entry in the boot image priv table
+ * or panic if not found.
+ */
+ if(pp) {
+ for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) {
+ if(boot_image_priv_table[i].endpoint == endpoint) {
+ *pp = &boot_image_priv_table[i];
+ break;
+ }
+ }
+ if(i == NULL_BOOT_NR) {
+ panic("RS", "boot image priv table lookup failed", NO_NUM);
+ }
+ }
+
+ /* When requested, locate the corresponding entry in the boot image sys table
+ * or resort to the default entry if not found.
+ */
+ if(sp) {
+ for (i=0; boot_image_sys_table[i].endpoint != DEFAULT_BOOT_NR; i++) {
+ if(boot_image_sys_table[i].endpoint == endpoint) {
+ *sp = &boot_image_sys_table[i];
+ break;
+ }
+ }
+ if(boot_image_sys_table[i].endpoint == DEFAULT_BOOT_NR) {
+ *sp = &boot_image_sys_table[i]; /* accept the default entry */
+ }
+ }
+
+ /* When requested, locate the corresponding entry in the boot image dev table
+ * or resort to the default entry if not found.
+ */
+ if(dp) {
+ for (i=0; boot_image_dev_table[i].endpoint != DEFAULT_BOOT_NR; i++) {
+ if(boot_image_dev_table[i].endpoint == endpoint) {
+ *dp = &boot_image_dev_table[i];
+ break;
+ }
+ }
+ if(boot_image_dev_table[i].endpoint == DEFAULT_BOOT_NR) {
+ *dp = &boot_image_dev_table[i]; /* accept the default entry */
+ }
+ }
+}
+
+/*===========================================================================*
+ * catch_boot_init_ready *
+ *===========================================================================*/
+PRIVATE void catch_boot_init_ready(endpoint)
+endpoint_t endpoint;
+{
+/* Block and catch an init ready message from the given source. */
+ int r;
+ message m;
+ struct rproc *rp;
+ int result;
+
+ /* Receive init ready message. */
+ if ((r = receive(endpoint, &m)) != OK) {
+ panic("RS", "unable to receive init reply", r);
+ }
+ if(m.m_type != RS_INIT) {
+ panic("RS", "unexpected reply from service", m.m_source);
+ }
+ result = m.RS_INIT_RESULT;
+ rp = rproc_ptr[_ENDPOINT_P(m.m_source)];
+
+ /* Check result. */
+ if(result != OK) {
+ panic("RS", "unable to complete init for service", m.m_source);
+ }
+
+ /* Mark the slot as no longer initializing. */
+ rp->r_flags &= ~RS_INITIALIZING;
+ rp->r_check_tm = 0;
+ getuptime(&rp->r_alive_tm);
}
/*===========================================================================*
{
int control_allowed = 0;
register struct rproc *rp;
+ register struct rprocpub *rpub;
int c;
char *progname;
/* Find name of binary for given label. */
for (rp = BEG_RPROC_ADDR; rp < END_RPROC_ADDR; rp++) {
- if (strcmp(rp->r_label, label) == 0) {
+ rpub = rp->r_pub;
+ if (strcmp(rpub->label, label) == 0) {
break;
}
}
/* Check if label is listed in caller's isolation policy. */
for (rp = BEG_RPROC_ADDR; rp < END_RPROC_ADDR; rp++) {
- if (rp->r_proc_nr_e == endpoint) {
+ rpub = rp->r_pub;
+ if (rpub->endpoint == endpoint) {
break;
}
}
/* A request was made to start a new system service.
*/
register struct rproc *rp; /* system process table */
+ register struct rprocpub *rpub; /* public entry */
int slot_nr; /* local table entry */
int arg_count; /* number of arguments */
char *cmd_ptr; /* parse command string */
int r;
endpoint_t ep;
struct rproc *tmp_rp;
+ struct rprocpub *tmp_rpub;
struct rs_start rs_start;
/* This call requires special privileges. */
printf("RS: do_up: system process table full\n");
return ENOMEM;
}
+ rpub = rp->r_pub;
/* Ok, there is space. Get the request structure. */
s= sys_datacopy(m_ptr->m_source, (vir_bytes) m_ptr->RS_CMD_ADDR,
else
cmd_ptr= rp->r_argv[0];
len= strlen(cmd_ptr);
- if (len > P_NAME_LEN-1)
- len= P_NAME_LEN-1; /* truncate name */
- memcpy(rp->r_proc_name, cmd_ptr, len);
- rp->r_proc_name[len]= '\0';
+ if (len > RS_MAX_LABEL_LEN-1)
+ len= RS_MAX_LABEL_LEN-1; /* truncate name */
+ memcpy(rpub->proc_name, cmd_ptr, len);
+ rpub->proc_name[len]= '\0';
if(rs_verbose)
printf("RS: do_up: using proc_name (from binary %s) '%s'\n",
- rp->r_argv[0], rp->r_proc_name);
+ rp->r_argv[0], rpub->proc_name);
if(rs_start.rss_label.l_len > 0) {
/* RS_UP caller has supplied a custom label for this service. */
int s = copy_label(m_ptr->m_source, &rs_start.rss_label,
- rp->r_label, sizeof(rp->r_label));
+ rpub->label, sizeof(rpub->label));
if(s != OK)
return s;
if(rs_verbose)
- printf("RS: do_up: using label (custom) '%s'\n", rp->r_label);
+ printf("RS: do_up: using label (custom) '%s'\n", rpub->label);
} else {
/* Default label for the service. */
- label = rp->r_proc_name;
+ label = rpub->proc_name;
len= strlen(label);
- if (len > MAX_LABEL_LEN-1)
- len= MAX_LABEL_LEN-1; /* truncate name */
- memcpy(rp->r_label, label, len);
- rp->r_label[len]= '\0';
+ memcpy(rpub->label, label, len);
+ rpub->label[len]= '\0';
if(rs_verbose)
printf("RS: do_up: using label (from proc_name) '%s'\n",
- rp->r_label);
+ rpub->label);
}
if(rs_start.rss_nr_control > 0) {
int i, s;
- if (rs_start.rss_nr_control > RSS_NR_CONTROL)
+ if (rs_start.rss_nr_control > RS_NR_CONTROL)
{
printf("RS: do_up: too many control labels\n");
return EINVAL;
continue;
if (tmp_rp == rp)
continue; /* Our slot */
- if (strcmp(tmp_rp->r_label, rp->r_label) == 0)
+ tmp_rpub = tmp_rp->r_pub;
+ if (strcmp(tmp_rpub->label, rpub->label) == 0)
{
printf("RS: found duplicate label '%s': slot %d\n",
- rp->r_label, slot_nr);
+ rpub->label, slot_nr);
return EBUSY;
}
}
rp->r_uid= rs_start.rss_uid;
rp->r_nice= rs_start.rss_nice;
- if (rs_start.rss_flags & RF_IPC_VALID)
+ if (rs_start.rss_flags & RSS_IPC_VALID)
{
if (rs_start.rss_ipclen+1 > sizeof(rp->r_ipc_list))
{
- printf("rs: ipc list too long for '%s'\n", rp->r_label);
+ printf("rs: ipc list too long for '%s'\n", rpub->label);
return EINVAL;
}
s=sys_datacopy(m_ptr->m_source, (vir_bytes) rs_start.rss_ipc,
else
rp->r_ipc_list[0]= '\0';
- rp->r_sys_flags = DSRV_SF;
+ rpub->sys_flags = DSRV_SF;
rp->r_exec= NULL;
- if (rs_start.rss_flags & RF_COPY) {
+ if (rs_start.rss_flags & RSS_COPY) {
int exst_cpy;
struct rproc *rp2;
+ struct rprocpub *rpub2;
exst_cpy = 0;
- if(rs_start.rss_flags & RF_REUSE) {
+ if(rs_start.rss_flags & RSS_REUSE) {
int i;
for(i = 0; i < NR_SYS_PROCS; i++) {
rp2 = &rproc[i];
- if(strcmp(rp->r_proc_name, rp2->r_proc_name) == 0 &&
- (rp2->r_sys_flags & SF_USE_COPY)) {
+ rpub2 = rproc[i].r_pub;
+ if(strcmp(rpub->proc_name, rpub2->proc_name) == 0 &&
+ (rpub2->sys_flags & SF_USE_COPY)) {
/* We have found the same binary that's
* already been copied */
exst_cpy = 1;
if (s != OK)
return s;
- rp->r_sys_flags |= SF_USE_COPY;
+ rpub->sys_flags |= SF_USE_COPY;
}
/* All dynamically created services get the same privilege flags, and
rp->r_priv.s_io_tab[i].ior_limit);
}
- if (rs_start.rss_nr_pci_id > RSS_NR_PCI_ID)
+ if (rs_start.rss_nr_pci_id > RS_NR_PCI_DEVICE)
{
printf("RS: do_up: too many PCI device IDs\n");
return EINVAL;
}
- rp->r_nr_pci_id= rs_start.rss_nr_pci_id;
- for (i= 0; i<rp->r_nr_pci_id; i++)
+ rpub->pci_acl.rsp_nr_device = rs_start.rss_nr_pci_id;
+ for (i= 0; i<rpub->pci_acl.rsp_nr_device; i++)
{
- rp->r_pci_id[i].vid= rs_start.rss_pci_id[i].vid;
- rp->r_pci_id[i].did= rs_start.rss_pci_id[i].did;
+ rpub->pci_acl.rsp_device[i].vid= rs_start.rss_pci_id[i].vid;
+ rpub->pci_acl.rsp_device[i].did= rs_start.rss_pci_id[i].did;
if(rs_verbose)
printf("RS: do_up: PCI %04x/%04x\n",
- rp->r_pci_id[i].vid, rp->r_pci_id[i].did);
+ rpub->pci_acl.rsp_device[i].vid,
+ rpub->pci_acl.rsp_device[i].did);
}
- if (rs_start.rss_nr_pci_class > RSS_NR_PCI_CLASS)
+ if (rs_start.rss_nr_pci_class > RS_NR_PCI_CLASS)
{
printf("RS: do_up: too many PCI class IDs\n");
return EINVAL;
}
- rp->r_nr_pci_class= rs_start.rss_nr_pci_class;
- for (i= 0; i<rp->r_nr_pci_class; i++)
+ rpub->pci_acl.rsp_nr_class= rs_start.rss_nr_pci_class;
+ for (i= 0; i<rpub->pci_acl.rsp_nr_class; i++)
{
- rp->r_pci_class[i].class= rs_start.rss_pci_class[i].class;
- rp->r_pci_class[i].mask= rs_start.rss_pci_class[i].mask;
+ rpub->pci_acl.rsp_class[i].class= rs_start.rss_pci_class[i].class;
+ rpub->pci_acl.rsp_class[i].mask= rs_start.rss_pci_class[i].mask;
if(rs_verbose)
printf("RS: do_up: PCI class %06x mask %06x\n",
- rp->r_pci_class[i].class, rp->r_pci_class[i].mask);
+ rpub->pci_acl.rsp_class[i].class,
+ rpub->pci_acl.rsp_class[i].mask);
}
/* Copy 'system' call number bits */
if (sizeof(rs_start.rss_system[0]) == sizeof(rp->r_call_mask[0]) &&
sizeof(rs_start.rss_system) == sizeof(rp->r_call_mask))
{
- for (i= 0; i<RSS_NR_SYSTEM; i++)
+ for (i= 0; i<RS_SYS_CALL_MASK_SIZE; i++)
rp->r_call_mask[i]= rs_start.rss_system[i];
}
else
}
/* Initialize some fields. */
- rp->r_period = rs_start.rss_period;
- rp->r_dev_nr = rs_start.rss_major;
- rp->r_dev_style = STYLE_DEV;
+ rpub->period = rs_start.rss_period;
+ rpub->dev_nr = rs_start.rss_major;
+ rpub->dev_style = STYLE_DEV;
rp->r_restarts = -1; /* will be incremented */
rp->r_set_resources= 1; /* set resources */
- if (sizeof(rp->r_vm) == sizeof(rs_start.rss_vm) &&
- sizeof(rp->r_vm[0]) == sizeof(rs_start.rss_vm[0]))
+ if (sizeof(rpub->vm_call_mask) == sizeof(rs_start.rss_vm) &&
+ sizeof(rpub->vm_call_mask[0]) == sizeof(rs_start.rss_vm[0]))
{
- memcpy(rp->r_vm, rs_start.rss_vm, sizeof(rp->r_vm));
+ int basic_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C };
+ memcpy(rpub->vm_call_mask, rs_start.rss_vm,
+ sizeof(rpub->vm_call_mask));
+ fill_call_mask(basic_vmc, NR_VM_CALLS,
+ rpub->vm_call_mask, VM_RQ_BASE, FALSE);
}
else
{
- printf("RS: do_up: internal inconsistency: bad size of r_vm\n");
- memset(rp->r_vm, '\0', sizeof(rp->r_vm));
+ printf("RS: internal inconsistency: bad size of vm_call_mask\n");
+ memset(rpub->vm_call_mask, '\0', sizeof(rpub->vm_call_mask));
}
/* All information was gathered. Now try to start the system service. */
PUBLIC int do_down(message *m_ptr)
{
register struct rproc *rp;
+ register struct rprocpub *rpub;
size_t len;
int s, proc;
- char label[MAX_LABEL_LEN];
+ char label[RS_MAX_LABEL_LEN];
/* This call requires special privileges. */
if (!caller_is_root(m_ptr->m_source)) return(EPERM);
label[len]= '\0';
for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
- if (rp->r_flags & RS_IN_USE && strcmp(rp->r_label, label) == 0) {
+ rpub = rp->r_pub;
+ if (rp->r_flags & RS_IN_USE && strcmp(rpub->label, label) == 0) {
+ /* Core system services should never go down. */
+ if (rpub->sys_flags & SF_CORE_SRV) return(EPERM);
+
if(rs_verbose)
printf("RS: stopping '%s' (%d)\n", label, rp->r_pid);
stop_service(rp,RS_EXITING);
PUBLIC int do_restart(message *m_ptr)
{
register struct rproc *rp;
+ register struct rprocpub *rpub;
size_t len;
int s, proc, r;
- char label[MAX_LABEL_LEN];
+ char label[RS_MAX_LABEL_LEN];
endpoint_t ep;
len= m_ptr->RS_CMD_LEN;
}
for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
- if ((rp->r_flags & RS_IN_USE) && strcmp(rp->r_label, label) == 0) {
+ rpub = rp->r_pub;
+ if ((rp->r_flags & RS_IN_USE) && strcmp(rpub->label, label) == 0) {
if(rs_verbose) printf("RS: restarting '%s' (%d)\n", label, rp->r_pid);
if (rp->r_pid >= 0)
{
PUBLIC int do_refresh(message *m_ptr)
{
register struct rproc *rp;
+ register struct rprocpub *rpub;
size_t len;
int s;
- char label[MAX_LABEL_LEN];
+ char label[RS_MAX_LABEL_LEN];
len= m_ptr->RS_CMD_LEN;
if (len >= sizeof(label))
}
for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
- if (rp->r_flags & RS_IN_USE && strcmp(rp->r_label, label) == 0) {
+ rpub = rp->r_pub;
+ if (rp->r_flags & RS_IN_USE && strcmp(rpub->label, label) == 0) {
+ /* Only system processes not including RS can refresh. */
+ if(!(rp->r_priv.s_flags & SYS_PROC) || rpub->endpoint == RS_PROC_NR) {
+ return EPERM;
+ }
+
if(rs_verbose) {
- printf("RS: refreshing %s (%d)\n", rp->r_label, rp->r_pid);
+ printf("RS: refreshing %s (%d)\n", rpub->label, rp->r_pid);
}
stop_service(rp,RS_REFRESHING);
return(OK);
return(OK);
}
+
+/*===========================================================================*
+ * do_init_ready *
+ *===========================================================================*/
+PUBLIC int do_init_ready(message *m_ptr)
+{
+ int who_p;
+ struct rproc *rp;
+ struct rprocpub *rpub;
+ int result;
+
+ who_p = _ENDPOINT_P(m_ptr->m_source);
+ rp = rproc_ptr[who_p];
+ rpub = rp->r_pub;
+ result = m_ptr->RS_INIT_RESULT;
+
+ /* Make sure the originating service was requested to initialize. */
+ if(! (rp->r_flags & RS_INITIALIZING) ) {
+ if(rs_verbose) {
+ printf("RS: do_init_ready: got unexpected init ready msg from %d\n",
+ m_ptr->m_source);
+ }
+ return(EINVAL);
+ }
+
+ /* Mark the slot as no longer initializing. */
+ rp->r_flags &= ~RS_INITIALIZING;
+ rp->r_check_tm = 0;
+ getuptime(&rp->r_alive_tm);
+
+ /* Check if something went wrong and the service failed to init.
+ * In that case, kill it and make sure it won't be restarted.
+ */
+ if(result != OK) {
+ if(rs_verbose)
+ printf("RS: initialization failed for service %d: %d\n",
+ rpub->endpoint, result);
+ rp->r_flags |= RS_EXITING;
+ kill(rp->r_pid, SIGKILL);
+ }
+ else {
+ if(rs_verbose)
+ printf("RS: initialization succeeded for service %d\n",
+ rpub->endpoint);
+ }
+
+ return(EDONTREPLY);
+}
+
/*===========================================================================*
* do_update *
*===========================================================================*/
PUBLIC int do_update(message *m_ptr)
{
register struct rproc *rp;
+ register struct rprocpub *rpub;
size_t len;
int s;
- char label[MAX_LABEL_LEN];
+ char label[RS_MAX_LABEL_LEN];
int lu_state;
int prepare_maxtime;
if (s != OK) return(s);
label[len]= '\0';
+ /* This call requires special privileges. */
+ if (! (caller_can_control(m_ptr->m_source, label) ||
+ caller_is_root(m_ptr->m_source))) {
+ return(EPERM);
+ }
+
/* Retrieve live update state. */
lu_state = m_ptr->RS_LU_STATE;
if(lu_state == SEF_LU_STATE_NULL) {
/* Try to start the update process. */
for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
- if (rp->r_flags & RS_IN_USE && strcmp(rp->r_label, label) == 0) {
+ rpub = rp->r_pub;
+ if (rp->r_flags & RS_IN_USE && strcmp(rpub->label, label) == 0) {
+ /* Only system processes not including RS can update. */
+ if(!(rp->r_priv.s_flags & SYS_PROC) || rpub->endpoint == RS_PROC_NR) {
+ return EPERM;
+ }
+
if(rs_verbose) {
- printf("RS: updating %s (%d)\n", rp->r_label, rp->r_pid);
+ printf("RS: updating %s (%d)\n", rpub->label, rp->r_pid);
}
-
+
rp->r_flags |= RS_UPDATING;
rupdate.flags |= RS_UPDATING;
getuptime(&rupdate.prepare_tm);
rupdate.prepare_maxtime = prepare_maxtime;
rupdate.rp = rp;
-
+
m_ptr->m_type = RS_LU_PREPARE;
- asynsend(rp->r_proc_nr_e, m_ptr); /* request to prepare for update */
-
+ asynsend(rpub->endpoint, m_ptr); /* request to update */
+
return(OK);
}
}
rp = rproc_ptr[who_p];
result = m_ptr->RS_LU_RESULT;
- /* Make sure the originating process was requested to prepare for update. */
+ /* Make sure the originating service was requested to prepare for update. */
if(! (rp->r_flags & RS_UPDATING) ) {
if(rs_verbose) {
printf("RS: do_upd_ready: got unexpected update ready msg from %d\n",
return(EINVAL);
}
- /* Check if something went wrong and the process failed to prepare
+ /* Check if something went wrong and the service failed to prepare
* for the update. In that case, end the update process.
*/
if(result != OK) {
switch(result) {
case EACCES:
printf("RS: update failed: %s\n",
- "process does not support live update");
+ "service does not support live update");
break;
case EINVAL:
printf("RS: update failed: %s\n",
- "process does not support the required state");
+ "service does not support the required state");
break;
case EBUSY:
printf("RS: update failed: %s\n",
- "process is not able to prepare for the update now");
+ "service is not able to prepare for the update now");
break;
case EGENERIC:
break;
}
- return ENOTREADY;
+ return(OK);
}
/* Kill the process now and mark it for refresh, the new version will
rp->r_flags |= RS_REFRESHING;
kill(rp->r_pid, SIGKILL);
- return(OK);
+ return(EDONTREPLY);
}
/*===========================================================================*
clock_t now = m_ptr->NOTIFY_TIMESTAMP;
short has_update_timed_out;
message m;
+ struct rprocpub *rpub;
+
+ rpub = rupdate.rp->r_pub;
/* See if a timeout has occurred. */
has_update_timed_out = (now - rupdate.prepare_tm > rupdate.prepare_maxtime);
/* Prepare cancel request. */
m.m_type = RS_LU_PREPARE;
m.RS_LU_STATE = SEF_LU_STATE_NULL;
- asynsend(rupdate.rp->r_proc_nr_e, &m);
+ asynsend(rpub->endpoint, &m);
}
}
/* End the update process and mark the affected service as no longer under
* update. Eventual late ready to update message (if any) will simply be
* ignored and the service can continue executing.
- * Also, if the service has a period, update the alive and check timestamps
- * of the service to force a status request in the next period.
+ * We reset the check timestamp, so that if the service has a period a status
+ * request will be forced in the next period.
*/
rupdate.flags &= ~RS_UPDATING;
rupdate.rp->r_flags &= ~RS_UPDATING;
- if(rupdate.rp->r_period > 0 ) {
- rupdate.rp->r_alive_tm = now;
- rupdate.rp->r_check_tm = now - rupdate.rp->r_period - 1;
- }
+ rupdate.rp->r_check_tm = 0;
}
/*===========================================================================*
PUBLIC void do_exit(message *m_ptr)
{
register struct rproc *rp;
+ register struct rprocpub *rpub;
pid_t exit_pid;
int exit_status, r, slot_nr;
endpoint_t ep;
* This should always succeed.
*/
for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
+ rpub = rp->r_pub;
if ((rp->r_flags & RS_IN_USE) && rp->r_pid == exit_pid) {
int proc;
- proc = _ENDPOINT_P(rp->r_proc_nr_e);
+ proc = _ENDPOINT_P(rpub->endpoint);
rproc_ptr[proc] = NULL; /* invalidate */
rp->r_pid= -1;
/* If PCI properties are set, inform the PCI driver. */
- if(rp->r_nr_pci_id || rp->r_nr_pci_class) {
- pci_del_acl(rp->r_proc_nr_e);
+ if(rpub->pci_acl.rsp_nr_device || rpub->pci_acl.rsp_nr_class) {
+ pci_del_acl(rpub->endpoint);
}
if ((rp->r_flags & RS_EXITING) || shutting_down) {
short is_updating = rp->r_flags & RS_UPDATING;
/* Refresh */
- rp->r_restarts = -1; /* reset counter */
if (rp->r_script[0] != '\0')
run_script(rp);
else {
rp->r_cmd, rp->r_backoff);
rp->r_backoff = 1 << MIN(rp->r_restarts,(BACKOFF_BITS-2));
rp->r_backoff = MIN(rp->r_backoff,MAX_BACKOFF);
- if ((rp->r_sys_flags & SF_USE_COPY) && rp->r_backoff > 1)
+ if ((rpub->sys_flags & SF_USE_COPY) && rp->r_backoff > 1)
rp->r_backoff= 1;
}
else {
message *m_ptr;
{
register struct rproc *rp;
+ register struct rprocpub *rpub;
clock_t now = m_ptr->NOTIFY_TIMESTAMP;
int s;
endpoint_t ep;
+ long period;
/* If an update is in progress, check its status. */
if(rupdate.flags & RS_UPDATING) {
* updating.
*/
for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
+ rpub = rp->r_pub;
if ((rp->r_flags & RS_IN_USE) && !(rp->r_flags & RS_UPDATING)) {
+ /* Compute period. */
+ period = rpub->period;
+ if(rp->r_flags & RS_INITIALIZING) {
+ period = RS_INIT_T;
+ }
+
/* If the service is to be revived (because it repeatedly exited,
* and was not directly restarted), the binary backoff field is
* greater than zero.
/* There seems to be no special conditions. If the service has a
* period assigned check its status.
*/
- else if (rp->r_period > 0) {
+ else if (period > 0) {
/* Check if an answer to a status request is still pending. If
* the service didn't respond within time, kill it to simulate
* be restarted automatically.
*/
if (rp->r_alive_tm < rp->r_check_tm) {
- if (now - rp->r_alive_tm > 2*rp->r_period &&
+ if (now - rp->r_alive_tm > 2*period &&
rp->r_pid > 0 && !(rp->r_flags & RS_NOPINGREPLY)) {
if(rs_verbose)
printf("RS: service %d reported late\n",
- rp->r_proc_nr_e);
+ rpub->endpoint);
rp->r_flags |= RS_NOPINGREPLY;
+ if(rp->r_flags & RS_INITIALIZING) {
+ rp->r_flags |= RS_EXITING; /* don't restart */
+ }
kill(rp->r_pid, SIGKILL); /* simulate crash */
}
}
/* No answer pending. Check if a period expired since the last
* check and, if so request the system service's status.
*/
- else if (now - rp->r_check_tm > rp->r_period) {
+ else if (now - rp->r_check_tm > rpub->period) {
#if 0
if(rs_verbose)
- printf("RS: status request sent to %d\n", rp->r_proc_nr_e);
+ printf("RS: status request sent to %d\n", rpub->endpoint);
#endif
- notify(rp->r_proc_nr_e); /* request status */
+ notify(rpub->endpoint); /* request status */
rp->r_check_tm = now; /* mark time */
}
}
int child_proc_nr_e, child_proc_nr_n; /* child process slot */
pid_t child_pid; /* child's process id */
char *file_only;
- int s, use_copy, slot_nr;
+ int s, use_copy, slot_nr, init_type;
bitchunk_t *vm_mask;
message m;
char * null_env = NULL;
+ struct rprocpub *rpub;
- use_copy= (rp->r_sys_flags & SF_USE_COPY);
+ rpub = rp->r_pub;
+ use_copy= (rpub->sys_flags & SF_USE_COPY);
/* See if we are not using a copy but we do need one to start the service. */
- if(!use_copy && (rp->r_sys_flags & SF_NEED_COPY)) {
+ if(!use_copy && (rpub->sys_flags & SF_NEED_COPY)) {
printf("RS: unable to start service %s without an in-memory copy\n",
- rp->r_label);
+ rpub->label);
+ free_slot(rp);
return(EPERM);
}
child_proc_nr_n = _ENDPOINT_P(child_proc_nr_e);
rp->r_flags = RS_IN_USE | flags; /* mark slot in use */
rp->r_restarts += 1; /* raise nr of restarts */
- rp->r_proc_nr_e = child_proc_nr_e; /* set child details */
+ rpub->endpoint = child_proc_nr_e; /* set child details */
rp->r_pid = child_pid;
rp->r_check_tm = 0; /* not checked yet */
getuptime(&rp->r_alive_tm); /* currently alive */
rp->r_stop_tm = 0; /* not exiting yet */
rp->r_backoff = 0; /* not to be restarted */
rproc_ptr[child_proc_nr_n] = rp; /* mapping for fast access */
+ rpub->in_use = TRUE; /* public entry is now in use */
/* If any of the calls below fail, the RS_EXITING flag is set. This implies
* that the process will be removed from RS's process table once it has
init_privs(rp, &rp->r_priv);
/* Tell VM about allowed calls. */
- vm_mask = &rp->r_vm[0];
+ vm_mask = &rpub->vm_call_mask[0];
if ((s = vm_set_priv(child_proc_nr_e, vm_mask)) < 0) {
report("RS", "vm_set_priv call failed", s);
kill(child_pid, SIGKILL);
}
/* If PCI properties are set, inform the PCI driver about the new service. */
- if(rp->r_nr_pci_id || rp->r_nr_pci_class) {
+ if(rpub->pci_acl.rsp_nr_device || rpub->pci_acl.rsp_nr_class) {
init_pci(rp, child_proc_nr_e);
}
}
/* Allow the service to run.
- * XXX FIXME: we should let the service run only after publishing information
+ * XXX: We should let the service run/init only after publishing information
* about the new system service, but this is not currently possible due to
* the blocking nature of mapdriver() that expects the service to be running.
* The current solution is not race-free. This hack can go once service
return(s); /* return error */
}
+ /* Initialize service. */
+ init_type = rp->r_restarts > 0 ? SEF_INIT_RESTART : SEF_INIT_FRESH;
+ if((s = init_service(rp, init_type)) != OK) {
+ panic("RS", "unable to initialize service", s);
+ }
+
/* The purpose of non-blocking forks is to avoid involving VFS in the forking
* process, because VFS may be blocked on a sendrec() to a MFS that is
* waiting for a endpoint update for a dead driver. We have just published
setuid(0);
/* Map the new service. */
- if (rp->r_dev_nr > 0) { /* set driver map */
- if ((s=mapdriver(rp->r_label,
- rp->r_dev_nr, rp->r_dev_style, !!use_copy /* force */)) < 0) {
+ if (rpub->dev_nr > 0) { /* set driver map */
+ if ((s=mapdriver(rpub->label,
+ rpub->dev_nr, rpub->dev_style, !!use_copy /* force */)) < 0) {
report("RS", "couldn't map driver (continuing)", errno);
}
}
if(rs_verbose)
printf("RS: started '%s', major %d, pid %d, endpoint %d, proc %d\n",
- rp->r_cmd, rp->r_dev_nr, child_pid,
+ rp->r_cmd, rpub->dev_nr, child_pid,
child_proc_nr_e, child_proc_nr_n);
/* The system service now has been successfully started. The only thing
src_addr = (vir_bytes) rproc;
len = sizeof(struct rproc) * NR_SYS_PROCS;
break;
+ case SI_PROCPUB_TAB:
+ src_addr = (vir_bytes) rprocpub;
+ len = sizeof(struct rprocpub) * NR_SYS_PROCS;
+ break;
default:
return(EINVAL);
}
PRIVATE int share_exec(rp_dst, rp_src)
struct rproc *rp_dst, *rp_src;
{
+ struct rprocpub *rpub_src;
+ struct rprocpub *rpub_dst;
+
+ rpub_src = rp_src->r_pub;
+ rpub_dst = rp_dst->r_pub;
+
if(rs_verbose) {
printf("RS: share_exec: sharing exec image from %s to %s\n",
- rp_src->r_label, rp_dst->r_label);
+ rpub_src->label, rpub_dst->label);
}
/* Share exec image from rp_src to rp_dst. */
struct rproc *rp;
{
int slot_nr, has_shared_exec;
+ struct rprocpub *rpub;
struct rproc *other_rp;
+ rpub = rp->r_pub;
+
/* Free memory if necessary. */
- if(rp->r_sys_flags & SF_USE_COPY) {
+ if(rpub->sys_flags & SF_USE_COPY) {
/* Search for some other slot sharing the same exec image. */
has_shared_exec = FALSE;
for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
/* If nobody uses our copy of the exec image, we can get rid of it. */
if(!has_shared_exec) {
if(rs_verbose) {
- printf("RS: free_slot: free exec image from %s\n", rp->r_label);
+ printf("RS: free_slot: free exec image from %s\n",
+ rpub->label);
}
free(rp->r_exec);
rp->r_exec = NULL;
/* Mark slot as no longer in use.. */
rp->r_flags = 0;
- rproc_ptr[_ENDPOINT_P(rp->r_proc_nr_e)] = NULL;
+ rpub->in_use = FALSE;
+ rproc_ptr[_ENDPOINT_P(rpub->endpoint)] = NULL;
}
/*===========================================================================*
PRIVATE void run_script(rp)
struct rproc *rp;
{
- int r, proc_nr_e;
+ int r, endpoint;
pid_t pid;
char *reason;
char incarnation_str[20]; /* Enough for a counter? */
char *envp[1] = { NULL };
+ struct rprocpub *rpub;
+ rpub = rp->r_pub;
if (rp->r_flags & RS_REFRESHING)
reason= "restart";
else if (rp->r_flags & RS_NOPINGREPLY)
{
printf(
"RS: run_script: can't find reason for termination of '%s'\n",
- rp->r_label);
+ rpub->label);
return;
}
sprintf(incarnation_str, "%d", rp->r_restarts);
if(rs_verbose) {
printf("RS: calling script '%s'\n", rp->r_script);
- printf("RS: sevice name: '%s'\n", rp->r_label);
+ printf("RS: sevice name: '%s'\n", rpub->label);
printf("RS: reason: '%s'\n", reason);
printf("RS: incarnation: '%s'\n", incarnation_str);
}
printf("RS: run_script: fork failed: %s\n", strerror(errno));
break;
case 0:
- execle(rp->r_script, rp->r_script, rp->r_label, reason,
+ execle(rp->r_script, rp->r_script, rpub->label, reason,
incarnation_str, NULL, envp);
printf("RS: run_script: execl '%s' failed: %s\n",
rp->r_script, strerror(errno));
exit(1);
default:
/* Set the privilege structure for the child process. */
- proc_nr_e = getnprocnr(pid);
- if ((r = sys_privctl(proc_nr_e, SYS_PRIV_SET_USER, NULL))
+ endpoint = getnprocnr(pid);
+ if ((r = sys_privctl(endpoint, SYS_PRIV_SET_USER, NULL))
!= OK) {
printf("RS: run_script: can't set privileges: %d\n",r);
}
- /* Allow the process to run. */
- if ((r = sys_privctl(proc_nr_e, SYS_PRIV_ALLOW, NULL)) != OK) {
+ /* Allow the service to run. */
+ if ((r = sys_privctl(endpoint, SYS_PRIV_ALLOW, NULL)) != OK) {
printf("RS: run_script: process can't run: %d\n",r);
}
/* Do not wait for the child */
if (q == p)
continue;
len= q-p;
- if (len > MAX_LABEL_LEN)
+ if (len > RS_MAX_LABEL_LEN)
{
printf(
"rs:get_next_label: bad ipc list entry '.*s' for %s: too long\n",
/* Add IPC send permissions to a process based on that process's IPC
* list.
*/
- char label[MAX_LABEL_LEN+1], *p;
+ char label[RS_MAX_LABEL_LEN+1], *p;
struct rproc *tmp_rp;
- endpoint_t proc_nr_e;
+ struct rprocpub *tmp_rpub;
+ endpoint_t endpoint;
int r;
int slot_nr, priv_id;
struct priv priv;
+ struct rprocpub *rpub;
+ rpub = rp->r_pub;
p = rp->r_ipc_list;
- while ((p = get_next_label(p, label, rp->r_label)) != NULL) {
+ while ((p = get_next_label(p, label, rpub->label)) != NULL) {
if (strcmp(label, "SYSTEM") == 0)
- proc_nr_e= SYSTEM;
+ endpoint= SYSTEM;
else if (strcmp(label, "USER") == 0)
- proc_nr_e= INIT_PROC_NR; /* all user procs */
+ endpoint= INIT_PROC_NR; /* all user procs */
else if (strcmp(label, "PM") == 0)
- proc_nr_e= PM_PROC_NR;
+ endpoint= PM_PROC_NR;
else if (strcmp(label, "VFS") == 0)
- proc_nr_e= FS_PROC_NR;
+ endpoint= FS_PROC_NR;
else if (strcmp(label, "RS") == 0)
- proc_nr_e= RS_PROC_NR;
+ endpoint= RS_PROC_NR;
else if (strcmp(label, "LOG") == 0)
- proc_nr_e= LOG_PROC_NR;
+ endpoint= LOG_PROC_NR;
else if (strcmp(label, "TTY") == 0)
- proc_nr_e= TTY_PROC_NR;
+ endpoint= TTY_PROC_NR;
else if (strcmp(label, "DS") == 0)
- proc_nr_e= DS_PROC_NR;
+ endpoint= DS_PROC_NR;
else if (strcmp(label, "VM") == 0)
- proc_nr_e= VM_PROC_NR;
+ endpoint= VM_PROC_NR;
else
{
/* Try to find process */
tmp_rp = &rproc[slot_nr];
if (!(tmp_rp->r_flags & RS_IN_USE))
continue;
- if (strcmp(tmp_rp->r_label, label) == 0)
+ tmp_rpub = tmp_rp->r_pub;
+ if (strcmp(tmp_rpub->label, label) == 0)
break;
}
if (slot_nr >= NR_SYS_PROCS)
"add_forward_ipc: unable to find '%s'\n", label);
continue;
}
- proc_nr_e= tmp_rp->r_proc_nr_e;
+ endpoint= tmp_rpub->endpoint;
}
- if ((r = sys_getpriv(&priv, proc_nr_e)) < 0)
+ if ((r = sys_getpriv(&priv, endpoint)) < 0)
{
printf(
"add_forward_ipc: unable to get priv_id for '%s': %d\n",
* add these permissions now because the current process may not yet
* have existed at the time that the other process was initialized.
*/
- char label[MAX_LABEL_LEN+1], *p;
+ char label[RS_MAX_LABEL_LEN+1], *p;
struct rproc *rrp;
+ struct rprocpub *rrpub;
int priv_id, found;
for (rrp=BEG_RPROC_ADDR; rrp<END_RPROC_ADDR; rrp++) {
if (rrp->r_ipc_list[0]) {
found = 0;
+ rrpub = rrp->r_pub;
p = rrp->r_ipc_list;
- while ((p = get_next_label(p, label, rp->r_label)) !=
- NULL) {
- if (!strcmp(rp->r_label, label)) {
+ while ((p = get_next_label(p, label,
+ rrpub->label)) != NULL) {
+ if (!strcmp(rrpub->label, label)) {
found = 1;
break;
}
src_bits_per_word= 8*sizeof(rp->r_call_mask[0]);
dst_bits_per_word= 8*sizeof(privp->s_k_call_mask[0]);
- for (src_word= 0; src_word < RSS_NR_SYSTEM; src_word++)
+ for (src_word= 0; src_word < RS_SYS_CALL_MASK_SIZE; src_word++)
{
for (src_bit= 0; src_bit < src_bits_per_word; src_bit++)
{
#endif
dst_word= call_nr / dst_bits_per_word;
mask= (1UL << (call_nr % dst_bits_per_word));
- if (dst_word >= CALL_MASK_SIZE)
+ if (dst_word >= SYS_CALL_MASK_SIZE)
{
printf(
"RS: init_privs: call number %d doesn't fit\n",
size_t len;
int i, r;
struct rs_pci rs_pci;
+ struct rprocpub *rpub;
- if (strcmp(rp->r_label, "pci") == 0)
- {
- if(rs_verbose)
- printf("RS: init_pci: not when starting 'pci'\n");
- return;
- }
-
- len= strlen(rp->r_label);
- if (len+1 > sizeof(rs_pci.rsp_label))
- {
- if(rs_verbose)
- printf("RS: init_pci: label '%s' too long for rsp_label\n",
- rp->r_label);
- return;
- }
- strcpy(rs_pci.rsp_label, rp->r_label);
+ rpub = rp->r_pub;
+ rs_pci = rpub->pci_acl;
+ strcpy(rs_pci.rsp_label, rpub->label);
rs_pci.rsp_endpoint= endpoint;
- rs_pci.rsp_nr_device= rp->r_nr_pci_id;
- if (rs_pci.rsp_nr_device > RSP_NR_DEVICE)
- {
- printf("RS: init_pci: too many PCI devices (max %d) "
- "truncating\n",
- RSP_NR_DEVICE);
- rs_pci.rsp_nr_device= RSP_NR_DEVICE;
- }
- for (i= 0; i<rs_pci.rsp_nr_device; i++)
- {
- rs_pci.rsp_device[i].vid= rp->r_pci_id[i].vid;
- rs_pci.rsp_device[i].did= rp->r_pci_id[i].did;
- }
-
- rs_pci.rsp_nr_class= rp->r_nr_pci_class;
- if (rs_pci.rsp_nr_class > RSP_NR_CLASS)
- {
- printf("RS: init_pci: too many PCI classes "
- "(max %d) truncating\n",
- RSP_NR_CLASS);
- rs_pci.rsp_nr_class= RSP_NR_CLASS;
- }
- for (i= 0; i<rs_pci.rsp_nr_class; i++)
- {
- rs_pci.rsp_class[i].class= rp->r_pci_class[i].class;
- rs_pci.rsp_class[i].mask= rp->r_pci_class[i].mask;
- }
-
if(rs_verbose)
printf("RS: init_pci: calling pci_set_acl\n");
static char namebuf[100];
int len, r;
struct rproc *rrp;
+ struct rprocpub *rrpub;
len = m_ptr->RS_NAME_LEN;
for (rrp=BEG_RPROC_ADDR; rrp<END_RPROC_ADDR; rrp++) {
if (!(rrp->r_flags & RS_IN_USE))
continue;
- if (!strcmp(rrp->r_label, namebuf)) {
- m_ptr->RS_ENDPOINT = rrp->r_proc_nr_e;
+ rrpub = rrp->r_pub;
+ if (!strcmp(rrpub->label, namebuf)) {
+ m_ptr->RS_ENDPOINT = rrpub->endpoint;
return OK;
}
}
_PROTOTYPE( int do_lookup, (message *m));
_PROTOTYPE( int do_shutdown, (message *m));
_PROTOTYPE( void do_period, (message *m));
+_PROTOTYPE( int do_init_ready, (message *m));
_PROTOTYPE( int do_update, (message *m));
_PROTOTYPE( int do_upd_ready, (message *m));
_PROTOTYPE( void do_exit, (message *m));
_PROTOTYPE( int do_getsysinfo, (message *m));
/* utility.c */
+_PROTOTYPE( int init_service, (struct rproc *rp, int type));
_PROTOTYPE( int publish_service, (struct rproc *rp));
+_PROTOTYPE(void fill_call_mask, ( int *calls, int tot_nr_calls,
+ bitchunk_t *call_mask, int call_base, int is_init));
/* memory.c */
_PROTOTYPE( void* rs_startup_sbrk, (size_t size));
}
if (req_nr == RS_UP) {
- rs_start.rss_flags= RF_IPC_VALID;
+ rs_start.rss_flags= RSS_IPC_VALID;
if (c_flag)
- rs_start.rss_flags |= RF_COPY;
+ rs_start.rss_flags |= RSS_COPY;
if(r_flag)
- rs_start.rss_flags |= RF_REUSE;
+ rs_start.rss_flags |= RSS_REUSE;
if (do_run)
{
fatal("do_pci_device: bad ID '%s' at %s:%d",
cpe->word, cpe->file, cpe->line);
}
- if (rs_start.rss_nr_pci_id >= RSS_NR_PCI_ID)
+ if (rs_start.rss_nr_pci_id >= RS_NR_PCI_DEVICE)
{
fatal("do_pci_device: too many device IDs (max %d)",
- RSS_NR_PCI_ID);
+ RS_NR_PCI_DEVICE);
}
rs_start.rss_pci_id[rs_start.rss_nr_pci_id].vid= vid;
rs_start.rss_pci_id[rs_start.rss_nr_pci_id].did= did;
cpe->word, cpe->file, cpe->line);
}
class_id= (baseclass << 16) | (subclass << 8) | interface;
- if (rs_start.rss_nr_pci_class >= RSS_NR_PCI_CLASS)
+ if (rs_start.rss_nr_pci_class >= RS_NR_PCI_CLASS)
{
fatal("do_pci_class: too many class IDs (max %d)",
- RSS_NR_PCI_CLASS);
+ RS_NR_PCI_CLASS);
}
rs_start.rss_pci_class[rs_start.rss_nr_pci_class].class=
class_id;
word= call_nr / bits_per_word;
mask= (1UL << (call_nr % bits_per_word));
- if (word >= RSS_NR_SYSTEM)
+ if (word >= RS_SYS_CALL_MASK_SIZE)
{
fatal(
- "do_system: RSS_NR_SYSTEM is too small (%d needed)",
+ "RS_SYS_CALL_MASK_SIZE is too small (%d needed)",
word+1);
}
rs_start.rss_system[word] |= mask;
fatal("do_control: unexpected string at %s:%d",
cpe->file, cpe->line);
}
- if (nr_control >= RSS_NR_CONTROL)
+ if (nr_control >= RS_NR_CONTROL)
{
fatal(
- "do_control: RSS_NR_CONTROL is too small (%d needed)",
+ "do_control: RS_NR_CONTROL is too small (%d needed)",
nr_control+1);
}
#include "inc.h"
-/* Define kernel calls that processes are allowed to make. This is not looking
- * very nice, but we need to define the access rights on a per call basis.
+/* Define kernel calls that processes are allowed to make.
*
* Calls are unordered lists, converted by RS to bitmasks
* once at runtime.
*/
-#define FS_KC SYS_KILL, SYS_VIRCOPY, SYS_SAFECOPYFROM, SYS_SAFECOPYTO, \
+#define FS_KC SYS_KILL, SYS_VIRCOPY, SYS_SAFECOPYFROM, SYS_SAFECOPYTO, \
SYS_UMAP, SYS_GETINFO, SYS_EXIT, SYS_TIMES, SYS_SETALARM, \
SYS_PRIVCTL, SYS_TRACE , SYS_SETGRANT, SYS_PROFBUF, SYS_SYSCTL
#define DRV_KC FS_KC, SYS_SEGCTL, SYS_IRQCTL, SYS_INT86, SYS_DEVIO, \
SYS_SDEVIO, SYS_VDEVIO, SYS_SETGRANT, SYS_PROFBUF, SYS_SYSCTL
PRIVATE int
- fs_kc[] = { FS_KC, SYS_NULL_C },
- pm_kc[] = { SYS_ALL_C, SYS_NULL_C },
- ds_kc[] = { SYS_ALL_C, SYS_NULL_C },
- vm_kc[] = { SYS_ALL_C, SYS_NULL_C },
- drv_kc[] = { DRV_KC, SYS_NULL_C },
- tty_kc[] = { DRV_KC, SYS_PHYSCOPY, SYS_ABORT, SYS_IOPENABLE,
+ pm_kc[] = { SYS_ALL_C, SYS_NULL_C },
+ vfs_kc[] = { FS_KC, SYS_NULL_C },
+ rs_kc[] = { SYS_ALL_C, SYS_NULL_C },
+ ds_kc[] = { SYS_ALL_C, SYS_NULL_C },
+ vm_kc[] = { SYS_ALL_C, SYS_NULL_C },
+ tty_kc[] = { DRV_KC, SYS_PHYSCOPY, SYS_ABORT, SYS_IOPENABLE,
SYS_READBIOS, SYS_NULL_C },
- mem_kc[] = { DRV_KC, SYS_PHYSCOPY, SYS_IOPENABLE, SYS_NULL_C },
+ mem_kc[] = { DRV_KC, SYS_PHYSCOPY, SYS_IOPENABLE, SYS_NULL_C},
+ log_kc[] = { DRV_KC, SYS_NULL_C },
+ mfs_kc[] = { FS_KC, SYS_NULL_C },
+ pfs_kc[] = { FS_KC, SYS_NULL_C },
rusr_kc[] = { SYS_NULL_C },
+ no_kc[] = { SYS_NULL_C }; /* no kernel call */
- no_kc[] = { SYS_NULL_C }; /* no kernel call */
+/* Define VM calls that processes are allowed to make.
+ *
+ * Calls are unordered lists, converted by RS to bitmasks
+ * once at runtime.
+ */
+PRIVATE int
+ pm_vmc[] = { VM_BASIC_CALLS, VM_EXIT, VM_FORK, VM_BRK, VM_EXEC_NEWMEM,
+ VM_PUSH_SIG, VM_WILLEXIT, VM_ADDDMA, VM_DELDMA, VM_GETDMA,
+ VM_NOTIFY_SIG, SYS_NULL_C },
+ vfs_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
+ rs_vmc[] = { VM_BASIC_CALLS, VM_RS_SET_PRIV, SYS_NULL_C },
+ ds_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
+ vm_vmc[] = { SYS_NULL_C },
+ tty_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
+ mem_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
+ log_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
+ mfs_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
+ pfs_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
+ rusr_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
+ no_vmc[] = { SYS_NULL_C }; /* no vm call */
-/* Definition of the boot image priv table. */
+/* Definition of the boot image priv table. The order of entries in this table
+ * reflects the order boot system services are made runnable and initialized
+ * at boot time.
+ */
PUBLIC struct boot_image_priv boot_image_priv_table[] = {
- /*endpoint, label, flags, traps, ipcto, kcalls */
- { VM_PROC_NR, "vm", VM_F, SRV_T, SRV_M, vm_kc },
- { PM_PROC_NR, "pm", SRV_F, SRV_T, SRV_M, pm_kc },
- { FS_PROC_NR, "vfs", SRV_F, SRV_T, SRV_M, fs_kc },
- { DS_PROC_NR, "ds", SRV_F, SRV_T, SRV_M, ds_kc },
- { TTY_PROC_NR, "tty", SRV_F, SRV_T, SRV_M, tty_kc },
- { MEM_PROC_NR, "memory", SRV_F, SRV_T, SRV_M, mem_kc },
- { LOG_PROC_NR, "log", SRV_F, SRV_T, SRV_M, drv_kc },
- { MFS_PROC_NR, "fs_imgrd", SRV_F, SRV_T, SRV_M, fs_kc },
- { PFS_PROC_NR, "pfs", SRV_F, SRV_T, SRV_M, fs_kc },
- { INIT_PROC_NR, "init", RUSR_F, RUSR_T, RUSR_M, rusr_kc },
- { NULL_BOOT_NR, "", 0, 0, 0, no_kc } /* null entry */
+ /*endpoint, label, flags, traps, ipcto, kcalls, vmcalls */
+ { RS_PROC_NR, "rs", RSYS_F, RSYS_T, RSYS_M, rs_kc, rs_vmc },
+ { VM_PROC_NR, "vm", VM_F, SRV_T, SRV_M, vm_kc, vm_vmc },
+ { PM_PROC_NR, "pm", SRV_F, SRV_T, SRV_M, pm_kc, pm_vmc },
+ { VFS_PROC_NR, "vfs", SRV_F, SRV_T, SRV_M, vfs_kc, vfs_vmc },
+ { DS_PROC_NR, "ds", SRV_F, SRV_T, SRV_M, ds_kc, ds_vmc },
+ { TTY_PROC_NR, "tty", SRV_F, SRV_T, SRV_M, tty_kc, tty_vmc },
+ { MEM_PROC_NR, "memory", SRV_F, SRV_T, SRV_M, mem_kc, mem_vmc },
+ { LOG_PROC_NR, "log", SRV_F, SRV_T, SRV_M, log_kc, log_vmc },
+ { MFS_PROC_NR, "fs_imgrd", SRV_F, SRV_T, SRV_M, mfs_kc, mfs_vmc },
+ { PFS_PROC_NR, "pfs", SRV_F, SRV_T, SRV_M, pfs_kc, pfs_vmc },
+ { INIT_PROC_NR, "init", RUSR_F, RUSR_T, RUSR_M, rusr_kc, rusr_vmc },
+ { NULL_BOOT_NR, "", 0, 0, 0, no_kc, no_vmc }
};
/* Definition of the boot image sys table. */
PUBLIC struct boot_image_sys boot_image_sys_table[] = {
/*endpoint, flags */
+ { RS_PROC_NR, SRV_SF },
+ { VM_PROC_NR, VM_SF },
{ LOG_PROC_NR, SRVC_SF },
{ MFS_PROC_NR, SRVC_SF },
{ PFS_PROC_NR, SRVC_SF },
/* Definition of an entry of the boot image priv table. */
struct boot_image_priv {
endpoint_t endpoint; /* process endpoint number */
- char label[MAX_LABEL_LEN]; /* label to assign to this service */
+ char label[RS_MAX_LABEL_LEN]; /* label to assign to this service */
int flags; /* privilege flags */
short trap_mask; /* allowed system call traps */
int ipc_to; /* send mask protection */
- int *k_calls; /* kernel call protection */
+ int *k_calls; /* allowed kernel calls */
+ int *vm_calls; /* allowed vm calls */
};
/* Definition of an entry of the boot image sys table. */
/* Definition of an entry of the system process table. */
struct rproc {
- endpoint_t r_proc_nr_e; /* process endpoint number */
+ struct rprocpub *r_pub; /* pointer to the corresponding public entry */
pid_t r_pid; /* process id, -1 if the process is not there */
- dev_t r_dev_nr; /* major device number */
- int r_dev_style; /* device style */
int r_restarts; /* number of restarts (initially zero) */
long r_backoff; /* number of periods to wait before revive */
unsigned r_flags; /* status and policy flags */
- unsigned r_sys_flags; /* sys flags */
- long r_period; /* heartbeat period (or zero) */
clock_t r_check_tm; /* timestamp of last check */
clock_t r_alive_tm; /* timestamp of last heartbeat */
clock_t r_stop_tm; /* timestamp of SIGTERM signal */
endpoint_t r_caller; /* RS_LATEREPLY caller */
- char *r_exec; /* Executable image */
- size_t r_exec_len; /* Length of image */
-
- char r_label[MAX_LABEL_LEN]; /* label of this service */
- char r_proc_name[P_NAME_LEN]; /* process name of this service */
char r_cmd[MAX_COMMAND_LEN]; /* raw command plus arguments */
char r_script[MAX_SCRIPT_LEN]; /* name of the restart script executable */
char *r_argv[MAX_NR_ARGS+2]; /* parsed arguments vector */
int r_argc; /* number of arguments */
- /* Resources */
- int r_set_resources;
+ char *r_exec; /* Executable image */
+ size_t r_exec_len; /* Length of image */
+
+ int r_set_resources; /* set when resources must be set. */
struct priv r_priv; /* Privilege structure to be passed to the
* kernel.
*/
uid_t r_uid;
int r_nice;
- int r_nr_pci_id; /* Number of PCI devices IDs */
- struct { u16_t vid; u16_t did; } r_pci_id[RSS_NR_PCI_ID];
- int r_nr_pci_class; /* Number of PCI class IDs */
- struct { u32_t class; u32_t mask; } r_pci_class[RSS_NR_PCI_CLASS];
- u32_t r_call_mask[RSS_NR_SYSTEM];
+ u32_t r_call_mask[RS_SYS_CALL_MASK_SIZE];
char r_ipc_list[MAX_IPC_LIST];
- bitchunk_t r_vm[RSS_VM_CALL_SIZE];
int r_nr_control;
- char r_control[RSS_NR_CONTROL][MAX_LABEL_LEN];
+ char r_control[RS_NR_CONTROL][RS_MAX_LABEL_LEN];
};
/* Definition of the global update descriptor. */
#include <minix/ds.h>
+/*===========================================================================*
+ * init_service *
+ *===========================================================================*/
+PUBLIC int init_service(rp, type)
+struct rproc *rp; /* pointer to process slot */
+int type; /* type of initialization */
+{
+ int r;
+ message m;
+ struct rprocpub *rpub;
+
+ rpub = rp->r_pub;
+
+ rp->r_flags |= RS_INITIALIZING; /* now initializing */
+ rp->r_check_tm = rp->r_alive_tm + 1; /* expect reply within period */
+
+ m.m_type = RS_INIT;
+ m.RS_INIT_TYPE = type;
+ m.RS_INIT_RPROCTAB_GID = rinit.rproctab_gid;
+ r = asynsend(rpub->endpoint, &m);
+
+ return r;
+}
+
/*===========================================================================*
* publish_service *
*===========================================================================*/
{
/* A new system service has been started. Publish the necessary information. */
int s;
+ struct rprocpub *rpub;
+
+ rpub = rp->r_pub;
/* Register its label with DS. */
- s= ds_publish_u32(rp->r_label, rp->r_proc_nr_e);
+ s= ds_publish_u32(rpub->label, rpub->endpoint);
if (s != OK) {
return s;
}
if (rs_verbose) {
printf("RS: publish_service: DS label registration done: %s -> %d\n",
- rp->r_label, rp->r_proc_nr_e);
+ rpub->label, rpub->endpoint);
}
return(OK);
}
+/*===========================================================================*
+ * fill_call_mask *
+ *===========================================================================*/
+PUBLIC void fill_call_mask(calls, tot_nr_calls, call_mask, call_base, is_init)
+int *calls; /* the unordered set of calls */
+int tot_nr_calls; /* the total number of calls */
+bitchunk_t *call_mask; /* the call mask to fill in */
+int call_base; /* the base offset for the calls */
+int is_init; /* set when initializing a call mask */
+{
+/* Fill a call mask from an unordered set of calls. */
+ int i;
+ int call_mask_size, nr_calls;
+
+ call_mask_size = BITMAP_CHUNKS(tot_nr_calls);
+
+ /* Count the number of calls to fill in. */
+ nr_calls = 0;
+ for(i=0; calls[i] != SYS_NULL_C; i++) {
+ nr_calls++;
+ }
+
+ /* See if all calls are allowed and call mask must be completely filled. */
+ if(nr_calls == 1 && calls[0] == SYS_ALL_C) {
+ for(i=0; i < call_mask_size; i++) {
+ call_mask[i] = (~0);
+ }
+ }
+ else {
+ /* When initializing, reset the mask first. */
+ if(is_init) {
+ for(i=0; i < call_mask_size; i++) {
+ call_mask[i] = 0;
+ }
+ }
+ /* Enter calls bit by bit. */
+ for(i=0; i < nr_calls; i++) {
+ SET_BIT(call_mask, calls[i] - call_base);
+ }
+ }
+}
+
EXTERN unsigned long calls_stats[NCALLS];
#endif
-FORWARD _PROTOTYPE( void fs_init, (void) );
FORWARD _PROTOTYPE( void get_work, (void) );
FORWARD _PROTOTYPE( void init_root, (void) );
FORWARD _PROTOTYPE( void service_pm, (void) );
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
/*===========================================================================*
* main *
/* SEF local startup. */
sef_local_startup();
- fs_init();
-
- SANITYCHECK;
-
-#if DO_SANITYCHECKS
- FIXME("VFS: DO_SANITYCHECKS is on");
-#endif
-
/* This is the main loop that gets work, processes it, and sends replies. */
while (TRUE) {
SANITYCHECK;
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_restart_fail);
+
/* No live update support for now. */
/* Let SEF perform startup. */
sef_startup();
}
+/*===========================================================================*
+ * sef_cb_init_fresh *
+ *===========================================================================*/
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the virtual file server. */
+ int s;
+ register struct fproc *rfp;
+ struct vmnt *vmp;
+ struct vnode *root_vp;
+ message mess;
+
+ /* Clear endpoint field */
+ last_login_fs_e = NONE;
+ mount_m_in.m1_p3 = (char *) NONE;
+
+ /* Initialize the process table with help of the process manager messages.
+ * Expect one message for each system process with its slot number and pid.
+ * When no more processes follow, the magic process number NONE is sent.
+ * Then, stop and synchronize with the PM.
+ */
+ do {
+ if (OK != (s=sef_receive(PM_PROC_NR, &mess)))
+ panic(__FILE__,"FS couldn't receive from PM", s);
+
+ if (mess.m_type != PM_INIT)
+ panic(__FILE__, "unexpected message from PM", mess.m_type);
+
+ if (NONE == mess.PM_PROC) break;
+
+ rfp = &fproc[mess.PM_SLOT];
+ rfp->fp_pid = mess.PM_PID;
+ rfp->fp_endpoint = mess.PM_PROC;
+ rfp->fp_realuid = (uid_t) SYS_UID;
+ rfp->fp_effuid = (uid_t) SYS_UID;
+ rfp->fp_realgid = (gid_t) SYS_GID;
+ rfp->fp_effgid = (gid_t) SYS_GID;
+ rfp->fp_umask = ~0;
+ rfp->fp_grant = GRANT_INVALID;
+ rfp->fp_blocked_on = FP_BLOCKED_ON_NONE;
+ rfp->fp_revived = NOT_REVIVING;
+
+ } while (TRUE); /* continue until process NONE */
+ mess.m_type = OK; /* tell PM that we succeeded */
+ s = send(PM_PROC_NR, &mess); /* send synchronization message */
+
+ /* All process table entries have been set. Continue with FS initialization.
+ * Certain relations must hold for the file system to work at all. Some
+ * extra block_size requirements are checked at super-block-read-in time.
+ */
+ if (OPEN_MAX > 127) panic(__FILE__,"OPEN_MAX > 127", NO_NUM);
+
+ /* The following initializations are needed to let dev_opcl succeed .*/
+ fp = (struct fproc *) NULL;
+ who_e = who_p = FS_PROC_NR;
+
+ build_dmap(); /* build device table and map boot driver */
+ init_root(); /* init root device and load super block */
+ init_select(); /* init select() structures */
+
+
+ vmp = &vmnt[0]; /* Should be the root filesystem */
+ if (vmp->m_dev == NO_DEV)
+ panic(__FILE__, "vfs: no root filesystem", NO_NUM);
+ root_vp= vmp->m_root_node;
+
+ /* The root device can now be accessed; set process directories. */
+ for (rfp=&fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
+ FD_ZERO(&(rfp->fp_filp_inuse));
+ if (rfp->fp_pid != PID_FREE) {
+
+ dup_vnode(root_vp);
+ rfp->fp_rd = root_vp;
+ dup_vnode(root_vp);
+ rfp->fp_wd = root_vp;
+
+ } else rfp->fp_endpoint = NONE;
+ }
+
+ system_hz = sys_hz();
+
+ SANITYCHECK;
+
+#if DO_SANITYCHECKS
+ FIXME("VFS: DO_SANITYCHECKS is on");
+#endif
+
+ return(OK);
+}
+
/*===========================================================================*
* get_work *
*===========================================================================*/
result, whom, s);
}
-/*===========================================================================*
- * fs_init *
- *===========================================================================*/
-PRIVATE void fs_init()
-{
-/* Initialize global variables, tables, etc. */
- int s;
- register struct fproc *rfp;
- struct vmnt *vmp;
- struct vnode *root_vp;
- message mess;
-
- /* Clear endpoint field */
- last_login_fs_e = NONE;
- mount_m_in.m1_p3 = (char *) NONE;
-
- /* Initialize the process table with help of the process manager messages.
- * Expect one message for each system process with its slot number and pid.
- * When no more processes follow, the magic process number NONE is sent.
- * Then, stop and synchronize with the PM.
- */
- do {
- if (OK != (s=sef_receive(PM_PROC_NR, &mess)))
- panic(__FILE__,"FS couldn't receive from PM", s);
-
- if (mess.m_type != PM_INIT)
- panic(__FILE__, "unexpected message from PM", mess.m_type);
-
- if (NONE == mess.PM_PROC) break;
-
- rfp = &fproc[mess.PM_SLOT];
- rfp->fp_pid = mess.PM_PID;
- rfp->fp_endpoint = mess.PM_PROC;
- rfp->fp_realuid = (uid_t) SYS_UID;
- rfp->fp_effuid = (uid_t) SYS_UID;
- rfp->fp_realgid = (gid_t) SYS_GID;
- rfp->fp_effgid = (gid_t) SYS_GID;
- rfp->fp_umask = ~0;
- rfp->fp_grant = GRANT_INVALID;
- rfp->fp_blocked_on = FP_BLOCKED_ON_NONE;
- rfp->fp_revived = NOT_REVIVING;
-
- } while (TRUE); /* continue until process NONE */
- mess.m_type = OK; /* tell PM that we succeeded */
- s = send(PM_PROC_NR, &mess); /* send synchronization message */
-
- /* All process table entries have been set. Continue with FS initialization.
- * Certain relations must hold for the file system to work at all. Some
- * extra block_size requirements are checked at super-block-read-in time.
- */
- if (OPEN_MAX > 127) panic(__FILE__,"OPEN_MAX > 127", NO_NUM);
-
- /* The following initializations are needed to let dev_opcl succeed .*/
- fp = (struct fproc *) NULL;
- who_e = who_p = FS_PROC_NR;
-
- build_dmap(); /* build device table and map boot driver */
- init_root(); /* init root device and load super block */
- init_select(); /* init select() structures */
-
-
- vmp = &vmnt[0]; /* Should be the root filesystem */
- if (vmp->m_dev == NO_DEV)
- panic(__FILE__, "vfs:fs_init: no root filesystem", NO_NUM);
- root_vp= vmp->m_root_node;
-
- /* The root device can now be accessed; set process directories. */
- for (rfp=&fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
- FD_ZERO(&(rfp->fp_filp_inuse));
- if (rfp->fp_pid != PID_FREE) {
-
- dup_vnode(root_vp);
- rfp->fp_rd = root_vp;
- dup_vnode(root_vp);
- rfp->fp_wd = root_vp;
-
- } else rfp->fp_endpoint = NONE;
- }
-
- system_hz = sys_hz();
-}
-
/*===========================================================================*
* init_root *
*===========================================================================*/
vmc->vm_flags &= (VMF_INUSE|VMF_SEPARATE|VMF_HASPT);
/* inherit the priv call bitmaps */
- memcpy(&vmc->vm_call_priv_mask, &vmp->vm_call_priv_mask,
- sizeof(vmc->vm_call_priv_mask));
+ memcpy(&vmc->vm_call_mask, &vmp->vm_call_mask, sizeof(vmc->vm_call_mask));
/* Tell kernel about the (now successful) FORK. */
if((r=sys_fork(vmp->vm_endpoint, childproc,
#include <minix/const.h>
#include <minix/bitmap.h>
#include <minix/crtso.h>
+#include <minix/rs.h>
#include <errno.h>
#include <string.h>
#include "../../kernel/config.h"
#include "../../kernel/proc.h"
-typedef u32_t mask_t;
-#define MINEPM 0
-#define MAXMASK (sizeof(mask_t)*8)
-#define ANYEPM (MINEPM+MAXMASK-1)
-#define NEEDACL (MINEPM+MAXMASK-2)
-#define MAXEPM (NEEDACL-1)
-#define EPM(e) ((1L) << ((e)-MINEPM))
-#define EPMOK(mask, ep) (((mask) & EPM(ANYEPM)) || ((ep) >= MINEPM && (ep) <= MAXEPM && (EPM(ep) & (mask))))
-
/* Table of calls and a macro to test for being in range. */
struct {
- mask_t vmc_callers; /* bitmap of endpoint numbers */
int (*vmc_func)(message *); /* Call handles message. */
char *vmc_name; /* Human-readable string. */
-} vm_calls[VM_NCALLS];
+} vm_calls[NR_VM_CALLS];
/* Macro to verify call range and map 'high' range to 'base' range
* (starting at 0) in one. Evaluates to zero-based call number if call
(c) < VM_RQ_BASE + ELEMENTS(vm_calls)) ? \
((c) - VM_RQ_BASE) : -1)
-FORWARD _PROTOTYPE(void vm_init, (void));
+FORWARD _PROTOTYPE(int map_service, (struct rprocpub *rpub));
FORWARD _PROTOTYPE(int vm_acl_ok, (endpoint_t caller, int call));
+extern int unmap_ok;
+
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
/*===========================================================================*
* main *
/* SEF local startup. */
sef_local_startup();
-#if SANITYCHECKS
- incheck = nocheck = 0;
- FIXME("VM SANITYCHECKS are on");
-#endif
-
- vm_paged = 1;
- env_parse("vm_paged", "d", 0, &vm_paged, 0, 1);
-#if SANITYCHECKS
- env_parse("vm_sanitychecklevel", "d", 0, &vm_sanitychecklevel, 0, SCL_MAX);
-#endif
-
- vm_init();
-
/* This is VM's main loop. */
while (TRUE) {
int r, c;
*===========================================================================*/
PRIVATE void sef_local_startup()
{
+ /* Register init callbacks. */
+ sef_setcb_init_fresh(sef_cb_init_fresh);
+ sef_setcb_init_restart(sef_cb_init_restart_fail);
+
/* No live update support for now. */
/* Let SEF perform startup. */
sef_startup();
}
-extern int unmap_ok;
-
/*===========================================================================*
- * vm_init *
+ * sef_cb_init_fresh *
*===========================================================================*/
-PRIVATE void vm_init(void)
+PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
+/* Initialize the vm server. */
int s, i;
int click, clicksforgotten = 0;
struct memory mem_chunks[NR_MEMS];
struct boot_image image[NR_BOOT_PROCS];
struct boot_image *ip;
+ struct rprocpub rprocpub[NR_BOOT_PROCS];
phys_bytes limit = 0;
+#if SANITYCHECKS
+ incheck = nocheck = 0;
+ FIXME("VM SANITYCHECKS are on");
+#endif
+
+ vm_paged = 1;
+ env_parse("vm_paged", "d", 0, &vm_paged, 0, 1);
+#if SANITYCHECKS
+ env_parse("vm_sanitychecklevel", "d", 0, &vm_sanitychecklevel, 0, SCL_MAX);
+#endif
+
/* Get chunks of available memory. */
get_mem_chunks(mem_chunks);
vmp->vm_arch.vm_seg[D].mem_len;
if(pt_new(&vmp->vm_pt) != OK)
- vm_panic("vm_init: no new pagetable", NO_NUM);
+ vm_panic("VM: no new pagetable", NO_NUM);
#define BASICSTACK VM_PAGE_SIZE
old_stacktop = CLICK2ABS(vmp->vm_arch.vm_seg[S].mem_vir +
vmp->vm_arch.vm_seg[S].mem_len);
}
/* Set up table of calls. */
-#define CALLMAP(code, func, thecaller) { int i; \
+#define CALLMAP(code, func) { int i; \
if((i=CALLNUMBER(code)) < 0) { vm_panic(#code " invalid", (code)); } \
- if(i >= VM_NCALLS) { vm_panic(#code " invalid", (code)); } \
+ if(i >= NR_VM_CALLS) { vm_panic(#code " invalid", (code)); } \
vm_calls[i].vmc_func = (func); \
vm_calls[i].vmc_name = #code; \
- if(((thecaller) < MINEPM || (thecaller) > MAXEPM) \
- && (thecaller) != ANYEPM \
- && (thecaller) != NEEDACL ) { \
- vm_panic(#thecaller " invalid", (code)); \
- } \
- vm_calls[i].vmc_callers |= EPM(thecaller); \
}
/* Set call table to 0. This invalidates all calls (clear
*/
memset(vm_calls, 0, sizeof(vm_calls));
- /* Requests from PM (restricted to be from PM only). */
- CALLMAP(VM_EXIT, do_exit, PM_PROC_NR);
- CALLMAP(VM_FORK, do_fork, PM_PROC_NR);
- CALLMAP(VM_BRK, do_brk, PM_PROC_NR);
- CALLMAP(VM_EXEC_NEWMEM, do_exec_newmem, PM_PROC_NR);
- CALLMAP(VM_PUSH_SIG, do_push_sig, PM_PROC_NR);
- CALLMAP(VM_WILLEXIT, do_willexit, PM_PROC_NR);
- CALLMAP(VM_ADDDMA, do_adddma, PM_PROC_NR);
- CALLMAP(VM_DELDMA, do_deldma, PM_PROC_NR);
- CALLMAP(VM_GETDMA, do_getdma, PM_PROC_NR);
- CALLMAP(VM_NOTIFY_SIG, do_notify_sig, PM_PROC_NR);
-
- /* Requests from RS */
- CALLMAP(VM_RS_SET_PRIV, do_rs_set_priv, RS_PROC_NR);
-
- /* Requests from userland (source unrestricted). */
- CALLMAP(VM_MMAP, do_mmap, ANYEPM);
- CALLMAP(VM_MUNMAP, do_munmap, ANYEPM);
- CALLMAP(VM_MUNMAP_TEXT, do_munmap, ANYEPM);
- CALLMAP(VM_MAP_PHYS, do_map_phys, ANYEPM); /* Does its own checking. */
- CALLMAP(VM_UNMAP_PHYS, do_unmap_phys, ANYEPM);
-
- /* Requests from userland (anyone can call but need an ACL bit). */
- CALLMAP(VM_REMAP, do_remap, NEEDACL);
- CALLMAP(VM_GETPHYS, do_get_phys, NEEDACL);
- CALLMAP(VM_SHM_UNMAP, do_shared_unmap, NEEDACL);
- CALLMAP(VM_GETREF, do_get_refcount, NEEDACL);
- CALLMAP(VM_CTL, do_ctl, NEEDACL);
- CALLMAP(VM_QUERY_EXIT, do_query_exit, NEEDACL);
+ /* Basic VM calls. */
+ CALLMAP(VM_MMAP, do_mmap);
+ CALLMAP(VM_MUNMAP, do_munmap);
+ CALLMAP(VM_MUNMAP_TEXT, do_munmap);
+ CALLMAP(VM_MAP_PHYS, do_map_phys);
+ CALLMAP(VM_UNMAP_PHYS, do_unmap_phys);
+
+ /* Calls from PM. */
+ CALLMAP(VM_EXIT, do_exit);
+ CALLMAP(VM_FORK, do_fork);
+ CALLMAP(VM_BRK, do_brk);
+ CALLMAP(VM_EXEC_NEWMEM, do_exec_newmem);
+ CALLMAP(VM_PUSH_SIG, do_push_sig);
+ CALLMAP(VM_WILLEXIT, do_willexit);
+ CALLMAP(VM_ADDDMA, do_adddma);
+ CALLMAP(VM_DELDMA, do_deldma);
+ CALLMAP(VM_GETDMA, do_getdma);
+ CALLMAP(VM_NOTIFY_SIG, do_notify_sig);
+
+ /* Calls from RS */
+ CALLMAP(VM_RS_SET_PRIV, do_rs_set_priv);
+
+ /* Generic calls. */
+ CALLMAP(VM_REMAP, do_remap);
+ CALLMAP(VM_GETPHYS, do_get_phys);
+ CALLMAP(VM_SHM_UNMAP, do_shared_unmap);
+ CALLMAP(VM_GETREF, do_get_refcount);
+ CALLMAP(VM_CTL, do_ctl);
+ CALLMAP(VM_QUERY_EXIT, do_query_exit);
/* Sanity checks */
if(find_kernel_top() >= VM_PROCSTART)
/* Unmap our own low pages. */
unmap_ok = 1;
_minix_unmapzero();
+
+ /* Map all the services in the boot image. */
+ if((s = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0,
+ (vir_bytes) rprocpub, sizeof(rprocpub), S)) != OK) {
+ panic("VM", "sys_safecopyfrom failed", s);
+ }
+ for(i=0;i < NR_BOOT_PROCS;i++) {
+ if(rprocpub[i].in_use) {
+ if((s = map_service(&rprocpub[i])) != OK) {
+ vm_panic("unable to map service", s);
+ }
+ }
+ }
+
+ return(OK);
+}
+
+/*===========================================================================*
+ * map_service *
+ *===========================================================================*/
+PRIVATE int map_service(rpub)
+struct rprocpub *rpub;
+{
+/* Map a new service by initializing its call mask. */
+ int r, proc_nr;
+
+ if ((r = vm_isokendpt(rpub->endpoint, &proc_nr)) != OK) {
+ return r;
+ }
+
+ /* Copy the call mask. */
+ memcpy(&vmproc[proc_nr].vm_call_mask, &rpub->vm_call_mask,
+ sizeof(vmproc[proc_nr].vm_call_mask));
+
+ return(OK);
}
/*===========================================================================*
{
int n, r;
- /* Some calls are always allowed by some, or all, processes. */
- if(EPMOK(vm_calls[call].vmc_callers, caller)) {
- return OK;
- }
-
if ((r = vm_isokendpt(caller, &n)) != OK)
vm_panic("VM: from strange source.", caller);
- /* Other calls need an ACL bit. */
- if (!(vm_calls[call].vmc_callers & EPM(NEEDACL))) {
- return EPERM;
- }
- if (!GET_BIT(vmproc[n].vm_call_priv_mask, call)) {
- printf("VM: no ACL for %s for %d\n",
- vm_calls[call].vmc_name, caller);
+ /* See if the call is allowed. */
+ if (!GET_BIT(vmproc[n].vm_call_mask, call)) {
return EPERM;
}
return OK;
}
+
if (m->VM_RS_BUF) {
r = sys_datacopy(m->m_source, (vir_bytes) m->VM_RS_BUF,
- SELF, (vir_bytes) vmp->vm_call_priv_mask,
- sizeof(vmp->vm_call_priv_mask));
+ SELF, (vir_bytes) vmp->vm_call_mask,
+ sizeof(vmp->vm_call_mask));
if (r != OK)
return r;
}
/* Heap for brk() to extend. */
struct vir_region *vm_heap;
-#define VM_CALL_PRIV_MASK_SIZE BITMAP_CHUNKS(VM_NCALLS)
- bitchunk_t vm_call_priv_mask[VM_CALL_PRIV_MASK_SIZE];
+ bitchunk_t vm_call_mask[VM_CALL_MASK_SIZE];
/* State for requests pending to be done to vfs on behalf of
* this process.