Initialization protocol for system services.

SYSLIB CHANGES:
- SEF framework now supports a new SEF Init request type from RS. 3 different
callbacks are available (init_fresh, init_lu, init_restart) to specify
initialization code when a service starts fresh, starts after a live update,
or restarts.

SYSTEM SERVICE CHANGES:
- Initialization code for system services is now enclosed in a callback SEF will
automatically call at init time. The return code of the callback will
tell RS whether the initialization completed successfully.
- Each init callback can access information passed by RS to initialize. As of
now, each system service has access to the public entries of RS's system process
table to gather all the information required to initialize. This design
eliminates many existing or potential races at boot time and provides a uniform
initialization interface to system services. The same interface will be reused
for the upcoming publish/subscribe model to handle dynamic 
registration / deregistration of system services.

VM CHANGES:
- Uniform privilege management for all system services. Every service uses the
same call mask format. For boot services, VM copies the call mask from init
data. For dynamic services, VM still receives the call mask via rs_set_priv
call that will be soon replaced by the upcoming publish/subscribe model.

RS CHANGES:
- The system process table has been reorganized and split into private entries
and public entries. Only the latter ones are exposed to system services.
- VM call masks are now entirely configured in rs/table.c
- RS has now its own slot in the system process table. Only kernel tasks and
user processes not included in the boot image are now left out from the system
process table.
- RS implements the initialization protocol for system services.
- For services in the boot image, RS blocks till initialization is complete and
panics when failure is reported back. Services are initialized in their order of
appearance in the boot image priv table and RS blocks to implements synchronous
initialization for every system service having the flag SF_SYNCH_BOOT set.
- For services started dynamically, the initialization protocol is implemented
as though it were the first ping for the service. In this case, if the
system service fails to report back (or reports failure), RS brings the service
down rather than trying to restart it.
This commit is contained in:
Cristiano Giuffrida 2010-01-08 01:20:42 +00:00
parent acc3c30855
commit d1fd04e72a
70 changed files with 2575 additions and 1607 deletions

View file

@ -49,7 +49,6 @@ static int dev_devind;
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);
@ -65,6 +64,7 @@ static void report_exceptions(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) );
int main(void)
{
@ -74,10 +74,6 @@ int main(void)
/* SEF local startup. */
sef_local_startup();
printf("amddev: starting\n");
init();
for(;;)
{
report_exceptions();
@ -106,6 +102,11 @@ int main(void)
*===========================================================================*/
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);
@ -114,12 +115,18 @@ PRIVATE void sef_local_startup()
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;
@ -147,6 +154,8 @@ static int init()
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)

View file

@ -217,6 +217,7 @@ PRIVATE struct driver w_dtab = {
/* 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) );
@ -226,11 +227,43 @@ 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();
/* Call the generic receive loop. */
driver_task(&w_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 at_wini driver. */
struct sigaction sa;
/* Install signal handlers. Ask PM to transform signal into message. */
system_hz = sys_hz();
@ -244,28 +277,13 @@ PUBLIC int main(int argc, char *argv[])
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);
/* Set special disk parameters. */
init_params();
signal(SIGTERM, SIG_IGN);
driver_task(&w_dtab, DRIVER_STD);
return(OK);
}
/*===========================================================================*
* 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();
}
/*===========================================================================*
* init_params *
*===========================================================================*/

View file

@ -91,6 +91,8 @@ PRIVATE struct {
{ 0x0000, 0x0000 }
};
long instance;
/*===========================================================================*
* atl2_read_vpd *
*===========================================================================*/
@ -1237,39 +1239,19 @@ PRIVATE void atl2_dump(void)
}
/*===========================================================================*
* 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. */
@ -1296,6 +1278,39 @@ int main(int argc, char **argv)
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);

View file

@ -79,6 +79,7 @@ PRIVATE device_available = 0;/*todo*/
/* 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) );
@ -92,8 +93,6 @@ PUBLIC void main(void)
/* 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. */
@ -185,6 +184,11 @@ PUBLIC void main(void)
*===========================================================================*/
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);
@ -194,6 +198,15 @@ PRIVATE void sef_local_startup()
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;

View file

@ -96,23 +96,19 @@ PRIVATE struct driver w_dtab = {
/* 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);
}
@ -121,6 +117,11 @@ PUBLIC int main()
*===========================================================================*/
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);
@ -129,6 +130,21 @@ PRIVATE void sef_local_startup()
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 *
*===========================================================================*/

View file

@ -234,6 +234,9 @@ PRIVATE int handle_hw_intr(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;
/*===========================================================================*
* dpeth_task *
@ -241,38 +244,11 @@ FORWARD _PROTOTYPE( void sef_local_startup, (void) );
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)
{
@ -331,12 +307,54 @@ int main(int argc, char *argv[])
*===========================================================================*/
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 *

View file

@ -579,6 +579,9 @@ PRIVATE void handle_hw_intr(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;
/*
** Name: int dpeth_task(void)
@ -588,34 +591,11 @@ PUBLIC int main(int argc, char **argv)
{
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);
@ -680,10 +660,48 @@ PUBLIC int main(int argc, char **argv)
*===========================================================================*/
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 **/

View file

@ -64,6 +64,9 @@ _PROTOTYPE( PRIVATE void mess_reply, (message *req, message *reply) );
/* 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 *
@ -71,40 +74,12 @@ FORWARD _PROTOTYPE( void sef_local_startup, (void) );
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.
*/
@ -150,12 +125,55 @@ int main(int argc, char *argv[])
*===========================================================================*/
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 *
*===========================================================================*/

View file

@ -73,6 +73,12 @@ static cp_grant_id_t grant_id; /* IO_GRANT */
/* 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 *
*===========================================================================*/
@ -384,17 +390,6 @@ static void got_signal(void)
exit(0);
}
/*===========================================================================*
* sef_local_startup *
*===========================================================================*/
static void sef_local_startup(void)
{
/* No live update support for now. */
/* Let SEF perform startup. */
sef_startup();
}
/*===========================================================================*
* main *
*===========================================================================*/
@ -404,21 +399,9 @@ int main(int argc, char *argv[])
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) {
@ -466,3 +449,43 @@ int main(int argc, char *argv[])
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);
}

View file

@ -292,6 +292,7 @@ static phys_bytes floppy_buf_phys;
/* 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) );
@ -300,14 +301,45 @@ PUBLIC int last_transfer_opcode;
/*===========================================================================*
* 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();
@ -337,21 +369,7 @@ PUBLIC void main()
/* 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);
}
/*===========================================================================*

View file

@ -2,6 +2,6 @@
#include "../libdriver/driver.h"
#include "../libdriver/drvlib.h"
_PROTOTYPE(void main, (void));
_PROTOTYPE(int main, (void));

View file

@ -303,6 +303,9 @@ PRIVATE void handle_hw_intr(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 *
@ -310,42 +313,12 @@ FORWARD _PROTOTYPE( void sef_local_startup, (void) );
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)
@ -401,12 +374,59 @@ int main(int argc, char *argv[])
*===========================================================================*/
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 *
*===========================================================================*/

View file

@ -267,6 +267,9 @@ phys_bytes lance_buf_phys;
/* 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 *
@ -275,38 +278,12 @@ void main( int argc, char **argv )
{
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)
@ -396,12 +373,52 @@ void main( int argc, char **argv )
*===========================================================================*/
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 *
*===========================================================================*/

View file

@ -56,6 +56,7 @@ extern int device_caller;
/* 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) );
@ -65,11 +66,42 @@ EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) );
*===========================================================================*/
PUBLIC int main(void)
{
int i;
/* SEF local startup. */
sef_local_startup();
/* Call the generic receive loop. */
driver_task(&log_dtab, DRIVER_ASYN);
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 log driver. */
int i;
/* Initialize log devices. */
for(i = 0; i < NR_DEVS; i++) {
log_geom[i].dv_size = cvul64(LOG_SIZE);
@ -82,24 +114,10 @@ PUBLIC int main(void)
logdevices[i].log_proc_nr = 0;
logdevices[i].log_revive_alerted = 0;
}
driver_task(&log_dtab, DRIVER_ASYN);
return(OK);
}
/*===========================================================================*
* 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();
}
/*===========================================================================*
* log_name *
*===========================================================================*/

View file

@ -55,7 +55,6 @@ FORWARD _PROTOTYPE( int m_transfer, (int proc_nr, int opcode,
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) );
@ -86,25 +85,19 @@ PRIVATE char dev_zero[ZERO_BUF_SIZE];
/* 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);
}
@ -113,6 +106,11 @@ PUBLIC int main(void)
*===========================================================================*/
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);
@ -121,6 +119,58 @@ PRIVATE void sef_local_startup()
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 *
*===========================================================================*/
@ -357,50 +407,6 @@ message *m_ptr;
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 *
*===========================================================================*/

View file

@ -238,6 +238,9 @@ extern int errno;
/* 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 *
@ -246,33 +249,11 @@ FORWARD _PROTOTYPE( void sef_local_startup, (void) );
* 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)
@ -354,12 +335,47 @@ int main(int argc, char *argv[]) {
*===========================================================================*/
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 *
* *

View file

@ -10,13 +10,7 @@ main.c
#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) );
@ -52,8 +46,6 @@ int main(void)
/* SEF local startup. */
sef_local_startup();
pci_init();
for(;;)
{
r= sef_receive(ANY, &m);
@ -112,6 +104,11 @@ int main(void)
*===========================================================================*/
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);
@ -126,7 +123,7 @@ message *mp;
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;
@ -363,7 +360,7 @@ message *mp;
for (i= 0; i<NR_DRIVERS; i++)
{
if (!acl[i].inuse)
if (!pci_acl[i].inuse)
break;
}
if (i >= NR_DRIVERS)
@ -375,18 +372,18 @@ message *mp;
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);
@ -408,9 +405,9 @@ message *mp;
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;
}
@ -421,10 +418,10 @@ message *mp;
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 */
@ -621,10 +618,10 @@ int endpoint;
/* 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;
}

View file

@ -12,7 +12,6 @@ Created: Jan 2000 by Philip Homburg <philip@cs.vu.nl>
#include <ibm/pci.h>
#include <sys/vm_i386.h>
#include <minix/com.h>
#include <minix/rs.h>
#include <minix/syslib.h>
#include "pci.h"
@ -86,6 +85,8 @@ PRIVATE struct pcidev
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 */
@ -149,6 +150,75 @@ FORWARD _PROTOTYPE( void print_capabilities, (int devind) );
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 *
*===========================================================================*/
@ -189,34 +259,6 @@ PUBLIC void pci_outl(U16_t port, U32_t value) {
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 *
*===========================================================================*/

View file

@ -4,6 +4,8 @@ pci.h
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) );
@ -61,6 +63,14 @@ struct pci_pcibridge
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 */
@ -81,7 +91,9 @@ extern struct pci_intel_ctrl pci_intel_ctrl[];
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,

View file

@ -117,6 +117,7 @@ FORWARD _PROTOTYPE( void do_signal, (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 _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) );
@ -129,18 +130,10 @@ PUBLIC void main(void)
{
/* 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);
@ -180,6 +173,11 @@ PUBLIC void main(void)
*===========================================================================*/
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);
@ -189,6 +187,23 @@ PRIVATE void sef_local_startup()
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 *
*===========================================================================*/

View file

@ -26,7 +26,6 @@ FORWARD _PROTOTYPE( struct device *r_prepare, (int device) );
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) );
@ -56,6 +55,7 @@ PRIVATE char random_buf[RANDOM_BUF_SIZE];
/* 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 *
@ -65,8 +65,9 @@ PUBLIC int main(void)
/* 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);
}
@ -75,6 +76,11 @@ PUBLIC int main(void)
*===========================================================================*/
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);
@ -83,6 +89,40 @@ PRIVATE void sef_local_startup()
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 *
*===========================================================================*/
@ -199,37 +239,6 @@ message *m_ptr;
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 *
*===========================================================================*/

View file

@ -52,6 +52,7 @@
#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>
@ -103,6 +104,7 @@ int main(int argc, char **argv)
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) {

View file

@ -193,52 +193,23 @@ u32_t system_hz;
/* 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)
{
@ -317,6 +288,11 @@ int main(int argc, char *argv[])
*===========================================================================*/
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);
@ -326,6 +302,49 @@ PRIVATE void sef_local_startup()
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 *
*===========================================================================*/

View file

@ -286,46 +286,21 @@ u32_t system_hz;
/* 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. */
env_setargs(argc, argv);
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);
/* 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);
@ -391,12 +366,56 @@ int main(int argc, char *argv[])
*===========================================================================*/
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;

View file

@ -37,7 +37,6 @@ FORWARD _PROTOTYPE( void dsp_hardware_msg, (void) );
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) );
@ -79,6 +78,7 @@ PRIVATE int reviveProcNr;
/* 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) );
@ -90,17 +90,12 @@ PUBLIC int is_status_msg_expected = FALSE;
*===========================================================================*/
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);
@ -152,6 +147,11 @@ send_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);
@ -161,6 +161,33 @@ PRIVATE void sef_local_startup()
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
*===========================================================================*/
@ -392,33 +419,6 @@ int status;
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
*===========================================================================*/

View file

@ -47,7 +47,7 @@ FORWARD _PROTOTYPE( void sef_local_startup, (void) );
* main
*===========================================================================*/
PUBLIC void main() {
message mess;
message mess;
int err, caller, proc_nr;
/* SEF local startup. */

View file

@ -51,7 +51,6 @@ PRIVATE struct pcitab pcitab_ti[]=
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) );
@ -61,33 +60,22 @@ FORWARD _PROTOTYPE( u8_t do_inb, (port_t port) );
/* 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);
@ -104,6 +92,11 @@ int main(int argc, char *argv[])
*===========================================================================*/
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);
@ -112,11 +105,32 @@ PRIVATE void sef_local_startup()
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;
@ -167,6 +181,8 @@ PRIVATE void init()
continue;
hw_init(&ports[i]);
}
return(OK);
}
PRIVATE void hw_init(pp)

View file

@ -149,6 +149,7 @@ extern PUBLIC phys_bytes vid_base;
/* 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 *
@ -159,23 +160,12 @@ PUBLIC int main(void)
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;
@ -338,12 +328,38 @@ PUBLIC int main(void)
*===========================================================================*/
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 *
*===========================================================================*/

View file

@ -352,6 +352,7 @@
# 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 */
@ -626,6 +627,7 @@
#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 */
@ -638,6 +640,10 @@
# 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 */
@ -959,7 +965,12 @@
#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 *

View file

@ -38,6 +38,7 @@
*/
#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

View file

@ -8,13 +8,25 @@ Interface to the reincarnation server
*/
#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
@ -40,38 +52,45 @@ struct rs_start
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));

View file

@ -13,6 +13,61 @@ _PROTOTYPE( int sef_receive, (endpoint_t src, message *m_ptr) );
#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 *
*===========================================================================*/

View file

@ -49,6 +49,7 @@
#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)

View file

@ -30,7 +30,6 @@
( 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)

View file

@ -126,7 +126,7 @@ PUBLIC void main()
}
/* 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));
}
}

View file

@ -40,8 +40,7 @@ struct priv {
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 */

View file

@ -97,7 +97,7 @@ message *m_ptr; /* pointer to request message */
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 */
@ -107,7 +107,7 @@ message *m_ptr; /* pointer to request message */
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));
}

View file

@ -113,7 +113,8 @@ endpoint_t *e_granter; /* new granter (magic grants) */
/* 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");
@ -147,7 +148,8 @@ endpoint_t *e_granter; /* new granter (magic grants) */
}
/* 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;
@ -180,7 +182,8 @@ endpoint_t *e_granter; /* new granter (magic grants) */
}
/* 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;

View file

@ -30,6 +30,7 @@ libsys_FILES=" \
sef.c \
sef_liveupdate.c \
sef_ping.c \
sef_init.c \
sys_abort.c \
sys_cprof.c \
sys_endsig.c \

View file

@ -37,6 +37,8 @@
} \
}
#define NR_STATIC_GRANTS 2
PRIVATE cp_grant_t static_grants[NR_STATIC_GRANTS];
PRIVATE cp_grant_t *grants = NULL;
PRIVATE int ngrants = 0;
@ -48,12 +50,19 @@ cpf_grow(void)
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. */
@ -66,12 +75,12 @@ cpf_grow(void)
/* 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;
}

View file

@ -18,6 +18,10 @@ PRIVATE char sef_debug_header_buff[SEF_DEBUG_HEADER_MAXLEN];
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) );
@ -39,6 +43,30 @@ PUBLIC void sef_startup()
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
}
/*===========================================================================*

137
lib/syslib/sef_init.c Normal file
View file

@ -0,0 +1,137 @@
#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);
}

View file

@ -2,8 +2,8 @@
#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));
@ -14,8 +14,8 @@ PUBLIC void env_setargs(arg_c, arg_v)
int arg_c;
char *arg_v[];
{
argc= arg_c;
argv= arg_v;
env_argc= arg_c;
env_argv= arg_v;
}
/*===========================================================================*
@ -35,15 +35,15 @@ int max_len; /* maximum length of value */
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);

View file

@ -17,6 +17,7 @@
#include <minix/sysutil.h>
#include <minix/keymap.h>
#include <minix/bitmap.h>
#include <minix/rs.h>
#include <stdlib.h>
#include <stdio.h>

View file

@ -19,7 +19,6 @@ int sys_panic; /* flag to indicate system-wide panic */
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) );
@ -42,11 +41,9 @@ PUBLIC int main(int argc, char **argv)
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) {
@ -104,25 +101,16 @@ send_reply:
*===========================================================================*/
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 *
*===========================================================================*/

View file

@ -9,4 +9,6 @@ _PROTOTYPE(int do_retrieve, (message *m_ptr));
_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));

View file

@ -14,14 +14,15 @@ PRIVATE _PROTOTYPE(void check_subscribers, (struct data_store *dsp));
/*===========================================================================*
* 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;
@ -32,7 +33,42 @@ PUBLIC void ds_init(void)
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)

View file

@ -95,98 +95,17 @@ FORWARD _PROTOTYPE( void nw_init, (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) );
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
@ -269,12 +188,111 @@ PUBLIC void main()
*===========================================================================*/
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();

View file

@ -25,19 +25,16 @@ int verbose = 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) );
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;
@ -111,9 +108,28 @@ PUBLIC int main(int argc, char *argv[])
*===========================================================================*/
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);
}

View file

@ -14,6 +14,7 @@
#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) );
@ -24,21 +25,24 @@ 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");
@ -53,10 +57,10 @@ PRIVATE char *s_flags_str(int flags)
{
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);

View file

@ -19,13 +19,13 @@ int callnr; /* system call number */
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 *
@ -40,11 +40,9 @@ PUBLIC int main(int argc, char **argv)
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'. */
@ -87,6 +85,11 @@ PUBLIC int main(int argc, char **argv)
*===========================================================================*/
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);
@ -96,11 +99,11 @@ PRIVATE void sef_local_startup()
}
/*===========================================================================*
* 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. */
@ -112,6 +115,8 @@ PRIVATE void init_server(int argc, char **argv)
/* Set key mappings. */
map_unmap_fkeys(TRUE /*map*/);
return(OK);
}
/*===========================================================================*

View file

@ -9,11 +9,11 @@
#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 *
@ -25,16 +25,6 @@ PUBLIC int main(void) {
/* 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. */
@ -76,6 +66,10 @@ PUBLIC int main(void) {
*===========================================================================*/
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. */
@ -83,11 +77,12 @@ PRIVATE void sef_local_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)
@ -96,6 +91,14 @@ PRIVATE void init_server(void)
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);
}
/*===========================================================================*

View file

@ -10,12 +10,12 @@
/* 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 *
@ -30,18 +30,9 @@ PUBLIC int main(int argc, char *argv[])
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;
@ -94,6 +85,10 @@ PUBLIC int main(int argc, char *argv[])
*===========================================================================*/
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. */
@ -101,11 +96,12 @@ PRIVATE void sef_local_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) {
@ -122,6 +118,14 @@ PRIVATE void init_server(void)
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);
}

View file

@ -52,7 +52,7 @@ PUBLIC int fs_readsuper()
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);
}

View file

@ -7,11 +7,11 @@
#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 *
@ -26,11 +26,9 @@ PUBLIC int main(int argc, char *argv[])
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;
@ -71,6 +69,10 @@ PUBLIC int main(int argc, char *argv[])
*===========================================================================*/
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. */
@ -78,10 +80,11 @@ PRIVATE void sef_local_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. */
@ -102,6 +105,8 @@ PRIVATE void init_server(void)
SELF_E = getprocnr();
buf_pool();
return(OK);
}

View file

@ -41,15 +41,17 @@ EXTERN unsigned long calls_stats[NCALLS];
#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 *
@ -64,8 +66,6 @@ PUBLIC int 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 */
@ -166,6 +166,10 @@ send_reply:
*===========================================================================*/
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. */
@ -173,55 +177,9 @@ PRIVATE void sef_local_startup()
}
/*===========================================================================*
* get_work *
* sef_cb_init_fresh *
*===========================================================================*/
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 *
*===========================================================================*/
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
@ -351,6 +309,52 @@ PRIVATE void pm_init()
*/
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 */
}
/*===========================================================================*

View file

@ -5,16 +5,12 @@
/* 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 */
@ -25,19 +21,22 @@
#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 */
@ -55,8 +54,8 @@
/* 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 */
@ -79,9 +78,10 @@
| 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 */

View file

@ -27,6 +27,7 @@ extern struct boot_image_dev boot_image_dev_table[];
* 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 */
@ -37,6 +38,11 @@ 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.
*/

View file

@ -25,9 +25,7 @@ FORWARD _PROTOTYPE(void boot_image_info_lookup, ( 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) );
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) );
@ -36,16 +34,12 @@ 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 *
@ -59,15 +53,10 @@ PUBLIC int main(void)
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) {
@ -83,8 +72,8 @@ PUBLIC int main(void)
/* 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.
@ -107,21 +96,7 @@ PUBLIC int main(void)
}
}
/* 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 {
@ -136,6 +111,7 @@ PUBLIC int main(void)
/* 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;
@ -144,6 +120,9 @@ PUBLIC int main(void)
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);
@ -164,12 +143,359 @@ PUBLIC int main(void)
*===========================================================================*/
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();
}
/*===========================================================================*
* sef_cb_init_fresh *
*===========================================================================*/
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, 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;
struct boot_image_priv *boot_image_priv;
struct boot_image_sys *boot_image_sys;
struct boot_image_dev *boot_image_dev;
/* 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;
/* Get a copy of the boot image table. */
if ((s = sys_getimage(image)) != OK) {
panic("RS", "unable to get copy of boot image table", s);
}
/* Determine the number of system services in the boot image table and
* compute the size required for the boot image buffer.
*/
nr_image_srvs = 0;
boot_image_buffer_size = 0;
for(i=0;i<NR_BOOT_PROCS;i++) {
ip = &image[i];
/* System services only. */
if(iskerneln(_ENDPOINT_P(ip->endpoint))) {
continue;
}
nr_image_srvs++;
/* Lookup the corresponding entry in the boot image sys table. */
boot_image_info_lookup(ip->endpoint, image,
NULL, NULL, &boot_image_sys, NULL);
/* If we must keep a copy of this system service, read the header
* and increase the size of the boot image buffer.
*/
if(boot_image_sys->flags & SF_USE_COPY) {
if((s = sys_getaoutheader(&header, i)) != OK) {
panic("RS", "unable to get copy of a.out header", s);
}
boot_image_buffer_size += header.a_hdrlen
+ header.a_text + header.a_data;
}
}
/* Determine the number of entries in the boot image priv table and make sure
* it matches the number of system services in the boot image table.
*/
nr_image_priv_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(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) {
continue;
}
nr_image_priv_srvs++;
}
if(nr_image_srvs != nr_image_priv_srvs) {
panic("RS", "boot image table and boot image priv table mismatch",
NO_NUM);
}
/* Allocate boot image buffer. */
if(boot_image_buffer_size > 0) {
boot_image_buffer = rs_startup_sbrk(boot_image_buffer_size);
if(boot_image_buffer == (char *) -1) {
panic("RS", "unable to allocate boot image buffer", NO_NUM);
}
}
/* 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.
* In addition, set priviliges, sys properties, and dev properties (if any)
* for every system service.
*/
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(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) {
continue;
}
/* Lookup the corresponding entries in other tables. */
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.
*/
rp->r_exec_len = 0;
rp->r_exec = NULL;
if(boot_image_sys->flags & SF_USE_COPY) {
exec_image_copy(ip - image, ip, rp);
}
/*
* Set privileges.
*/
/* Get label. */
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. */
if ((s = sys_getpriv(&(rp->r_priv), ip->endpoint)) != OK) {
panic("RS", "unable to synch privilege structure", s);
}
/*
* Set sys properties.
*/
rpub->sys_flags = boot_image_sys->flags; /* sys flags */
/*
* Set dev properties.
*/
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(rpub->proc_name, ip->proc_name);
/* Get command settings. */
rp->r_cmd[0]= '\0';
rp->r_argv[0] = rp->r_cmd;
rp->r_argv[1] = NULL;
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;
rpub->endpoint = ip->endpoint;
/* Set some defaults. */
rp->r_uid = 0; /* root */
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_restarts = 0; /* no restarts so far */
rp->r_set_resources = 0; /* don't set resources */
/* Mark as in use. */
rp->r_flags = RS_IN_USE;
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(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) {
continue;
}
/* 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(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 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.
*/
if ((s = getsysinfo(PM_PROC_NR, SI_PROC_TAB, mproc)) != OK) {
panic("RS", "unable to get copy of PM process table", s);
}
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(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 == rpub->endpoint) {
rp->r_pid = mproc[j].mp_pid;
break;
}
}
if(j == NR_PROCS) {
panic("RS", "unable to get pid", NO_NUM);
}
}
/*
* Now complete RS initialization process in collaboration with other
* system services.
*/
/* Let the rest of the system know about our dynamically allocated buffer. */
if(boot_image_buffer_size > 0) {
boot_image_buffer = rs_startup_sbrk_synch(boot_image_buffer_size);
if(boot_image_buffer == (char *) -1) {
panic("RS", "unable to synch boot image buffer", NO_NUM);
}
}
/* Set alarm to periodically check service status. */
if (OK != (s=sys_setalarm(RS_DELTA_T, 0)))
panic("RS", "couldn't set alarm", s);
/* 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(SIGCHLD,&sa,NULL)<0) panic("RS","sigaction failed", errno);
if (sigaction(SIGTERM,&sa,NULL)<0) panic("RS","sigaction failed", errno);
/* Initialize the exec pipe. */
if (pipe(exec_pipe) == -1)
panic("RS", "pipe failed", errno);
if (fcntl(exec_pipe[0], F_SETFD,
fcntl(exec_pipe[0], F_GETFD) | FD_CLOEXEC) == -1)
{
panic("RS", "fcntl set FD_CLOEXEC on pipe input failed", errno);
}
if (fcntl(exec_pipe[1], F_SETFD,
fcntl(exec_pipe[1], F_GETFD) | FD_CLOEXEC) == -1)
{
panic("RS", "fcntl set FD_CLOEXEC on pipe output failed", errno);
}
if (fcntl(exec_pipe[0], F_SETFL,
fcntl(exec_pipe[0], F_GETFL) | O_NONBLOCK) == -1)
{
panic("RS", "fcntl set O_NONBLOCK on pipe input failed", errno);
}
/* Map out our own text and data. This is normally done in crtso.o
* but RS is an exception - we don't get to talk to VM so early on.
* That's why we override munmap() and munmap_text() in utility.c.
*
* _minix_unmapzero() is the same code in crtso.o that normally does
* it on startup. It's best that it's there as crtso.o knows exactly
* what the ranges are of the filler data.
*/
unmap_ok = 1;
_minix_unmapzero();
return(OK);
}
/*===========================================================================*
* exec_image_copy *
*===========================================================================*/
@ -293,344 +619,36 @@ struct boot_image_dev **dp;
}
/*===========================================================================*
* fill_call_mask *
* catch_boot_init_ready *
*===========================================================================*/
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 */
PRIVATE void catch_boot_init_ready(endpoint)
endpoint_t endpoint;
{
/* 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)
{
/* Initialize the reincarnation server. */
struct sigaction sa;
struct boot_image *ip;
int s,i,j;
int nr_image_srvs, nr_image_priv_srvs;
/* Block and catch an init ready message from the given source. */
int r;
message m;
struct rproc *rp;
struct boot_image image[NR_BOOT_PROCS];
struct mproc mproc[NR_PROCS];
struct exec header;
struct boot_image_priv *boot_image_priv;
struct boot_image_sys *boot_image_sys;
struct boot_image_dev *boot_image_dev;
int result;
/* See if we run in verbose mode. */
env_parse("rs_verbose", "d", 0, &rs_verbose, 0, 1);
/* 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)];
/* Initialize the global update descriptor. */
rupdate.flags = 0;
/* Get a copy of the boot image table. */
if ((s = sys_getimage(image)) != OK) {
panic("RS", "unable to get copy of boot image table", s);
/* Check result. */
if(result != OK) {
panic("RS", "unable to complete init for service", m.m_source);
}
/* Determine the number of system services in the boot image table and
* compute the size required for the boot image buffer.
*/
nr_image_srvs = 0;
boot_image_buffer_size = 0;
for(i=0;i<NR_BOOT_PROCS;i++) {
ip = &image[i];
/* System services only. */
if(!isbootsrvprocn(_ENDPOINT_P(ip->endpoint))) {
continue;
}
nr_image_srvs++;
/* Lookup the corresponding entry in the boot image sys table. */
boot_image_info_lookup(ip->endpoint, image,
NULL, NULL, &boot_image_sys, NULL);
/* If we must keep a copy of this system service, read the header
* and increase the size of the boot image buffer.
*/
if(boot_image_sys->flags & SF_USE_COPY) {
if((s = sys_getaoutheader(&header, i)) != OK) {
panic("RS", "unable to get copy of a.out header", s);
}
boot_image_buffer_size += header.a_hdrlen
+ header.a_text + header.a_data;
}
}
/* Determine the number of entries in the boot image priv table and make sure
* it matches the number of system services in the boot image table.
*/
nr_image_priv_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))) {
continue;
}
nr_image_priv_srvs++;
}
if(nr_image_srvs != nr_image_priv_srvs) {
panic("RS", "boot image table and boot image priv table mismatch",
NO_NUM);
}
/* Allocate boot image buffer. */
if(boot_image_buffer_size > 0) {
boot_image_buffer = rs_startup_sbrk(boot_image_buffer_size);
if(boot_image_buffer == (char *) -1) {
panic("RS", "unable to allocate boot image buffer", NO_NUM);
}
}
/* Initialize the system process table in 3 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.
* In addition, set priviliges, sys properties, and dev properties (if any)
* for every system service.
*/
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))) {
continue;
}
/* Lookup the corresponding entries in other tables. */
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];
/*
* Get a copy of the executable image if required.
*/
rp->r_exec_len = 0;
rp->r_exec = NULL;
if(boot_image_sys->flags & SF_USE_COPY) {
exec_image_copy(ip - image, ip, rp);
}
/*
* 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);
}
/* Synch the privilege structure with the kernel. */
if ((s = sys_getpriv(&(rp->r_priv), ip->endpoint)) != OK) {
panic("RS", "unable to synch privilege structure", s);
}
/*
* Set sys properties.
*/
rp->r_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 */
/* Get process name. */
strcpy(rp->r_proc_name, ip->proc_name);
/* Get command settings. */
rp->r_cmd[0]= '\0';
rp->r_argv[0] = rp->r_cmd;
rp->r_argv[1] = NULL;
rp->r_argc = 1;
rp->r_script[0]= '\0';
/* Get some settings from the boot image table. */
rp->r_nice = ip->priority;
rp->r_proc_nr_e = ip->endpoint;
/* Set some defaults. */
rp->r_uid = 0; /* root */
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_restarts = 0; /* no restarts so far */
rp->r_set_resources = 0; /* don't set resources */
/* Mark as in use. */
rp->r_flags = RS_IN_USE;
rproc_ptr[_ENDPOINT_P(rp->r_proc_nr_e)]= rp;
}
/* - Step 2: allow every system service in the boot image to run.
*/
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))) {
continue;
}
/* Lookup the corresponding entry in the boot image table. */
boot_image_info_lookup(boot_image_priv->endpoint, image,
&ip, NULL, NULL, NULL);
/* Allow the service to run. */
if ((s = sys_privctl(ip->endpoint, SYS_PRIV_ALLOW, NULL)) != OK) {
panic("RS", "unable to initialize privileges", s);
}
}
/* - Step 3: 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.
*/
if ((s = getsysinfo(PM_PROC_NR, SI_PROC_TAB, mproc)) != OK) {
panic("RS", "unable to get copy of PM process table", s);
}
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))) {
continue;
}
/* Lookup the corresponding slot in the system process table. */
rp = &rproc[boot_image_priv - boot_image_priv_table];
/* 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) {
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);
}
}
/*
* Now complete RS initialization process in collaboration with other
* system services.
*/
/* Let the rest of the system know about our dynamically allocated buffer. */
if(boot_image_buffer_size > 0) {
boot_image_buffer = rs_startup_sbrk_synch(boot_image_buffer_size);
if(boot_image_buffer == (char *) -1) {
panic("RS", "unable to synch boot image buffer", NO_NUM);
}
}
/* Set alarm to periodically check service status. */
if (OK != (s=sys_setalarm(RS_DELTA_T, 0)))
panic("RS", "couldn't set alarm", s);
/* 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(SIGCHLD,&sa,NULL)<0) panic("RS","sigaction failed", errno);
if (sigaction(SIGTERM,&sa,NULL)<0) panic("RS","sigaction failed", errno);
/* Initialize the exec pipe. */
if (pipe(exec_pipe) == -1)
panic("RS", "pipe failed", errno);
if (fcntl(exec_pipe[0], F_SETFD,
fcntl(exec_pipe[0], F_GETFD) | FD_CLOEXEC) == -1)
{
panic("RS", "fcntl set FD_CLOEXEC on pipe input failed", errno);
}
if (fcntl(exec_pipe[1], F_SETFD,
fcntl(exec_pipe[1], F_GETFD) | FD_CLOEXEC) == -1)
{
panic("RS", "fcntl set FD_CLOEXEC on pipe output failed", errno);
}
if (fcntl(exec_pipe[0], F_SETFL,
fcntl(exec_pipe[0], F_GETFL) | O_NONBLOCK) == -1)
{
panic("RS", "fcntl set O_NONBLOCK on pipe input failed", errno);
}
/* Map out our own text and data. This is normally done in crtso.o
* but RS is an exception - we don't get to talk to VM so early on.
* That's why we override munmap() and munmap_text() in utility.c.
*
* _minix_unmapzero() is the same code in crtso.o that normally does
* it on startup. It's best that it's there as crtso.o knows exactly
* what the ranges are of the filler data.
*/
unmap_ok = 1;
_minix_unmapzero();
/* Mark the slot as no longer initializing. */
rp->r_flags &= ~RS_INITIALIZING;
rp->r_check_tm = 0;
getuptime(&rp->r_alive_tm);
}
/*===========================================================================*

File diff suppressed because it is too large Load diff

View file

@ -18,13 +18,17 @@ _PROTOTYPE( int do_restart, (message *m));
_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));

View file

@ -196,12 +196,12 @@ PRIVATE int parse_arguments(int argc, char **argv)
}
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)
{
@ -610,10 +610,10 @@ PRIVATE void do_pci_device(config_t *cpe)
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;
@ -662,10 +662,10 @@ PRIVATE void do_pci_class(config_t *cpe)
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;
@ -877,10 +877,10 @@ PRIVATE void do_system(config_t *cpe)
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;
@ -904,10 +904,10 @@ PRIVATE void do_control(config_t *cpe)
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);
}

View file

@ -8,50 +8,78 @@
#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 },

View file

@ -6,12 +6,13 @@
/* 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. */
@ -32,49 +33,37 @@ struct boot_image_dev {
/* 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. */

View file

@ -8,6 +8,30 @@
#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 *
*===========================================================================*/
@ -16,17 +40,62 @@ struct rproc *rp; /* pointer to process slot */
{
/* 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);
}
}
}

View file

@ -39,13 +39,13 @@
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 *
@ -61,14 +61,6 @@ PUBLIC int main(void)
/* 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;
@ -228,12 +220,106 @@ PUBLIC int main(void)
*===========================================================================*/
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 *
*===========================================================================*/
@ -347,88 +433,6 @@ int result; /* result of the call (usually OK or error #) */
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 *
*===========================================================================*/

View file

@ -144,8 +144,7 @@ PUBLIC int do_fork(message *msg)
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,

View file

@ -18,6 +18,7 @@
#include <minix/const.h>
#include <minix/bitmap.h>
#include <minix/crtso.h>
#include <minix/rs.h>
#include <errno.h>
#include <string.h>
@ -40,21 +41,11 @@ extern int missing_spares;
#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
@ -64,11 +55,14 @@ struct {
(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 *
@ -81,19 +75,6 @@ PUBLIC int main(void)
/* 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;
@ -171,26 +152,41 @@ PUBLIC int main(void)
*===========================================================================*/
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);
@ -285,7 +281,7 @@ PRIVATE void vm_init(void)
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);
@ -314,17 +310,11 @@ PRIVATE void vm_init(void)
}
/* 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
@ -332,35 +322,35 @@ PRIVATE void vm_init(void)
*/
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);
/* 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);
/* Requests from RS */
CALLMAP(VM_RS_SET_PRIV, do_rs_set_priv, RS_PROC_NR);
/* 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);
/* 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);
/* Calls from RS */
CALLMAP(VM_RS_SET_PRIV, do_rs_set_priv);
/* 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);
/* 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)
@ -372,6 +362,41 @@ PRIVATE void vm_init(void)
/* 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);
}
/*===========================================================================*
@ -381,23 +406,14 @@ PRIVATE int vm_acl_ok(endpoint_t caller, int call)
{
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;
}

View file

@ -46,8 +46,8 @@ PUBLIC int do_rs_set_priv(message *m)
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;
}

View file

@ -32,8 +32,7 @@ struct vmproc {
/* 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.